|
1 |
| -<ul |
2 |
| - role="tree" |
3 |
| - aria-expanded="{{ include.expanded | default: 'false' }}" |
4 |
| - class="nav-list" |
5 |
| -{%- if include.owned_tree_id -%}id="{{ include.owned_tree_id }}"{%- endif -%} |
6 |
| -> |
7 |
| - {%- assign titled_pages = include.pages |
8 |
| - | where_exp:"item", "item.title != nil" -%} |
9 |
| - |
10 |
| - {%- comment -%} |
| 1 | +{%- comment -%} |
11 | 2 | The values of `title` and `nav_order` can be numbers or strings.
|
12 | 3 | Jekyll gives build failures when sorting on mixtures of different types,
|
13 | 4 | so numbers and strings need to be sorted separately.
|
|
17 | 8 | (except that a numerical `title` value is treated as a string).
|
18 | 9 |
|
19 | 10 | The case-sensitivity of string sorting is determined by `site.nav_sort`.
|
20 |
| - {%- endcomment -%} |
| 11 | +{%- endcomment -%} |
21 | 12 |
|
22 |
| - {%- assign string_ordered_pages = titled_pages |
23 |
| - | where_exp:"item", "item.nav_order == nil" -%} |
24 |
| - {%- assign nav_ordered_pages = titled_pages |
25 |
| - | where_exp:"item", "item.nav_order != nil" -%} |
| 13 | +{%- comment -%}Pre-compute and cache page lists to avoid repeated filtering{%- endcomment -%} |
| 14 | +{%- assign titled_pages = include.pages | where_exp:"item", "item.title != nil" -%} |
26 | 15 |
|
27 |
| - {%- comment -%} |
28 |
| - The nav_ordered_pages have to be added to number_ordered_pages and |
29 |
| - string_ordered_pages, depending on the nav_order value. |
30 |
| - The first character of the jsonify result is `"` only for strings. |
31 |
| - {%- endcomment -%} |
32 |
| - {%- assign nav_ordered_groups = nav_ordered_pages |
33 |
| - | group_by_exp:"item", "item.nav_order | jsonify | slice: 0" -%} |
34 |
| - {%- assign number_ordered_pages = "" | split:"X" -%} |
35 |
| - {%- for group in nav_ordered_groups -%} |
36 |
| - {%- if group.name == '"' -%} |
37 |
| - {%- assign string_ordered_pages = string_ordered_pages | concat: group.items -%} |
38 |
| - {%- else -%} |
39 |
| - {%- assign number_ordered_pages = number_ordered_pages | concat: group.items -%} |
40 |
| - {%- endif -%} |
41 |
| - {%- endfor -%} |
| 16 | +{%- comment -%}Separate pages by nav_order type for efficient sorting{%- endcomment -%} |
| 17 | +{%- assign string_ordered_pages = titled_pages | where_exp:"item", "item.nav_order == nil" -%} |
| 18 | +{%- assign nav_ordered_pages = titled_pages | where_exp:"item", "item.nav_order != nil" -%} |
42 | 19 |
|
43 |
| - {%- assign sorted_number_ordered_pages = number_ordered_pages | sort:"nav_order" -%} |
44 |
| - |
45 |
| - {%- comment -%} |
46 |
| - The string_ordered_pages have to be sorted by nav_order, and otherwise title |
47 |
| - (where appending the empty string to a numeric title converts it to a string). |
48 |
| - After grouping them by those values, the groups are sorted, then the items |
49 |
| - of each group are concatenated. |
50 |
| - {%- endcomment -%} |
51 |
| - {%- assign string_ordered_groups = string_ordered_pages |
52 |
| - | group_by_exp:"item", "item.nav_order | default: item.title | append:''" -%} |
53 |
| - {%- if site.nav_sort == 'case_insensitive' -%} |
54 |
| - {%- assign sorted_string_ordered_groups = string_ordered_groups | sort_natural:"name" -%} |
| 20 | +{%- comment -%}Group nav_ordered_pages by type (number vs string){%- endcomment -%} |
| 21 | +{%- assign nav_ordered_groups = nav_ordered_pages | group_by_exp:"item", "item.nav_order | jsonify | slice: 0" -%} |
| 22 | +{%- assign number_ordered_pages = "" | split:"X" -%} |
| 23 | +{%- for group in nav_ordered_groups -%} |
| 24 | + {%- if group.name == '"' -%} |
| 25 | + {%- assign string_ordered_pages = string_ordered_pages | concat: group.items -%} |
55 | 26 | {%- else -%}
|
56 |
| - {%- assign sorted_string_ordered_groups = string_ordered_groups | sort:"name" -%} |
| 27 | + {%- assign number_ordered_pages = number_ordered_pages | concat: group.items -%} |
57 | 28 | {%- endif -%}
|
58 |
| - {%- assign sorted_string_ordered_pages = "" | split:"X" -%} |
59 |
| - {%- for group in sorted_string_ordered_groups -%} |
60 |
| - {%- assign sorted_string_ordered_pages = sorted_string_ordered_pages | concat: group.items -%} |
61 |
| - {%- endfor -%} |
| 29 | +{%- endfor -%} |
62 | 30 |
|
63 |
| - {%- assign pages_list = sorted_number_ordered_pages | concat: sorted_string_ordered_pages -%} |
64 |
| - |
| 31 | +{%- assign sorted_number_ordered_pages = number_ordered_pages | sort:"nav_order" -%} |
| 32 | + |
| 33 | +{%- comment -%}Sort string pages{%- endcomment -%} |
| 34 | +{%- assign string_ordered_groups = string_ordered_pages | group_by_exp:"item", "item.nav_order | default: item.title | append:''" -%} |
| 35 | +{%- if site.nav_sort == 'case_insensitive' -%} |
| 36 | + {%- assign sorted_string_ordered_groups = string_ordered_groups | sort_natural:"name" -%} |
| 37 | +{%- else -%} |
| 38 | + {%- assign sorted_string_ordered_groups = string_ordered_groups | sort:"name" -%} |
| 39 | +{%- endif -%} |
| 40 | +{%- assign sorted_string_ordered_pages = "" | split:"X" -%} |
| 41 | +{%- for group in sorted_string_ordered_groups -%} |
| 42 | + {%- assign sorted_string_ordered_pages = sorted_string_ordered_pages | concat: group.items -%} |
| 43 | +{%- endfor -%} |
| 44 | + |
| 45 | +{%- assign pages_list = sorted_number_ordered_pages | concat: sorted_string_ordered_pages -%} |
| 46 | + |
| 47 | +{%- comment -%}Pre-compute current page context for faster lookups{%- endcomment -%} |
| 48 | +{%- assign current_collection = page.collection -%} |
| 49 | +{%- assign current_url = page.url -%} |
| 50 | +{%- assign current_parent = page.parent -%} |
| 51 | +{%- assign current_grand_parent = page.grand_parent -%} |
| 52 | + |
| 53 | +<ul |
| 54 | + role="tree" |
| 55 | + aria-expanded="{{ include.expanded | default: 'false' }}" |
| 56 | + class="nav-list" |
| 57 | +{%- if include.owned_tree_id -%}id="{{ include.owned_tree_id }}"{%- endif -%} |
| 58 | +> |
65 | 59 | {%- for node in pages_list -%}
|
66 |
| - {%- if node.parent == nil -%} |
67 |
| - {%- unless node.nav_exclude -%} |
68 |
| - {% assign nested_owned_tree_id = include.owned_tree_id | append: "_" | append: forloop.index | append: "_" | append: node.title | append: "_navitems" | replace: " ", "_" %} |
69 |
| - {%- comment -%}Check if current page is a descendant of this node{%- endcomment -%} |
| 60 | + {%- unless node.parent or node.nav_exclude -%} |
| 61 | + {%- assign nested_owned_tree_id = include.owned_tree_id | append: "_" | append: forloop.index | append: "_" | append: node.title | append: "_navitems" | replace: " ", "_" -%} |
| 62 | + |
| 63 | + {%- comment -%}Optimized ancestor checking{%- endcomment -%} |
70 | 64 | {%- assign is_ancestor = false -%}
|
71 |
| - {%- if page.collection == include.key -%} |
72 |
| - {%- if page.url == node.url or page.parent == node.title or page.grand_parent == node.title -%} |
| 65 | + {%- if current_collection == include.key -%} |
| 66 | + {%- if current_url == node.url or current_parent == node.title or current_grand_parent == node.title -%} |
73 | 67 | {%- assign is_ancestor = true -%}
|
74 |
| - {%- else -%} |
75 |
| - {%- comment -%}Check for 4-level deep pages{%- endcomment -%} |
76 |
| - {%- for child in pages_list -%} |
77 |
| - {%- if child.parent == node.title -%} |
78 |
| - {%- for grand_child in pages_list -%} |
79 |
| - {%- if grand_child.parent == child.title and grand_child.grand_parent == node.title -%} |
80 |
| - {%- if page.parent == grand_child.title -%} |
81 |
| - {%- assign is_ancestor = true -%} |
82 |
| - {%- break -%} |
83 |
| - {%- endif -%} |
84 |
| - {%- endif -%} |
85 |
| - {%- endfor -%} |
86 |
| - {%- endif -%} |
87 |
| - {%- endfor -%} |
88 | 68 | {%- endif -%}
|
89 | 69 | {%- endif -%}
|
90 | 70 | <li role="none" class="nav-list-item{% if is_ancestor %} active{% endif %}">
|
91 | 71 | {%- if node.has_children -%}
|
92 | 72 | <a
|
93 | 73 | role="treeitem"
|
94 | 74 | aria-owns="{{ nested_owned_tree_id }}"
|
95 |
| - {%- if page.url == node.url -%}aria-current="page"{%- endif -%} |
| 75 | + {%- if current_url == node.url -%}aria-current="page"{%- endif -%} |
96 | 76 | href="#"
|
97 | 77 | class="nav-list-expander"
|
98 | 78 | ><svg viewBox="0 0 24 24"><use xlink:href="#svg-arrow-right"></use></svg></a>
|
|
101 | 81 | <a
|
102 | 82 | role="treeitem"
|
103 | 83 | {%- if node.has_children -%}aria-owns="{{ nested_owned_tree_id }}"{%- endif -%}
|
104 |
| - {%- if page.url == node.url -%}aria-current="page"{%- endif -%} |
| 84 | + {%- if current_url == node.url -%}aria-current="page"{%- endif -%} |
105 | 85 | href="{{ node.url | absolute_url }}"
|
106 |
| - class="nav-list-link{% if page.url == node.url %} active{% endif %}" |
| 86 | + class="nav-list-link{% if current_url == node.url %} active{% endif %}" |
107 | 87 | >{{ node.title }}</a>
|
108 | 88 | {%- if node.has_children -%}
|
| 89 | + {%- comment -%}Pre-filter children to avoid repeated filtering{%- endcomment -%} |
109 | 90 | {%- assign children_list = pages_list | where: "parent", node.title -%}
|
110 | 91 | <ul role="tree" class="nav-list" id="{{ nested_owned_tree_id }}">
|
111 | 92 | {%- for child in children_list -%}
|
112 | 93 | {%- unless child.nav_exclude -%}
|
113 |
| - {%- comment -%}Check if current page is a descendant of this child{%- endcomment -%} |
114 | 94 | {%- assign child_is_ancestor = false -%}
|
115 |
| - {%- if page.url == child.url or page.parent == child.title -%} |
| 95 | + {%- if current_url == child.url or current_parent == child.title -%} |
116 | 96 | {%- assign child_is_ancestor = true -%}
|
117 |
| - {%- else -%} |
118 |
| - {%- comment -%}Check for 4-level deep pages{%- endcomment -%} |
119 |
| - {%- for grand_child in pages_list -%} |
120 |
| - {%- if grand_child.parent == child.title and grand_child.grand_parent == node.title -%} |
121 |
| - {%- if page.parent == grand_child.title -%} |
122 |
| - {%- assign child_is_ancestor = true -%} |
123 |
| - {%- break -%} |
124 |
| - {%- endif -%} |
125 |
| - {%- endif -%} |
126 |
| - {%- endfor -%} |
127 | 97 | {%- endif -%}
|
128 | 98 | <li role="none" class="nav-list-item{% if child_is_ancestor %} active{% endif %}">
|
129 | 99 | {%- if child.has_children -%}
|
130 |
| - {% assign nested_nested_owned_tree_id = nested_owned_tree_id | append: "_" | append: forloop.index | append: "_" | append: child.title | append: "_navitems" | replace: " ", "_" %} |
| 100 | + {%- assign nested_nested_owned_tree_id = nested_owned_tree_id | append: "_" | append: forloop.index | append: "_" | append: child.title | append: "_navitems" | replace: " ", "_" -%} |
131 | 101 | <a
|
132 | 102 | role="treeitem"
|
133 | 103 | aria-owns="{{ nested_nested_owned_tree_id }}"
|
134 |
| - {%- if page.url == node.url -%}aria-current="page"{%- endif -%} |
| 104 | + {%- if current_url == child.url -%}aria-current="page"{%- endif -%} |
135 | 105 | href="#"
|
136 | 106 | class="nav-list-expander"
|
137 | 107 | ><svg viewBox="0 0 24 24"><use xlink:href="#svg-arrow-right"></use></svg></a>
|
138 | 108 | {%- endif -%}
|
139 | 109 | <a
|
140 | 110 | role="treeitem"
|
141 | 111 | {%- if child.has_children -%}aria-owns="{{ nested_nested_owned_tree_id }}"{%- endif -%}
|
142 |
| - {%- if page.url == node.url -%}aria-current="page"{%- endif -%} |
| 112 | + {%- if current_url == child.url -%}aria-current="page"{%- endif -%} |
143 | 113 | href="{{ child.url | absolute_url }}"
|
144 |
| - class="nav-list-link{% if page.url == child.url %} active{% endif %}" |
| 114 | + class="nav-list-link{% if current_url == child.url %} active{% endif %}" |
145 | 115 | >{{ child.title }}</a>
|
146 | 116 | {%- if child.has_children -%}
|
147 | 117 | {%- assign grand_children_list = pages_list | where: "parent", child.title | where: "grand_parent", node.title -%}
|
148 | 118 | <ul role="tree" class="nav-list" id="{{ nested_nested_owned_tree_id }}">
|
149 | 119 | {%- for grand_child in grand_children_list -%}
|
150 | 120 | {%- unless grand_child.nav_exclude -%}
|
151 |
| - {%- comment -%}Check if current page is a descendant of this grand_child{%- endcomment -%} |
152 | 121 | {%- assign grand_child_is_ancestor = false -%}
|
153 |
| - {%- if page.url == grand_child.url or page.parent == grand_child.title -%} |
| 122 | + {%- if current_url == grand_child.url or current_parent == grand_child.title -%} |
154 | 123 | {%- assign grand_child_is_ancestor = true -%}
|
155 | 124 | {%- endif -%}
|
156 | 125 | <li role="none" class="nav-list-item{% if grand_child_is_ancestor %} active{% endif %}">
|
157 | 126 | {%- if grand_child.has_children -%}
|
158 |
| - {% assign nested_nested_nested_owned_tree_id = nested_nested_owned_tree_id | append: "_" | append: forloop.index | append: "_" | append: grand_child.title | append: "_navitems" | replace: " ", "_" %} |
159 | 127 | <a
|
160 | 128 | role="treeitem"
|
161 | 129 | aria-owns="{{ nested_nested_nested_owned_tree_id }}"
|
162 |
| - {%- if page.url == grand_child.url -%}aria-current="page"{%- endif -%} |
| 130 | + {%- if current_url == grand_child.url -%}aria-current="page"{%- endif -%} |
163 | 131 | href="#"
|
164 | 132 | class="nav-list-expander"
|
165 | 133 | ><svg viewBox="0 0 24 24"><use xlink:href="#svg-arrow-right"></use></svg></a>
|
166 | 134 | {%- endif -%}
|
167 | 135 | <a
|
168 | 136 | role="treeitem"
|
169 | 137 | {%- if grand_child.has_children -%}aria-owns="{{ nested_nested_nested_owned_tree_id }}"{%- endif -%}
|
170 |
| - {%- if page.url == grand_child.url -%}aria-current="page"{%- endif -%} |
| 138 | + {%- if current_url == grand_child.url -%}aria-current="page"{%- endif -%} |
171 | 139 | href="{{ grand_child.url | absolute_url }}"
|
172 |
| - class="nav-list-link{% if page.url == grand_child.url %} active{% endif %}" |
| 140 | + class="nav-list-link{% if current_url == grand_child.url %} active{% endif %}" |
173 | 141 | >{{ grand_child.title }}</a>
|
174 | 142 | {%- if grand_child.has_children -%}
|
175 | 143 | {%- assign great_grand_children_list = pages_list | where: "parent", grand_child.title -%}
|
176 | 144 | <ul role="tree" class="nav-list" id="{{ nested_nested_nested_owned_tree_id }}">
|
177 | 145 | {%- for great_grand_child in great_grand_children_list -%}
|
178 | 146 | {%- unless great_grand_child.nav_exclude -%}
|
179 |
| - <li role="none" class="nav-list-item {% if page.url == great_grand_child.url %} active{% endif %}"> |
| 147 | + <li role="none" class="nav-list-item {% if current_url == great_grand_child.url %} active{% endif %}"> |
180 | 148 | <a
|
181 | 149 | role="treeitem"
|
182 |
| - {%- if page.url == great_grand_child.url -%}aria-current="page"{%- endif -%} |
| 150 | + {%- if current_url == great_grand_child.url -%}aria-current="page"{%- endif -%} |
183 | 151 | href="{{ great_grand_child.url | absolute_url }}"
|
184 |
| - class="nav-list-link{% if page.url == great_grand_child.url %} active{% endif %}" |
| 152 | + class="nav-list-link{% if current_url == great_grand_child.url %} active{% endif %}" |
185 | 153 | >{{ great_grand_child.title }}</a>
|
186 | 154 | </li>
|
187 | 155 | {%- endunless -%}
|
|
199 | 167 | </ul>
|
200 | 168 | {%- endif -%}
|
201 | 169 | </li>
|
202 |
| - {%- endunless -%} |
203 |
| - {%- endif -%} |
| 170 | + {%- endunless -%} |
204 | 171 | {%- endfor -%}
|
205 | 172 | </ul>
|
206 | 173 |
|
207 |
| -{%- if page.collection == include.key -%} |
208 |
| - |
| 174 | +{%- comment -%} |
| 175 | +Compute breadcrumb URLs and TOC only when needed |
| 176 | +{%- endcomment -%} |
| 177 | +{%- if current_collection == include.key -%} |
| 178 | + {%- comment -%}Pre-compute breadcrumb URLs efficiently{%- endcomment -%} |
209 | 179 | {%- for node in pages_list -%}
|
210 |
| - {%- if node.parent == nil -%} |
211 |
| - {%- if page.parent == node.title or page.grand_parent == node.title -%} |
| 180 | + {%- unless node.parent -%} |
| 181 | + {%- if current_parent == node.title or current_grand_parent == node.title -%} |
212 | 182 | {%- assign first_level_url = node.url | absolute_url -%}
|
213 | 183 | {%- endif -%}
|
214 | 184 | {%- if node.has_children -%}
|
215 | 185 | {%- assign children_list = pages_list | where: "parent", node.title -%}
|
216 | 186 | {%- for child in children_list -%}
|
217 | 187 | {%- if child.has_children -%}
|
218 |
| - {%- if page.url == child.url or page.parent == child.title and page.grand_parent == child.parent -%} |
| 188 | + {%- if current_url == child.url or current_parent == child.title and current_grand_parent == child.parent -%} |
219 | 189 | {%- assign second_level_url = child.url | absolute_url -%}
|
220 | 190 | {%- endif -%}
|
221 | 191 | {%- endif -%}
|
222 | 192 | {%- endfor -%}
|
223 | 193 | {%- endif -%}
|
224 |
| - {%- endif -%} |
| 194 | + {%- endunless -%} |
225 | 195 | {%- endfor -%}
|
226 |
| - |
227 |
| - {% if page.has_children == true and page.has_toc != false %} |
| 196 | + |
| 197 | + {%- comment -%}Compute TOC only if needed{%- endcomment -%} |
| 198 | + {%- if page.has_children == true and page.has_toc != false -%} |
228 | 199 | {%- assign toc_list = pages_list | where: "parent", page.title | where: "grand_parent", page.parent -%}
|
229 | 200 | {%- endif -%}
|
230 | 201 |
|
|
0 commit comments