From 4fc59a578fc987ea2dc67455c22bc5c356a0218b Mon Sep 17 00:00:00 2001 From: PLanCompS <18308236+pdmosses@users.noreply.github.com> Date: Tue, 11 Aug 2020 18:25:58 +0200 Subject: [PATCH] Separate sorting of numbers and strings for navigation order The values of `title` and `nav_order` can be numbers or strings. Jekyll gives build failures when sorting on mixtures of different types, so numbers and strings need to be sorted separately. Here, numbers are sorted by their values, and come before all strings. An omitted `nav_order` value is equivalent to the page's `title` value (except that a numerical `title` value is treated as a string). The case-sensitivity of string sorting is determined by `site.nav_sort`. --- _config.yml | 2 +- _includes/nav.html | 59 ++++++++++++++++++++++++++----- docs/tests/42.md | 11 ++++++ docs/{ => tests}/untitled-test.md | 0 4 files changed, 63 insertions(+), 9 deletions(-) create mode 100644 docs/tests/42.md rename docs/{ => tests}/untitled-test.md (100%) diff --git a/_config.yml b/_config.yml index fd71b516..32309d8a 100644 --- a/_config.yml +++ b/_config.yml @@ -19,7 +19,7 @@ baseurl: "/just-the-docs" # the subpath of your site, e.g. /blog url: "https://pmarsceill.github.io" # the base hostname & protocol for your site, e.g. http://example.com permalink: pretty -exclude: ["node_modules/", "*.gemspec", "*.gem", "Gemfile", "Gemfile.lock", "package.json", "package-lock.json", "script/", "LICENSE.txt", "lib/", "bin/", "README.md", "Rakefile"] +exclude: ["node_modules/", "*.gemspec", "*.gem", "Gemfile", "Gemfile.lock", "package.json", "package-lock.json", "script/", "LICENSE.txt", "lib/", "bin/", "README.md", "Rakefile", "docs/tests/"] # Set a path/url to a logo that will be displayed instead of the title #logo: "/assets/images/just-the-docs.png" diff --git a/_includes/nav.html b/_includes/nav.html index d74c17cb..748b6cea 100644 --- a/_includes/nav.html +++ b/_includes/nav.html @@ -1,15 +1,58 @@ <ul class="nav-list"> - {%- assign included_pages_list = site.html_pages | where_exp:"item", "item.nav_exclude != true" | where_exp:"item", "item.title != nil" -%} - {%- assign ordered_pages_list = included_pages_list | where_exp:"item", "item.nav_order != nil" -%} - {%- assign unordered_pages_list = included_pages_list | where_exp:"item", "item.nav_order == nil" -%} + {%- assign included_pages = site.html_pages + | where_exp:"item", "item.nav_exclude != true" + | where_exp:"item", "item.title != nil" -%} + + {%- comment -%} + A nav_order value can be a number or a string. + Numbers are sorted by their values, before strings. + An omitted nav_order value is equivalent to the title value, + except that a numerical title value is treated as a string. + The case-sensitivity of string sorting is determined by site.nav_sort. + {%- endcomment -%} + + {%- assign string_ordered_pages = included_pages + | where_exp:"item", "item.nav_order == nil" -%} + {%- assign nav_ordered_pages = included_pages + | where_exp:"item", "item.nav_order != nil" -%} + + {%- comment -%} + The nav_ordered_pages have to be added to number_ordered_pages and + string_ordered_pages, depending on the nav_order value. + The first character of jsonify is `"` only for strings. + {%- endcomment -%} + {%- assign nav_ordered_groups = nav_ordered_pages + | group_by_exp:"item", "item.nav_order | jsonify | slice: 0" -%} + {%- assign number_ordered_pages = "" | split:"X" -%} + {%- for group in nav_ordered_groups -%} + {%- if group.name == '"' -%} + {%- assign string_ordered_pages = string_ordered_pages | concat: group.items -%} + {%- else -%} + {%- assign number_ordered_pages = number_ordered_pages | concat: group.items -%} + {%- endif -%} + {%- endfor -%} + + {%- assign sorted_number_ordered_pages = number_ordered_pages | sort:"nav_order" -%} + + {%- comment -%} + The string_ordered_pages have to be sorted by nav_order, and otherwise title. + After grouping them by those values, the groups are sorted, then the items + of each group are concatenated. + {%- endcomment -%} + {%- assign string_ordered_groups = string_ordered_pages + | group_by_exp:"item", "item.nav_order | default: item.title | string" -%} {%- if site.nav_sort == 'case_insensitive' -%} - {%- assign sorted_ordered_pages_list = ordered_pages_list | sort_natural:"nav_order" -%} - {%- assign sorted_unordered_pages_list = unordered_pages_list | sort_natural:"title" -%} + {%- assign sorted_string_ordered_groups = string_ordered_groups | sort_natural:"name" -%} {%- else -%} - {%- assign sorted_ordered_pages_list = ordered_pages_list | sort:"nav_order" -%} - {%- assign sorted_unordered_pages_list = unordered_pages_list | sort:"title" -%} + {%- assign sorted_string_ordered_groups = string_ordered_groups | sort:"name" -%} {%- endif -%} - {%- assign pages_list = sorted_ordered_pages_list | concat: sorted_unordered_pages_list -%} + {%- assign sorted_string_ordered_pages = "" | split:"X" -%} + {%- for group in sorted_string_ordered_groups -%} + {%- assign sorted_string_ordered_pages = sorted_string_ordered_pages | concat: group.items -%} + {%- endfor -%} + + {%- assign pages_list = sorted_number_ordered_pages | concat: sorted_string_ordered_pages -%} + {%- for node in pages_list -%} {%- if node.parent == nil -%} <li class="nav-list-item{% if page.url == node.url or page.parent == node.title or page.grand_parent == node.title %} active{% endif %}"> diff --git a/docs/tests/42.md b/docs/tests/42.md new file mode 100644 index 00000000..fba05901 --- /dev/null +++ b/docs/tests/42.md @@ -0,0 +1,11 @@ +--- +layout: default +title: 42 +search_exclude: true +--- + +# The answer is 42 + +A link to this page should appear in the navigation after all pages where +the `nav_order` value is a number, because titles are treated as strings +when used as default `nav_order`s. diff --git a/docs/untitled-test.md b/docs/tests/untitled-test.md similarity index 100% rename from docs/untitled-test.md rename to docs/tests/untitled-test.md -- GitLab