From 345cdd04e6b85cc03ba040c18bf13d118b53af73 Mon Sep 17 00:00:00 2001 From: Sergei Gureev Date: Sat, 16 Jul 2022 15:22:17 +0300 Subject: [PATCH] Add sorting by slug --- components/content/src/sorting.rs | 34 +++++++++++++++++++ components/content/src/types.rs | 2 ++ docs/content/documentation/content/section.md | 7 ++-- 3 files changed, 41 insertions(+), 2 deletions(-) diff --git a/components/content/src/sorting.rs b/components/content/src/sorting.rs index 313df3674..eb4b91fb1 100644 --- a/components/content/src/sorting.rs +++ b/components/content/src/sorting.rs @@ -16,6 +16,7 @@ pub fn sort_pages(pages: &[&Page], sort_by: SortBy) -> (Vec, Vec page.meta.title.is_some(), SortBy::Weight => page.meta.weight.is_some(), + SortBy::Slug => true, SortBy::None => unreachable!(), }); @@ -32,6 +33,7 @@ pub fn sort_pages(pages: &[&Page], sort_by: SortBy) -> (Vec, Vec a.meta.weight.unwrap().cmp(&b.meta.weight.unwrap()), + SortBy::Slug => natural_lexical_cmp(&a.slug, &b.slug), SortBy::None => unreachable!(), }; @@ -73,6 +75,16 @@ mod tests { Page::new(format!("content/hello-{}.md", weight), front_matter, &PathBuf::new()) } + fn create_page_with_slug(slug: &str) -> Page { + let front_matter = PageFrontMatter { slug: Some(slug.to_owned()), ..Default::default() }; + let mut page = + Page::new(format!("content/hello-{}.md", slug), front_matter, &PathBuf::new()); + // Normally, the slug field is populated when a page is parsed, but + // since we're creating one manually, we have to set it explicitly + page.slug = slug.to_owned(); + page + } + #[test] fn can_sort_by_dates() { let page1 = create_page_with_date("2018-01-01", None); @@ -185,6 +197,28 @@ mod tests { ); } + #[test] + fn can_sort_by_slug() { + let page1 = create_page_with_slug("2"); + let page2 = create_page_with_slug("3"); + let page3 = create_page_with_slug("1"); + let (pages, ignored_pages) = sort_pages(&[&page1, &page2, &page3], SortBy::Slug); + assert_eq!(pages[0], page3.file.path); + assert_eq!(pages[1], page1.file.path); + assert_eq!(pages[2], page2.file.path); + assert_eq!(ignored_pages.len(), 0); + + // 10 should come after 2 + let page1 = create_page_with_slug("1"); + let page2 = create_page_with_slug("10"); + let page3 = create_page_with_slug("2"); + let (pages, ignored_pages) = sort_pages(&[&page1, &page2, &page3], SortBy::Slug); + assert_eq!(pages[0], page1.file.path); + assert_eq!(pages[1], page3.file.path); + assert_eq!(pages[2], page2.file.path); + assert_eq!(ignored_pages.len(), 0); + } + #[test] fn can_find_ignored_pages() { let page1 = create_page_with_date("2018-01-01", None); diff --git a/components/content/src/types.rs b/components/content/src/types.rs index e058dec9a..4d78303e8 100644 --- a/components/content/src/types.rs +++ b/components/content/src/types.rs @@ -15,6 +15,8 @@ pub enum SortBy { TitleBytes, /// Lower weight comes first Weight, + /// Sort by slug + Slug, /// No sorting None, } diff --git a/docs/content/documentation/content/section.md b/docs/content/documentation/content/section.md index c569205f8..708875091 100644 --- a/docs/content/documentation/content/section.md +++ b/docs/content/documentation/content/section.md @@ -187,11 +187,14 @@ of the Swedish alphabet, åäö, for example would be considered by the natural sort as aao. In that case the standard byte-order sort may be more suitable. ### `weight` -This will be sort all pages by their `weight` field, from lightest weight -(at the top of the list) to heaviest (at the bottom of the list). Each +This will sort all pages by their `weight` field, from the lightest weight +(at the top of the list) to the heaviest (at the bottom of the list). Each page gets `page.lower` and `page.higher` variables that contain the pages with lighter and heavier weights, respectively. +### `slug` +This will sort pages or sections by their slug in natural lexical order. + ### Reversed sorting When iterating through pages, you may wish to use the Tera `reverse` filter, which reverses the order of the pages. For example, after using the `reverse` filter,