Skip to content

Commit 9c8a676

Browse files
Fix Breadcrumb navigation for collections and reduce build time (#10683) (#10685)
1 parent 2c665a2 commit 9c8a676

File tree

4 files changed

+108
-117
lines changed

4 files changed

+108
-117
lines changed

_config.yml

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -54,9 +54,6 @@ collections:
5454
permalink: /:collection/:path/
5555
output: true
5656
ml-commons-plugin:
57-
permalink: /:collection/:path/
58-
output: true
59-
tuning-your-cluster:
6057
permalink: /:collection/:path/
6158
output: true
6259
monitoring-your-cluster:

_includes/nav.html

Lines changed: 78 additions & 107 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,4 @@
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 -%}
112
The values of `title` and `nav_order` can be numbers or strings.
123
Jekyll gives build failures when sorting on mixtures of different types,
134
so numbers and strings need to be sorted separately.
@@ -17,82 +8,71 @@
178
(except that a numerical `title` value is treated as a string).
189

1910
The case-sensitivity of string sorting is determined by `site.nav_sort`.
20-
{%- endcomment -%}
11+
{%- endcomment -%}
2112

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" -%}
2615

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" -%}
4219

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 -%}
5526
{%- else -%}
56-
{%- assign sorted_string_ordered_groups = string_ordered_groups | sort:"name" -%}
27+
{%- assign number_ordered_pages = number_ordered_pages | concat: group.items -%}
5728
{%- 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 -%}
6230

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+
>
6559
{%- 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 -%}
7064
{%- 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 -%}
7367
{%- 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 -%}
8868
{%- endif -%}
8969
{%- endif -%}
9070
<li role="none" class="nav-list-item{% if is_ancestor %} active{% endif %}">
9171
{%- if node.has_children -%}
9272
<a
9373
role="treeitem"
9474
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 -%}
9676
href="#"
9777
class="nav-list-expander"
9878
><svg viewBox="0 0 24 24"><use xlink:href="#svg-arrow-right"></use></svg></a>
@@ -101,87 +81,75 @@
10181
<a
10282
role="treeitem"
10383
{%- 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 -%}
10585
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 %}"
10787
>{{ node.title }}</a>
10888
{%- if node.has_children -%}
89+
{%- comment -%}Pre-filter children to avoid repeated filtering{%- endcomment -%}
10990
{%- assign children_list = pages_list | where: "parent", node.title -%}
11091
<ul role="tree" class="nav-list" id="{{ nested_owned_tree_id }}">
11192
{%- for child in children_list -%}
11293
{%- unless child.nav_exclude -%}
113-
{%- comment -%}Check if current page is a descendant of this child{%- endcomment -%}
11494
{%- 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 -%}
11696
{%- 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 -%}
12797
{%- endif -%}
12898
<li role="none" class="nav-list-item{% if child_is_ancestor %} active{% endif %}">
12999
{%- 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: " ", "_" -%}
131101
<a
132102
role="treeitem"
133103
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 -%}
135105
href="#"
136106
class="nav-list-expander"
137107
><svg viewBox="0 0 24 24"><use xlink:href="#svg-arrow-right"></use></svg></a>
138108
{%- endif -%}
139109
<a
140110
role="treeitem"
141111
{%- 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 -%}
143113
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 %}"
145115
>{{ child.title }}</a>
146116
{%- if child.has_children -%}
147117
{%- assign grand_children_list = pages_list | where: "parent", child.title | where: "grand_parent", node.title -%}
148118
<ul role="tree" class="nav-list" id="{{ nested_nested_owned_tree_id }}">
149119
{%- for grand_child in grand_children_list -%}
150120
{%- unless grand_child.nav_exclude -%}
151-
{%- comment -%}Check if current page is a descendant of this grand_child{%- endcomment -%}
152121
{%- 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 -%}
154123
{%- assign grand_child_is_ancestor = true -%}
155124
{%- endif -%}
156125
<li role="none" class="nav-list-item{% if grand_child_is_ancestor %} active{% endif %}">
157126
{%- 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: " ", "_" %}
159127
<a
160128
role="treeitem"
161129
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 -%}
163131
href="#"
164132
class="nav-list-expander"
165133
><svg viewBox="0 0 24 24"><use xlink:href="#svg-arrow-right"></use></svg></a>
166134
{%- endif -%}
167135
<a
168136
role="treeitem"
169137
{%- 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 -%}
171139
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 %}"
173141
>{{ grand_child.title }}</a>
174142
{%- if grand_child.has_children -%}
175143
{%- assign great_grand_children_list = pages_list | where: "parent", grand_child.title -%}
176144
<ul role="tree" class="nav-list" id="{{ nested_nested_nested_owned_tree_id }}">
177145
{%- for great_grand_child in great_grand_children_list -%}
178146
{%- 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 %}">
180148
<a
181149
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 -%}
183151
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 %}"
185153
>{{ great_grand_child.title }}</a>
186154
</li>
187155
{%- endunless -%}
@@ -199,32 +167,35 @@
199167
</ul>
200168
{%- endif -%}
201169
</li>
202-
{%- endunless -%}
203-
{%- endif -%}
170+
{%- endunless -%}
204171
{%- endfor -%}
205172
</ul>
206173

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 -%}
209179
{%- 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 -%}
212182
{%- assign first_level_url = node.url | absolute_url -%}
213183
{%- endif -%}
214184
{%- if node.has_children -%}
215185
{%- assign children_list = pages_list | where: "parent", node.title -%}
216186
{%- for child in children_list -%}
217187
{%- 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 -%}
219189
{%- assign second_level_url = child.url | absolute_url -%}
220190
{%- endif -%}
221191
{%- endif -%}
222192
{%- endfor -%}
223193
{%- endif -%}
224-
{%- endif -%}
194+
{%- endunless -%}
225195
{%- 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 -%}
228199
{%- assign toc_list = pages_list | where: "parent", page.title | where: "grand_parent", page.parent -%}
229200
{%- endif -%}
230201

0 commit comments

Comments
 (0)