Skip to content

Commit

Permalink
Add sorting by slug (#1926)
Browse files Browse the repository at this point in the history
  • Loading branch information
bemyak authored Aug 29, 2022
1 parent 3c8c204 commit 44ced17
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 2 deletions.
34 changes: 34 additions & 0 deletions components/content/src/sorting.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ pub fn sort_pages(pages: &[&Page], sort_by: SortBy) -> (Vec<PathBuf>, Vec<PathBu
}
SortBy::Title | SortBy::TitleBytes => page.meta.title.is_some(),
SortBy::Weight => page.meta.weight.is_some(),
SortBy::Slug => true,
SortBy::None => unreachable!(),
});

Expand All @@ -32,6 +33,7 @@ pub fn sort_pages(pages: &[&Page], sort_by: SortBy) -> (Vec<PathBuf>, Vec<PathBu
a.meta.title.as_ref().unwrap().cmp(b.meta.title.as_ref().unwrap())
}
SortBy::Weight => a.meta.weight.unwrap().cmp(&b.meta.weight.unwrap()),
SortBy::Slug => natural_lexical_cmp(&a.slug, &b.slug),
SortBy::None => unreachable!(),
};

Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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);
Expand Down
2 changes: 2 additions & 0 deletions components/content/src/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ pub enum SortBy {
TitleBytes,
/// Lower weight comes first
Weight,
/// Sort by slug
Slug,
/// No sorting
None,
}
7 changes: 5 additions & 2 deletions docs/content/documentation/content/section.md
Original file line number Diff line number Diff line change
Expand Up @@ -188,11 +188,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,
Expand Down

0 comments on commit 44ced17

Please sign in to comment.