Reverse pagination (#1147)
* mention code block output change * Update snap * Update themes gallery (#1082) Co-authored-by: GitHub Action <action@github.com> * Deployment guide for Vercel * Change wording a bit * Update themes gallery (#1122) Co-authored-by: GitHub Action <action@github.com> * Add feed autodiscovery documentation (#1123) * Add feed autodiscovery documentation * Fix link in template * Docs/configuration update (#1126) * Update configuration documentation - Attempt to split the configuration file into sections to make it more readable and avoid configuration mistakes (#1056). - Move translation instructions to the right part. - Add a bit more explanations to the extra section. * Take into account @Keats feedbacks * Remove short notice about translation usage - A i18n page should be created to better explain it. * add fix for (#1135) Taxonomies with identical slugs now get merged (#1136) * add test and implementation for reverse pagination * incorporate review changes Co-authored-by: Michael Plotke <bdjnks@gmail.com> Co-authored-by: Vincent Prouillet <balthek@gmail.com> Co-authored-by: GitHub Action <action@github.com> Co-authored-by: Samyak Bakliwal <w3bcode@gmail.com> Co-authored-by: René Ribaud <uggla@free.fr>
This commit is contained in:
parent
5ec3a9ca65
commit
c143d95c4e
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -27,3 +27,4 @@ stage
|
||||||
shell.nix
|
shell.nix
|
||||||
# vim temporary files
|
# vim temporary files
|
||||||
**/.*.sw*
|
**/.*.sw*
|
||||||
|
.swp
|
||||||
|
|
|
@ -71,7 +71,10 @@ pub fn split_section_content<'c>(
|
||||||
|
|
||||||
/// Split a file between the front matter and its content
|
/// Split a file between the front matter and its content
|
||||||
/// Returns a parsed `PageFrontMatter` and the rest of the content
|
/// Returns a parsed `PageFrontMatter` and the rest of the content
|
||||||
pub fn split_page_content<'c>(file_path: &Path, content: &'c str) -> Result<(PageFrontMatter, &'c str)> {
|
pub fn split_page_content<'c>(
|
||||||
|
file_path: &Path,
|
||||||
|
content: &'c str,
|
||||||
|
) -> Result<(PageFrontMatter, &'c str)> {
|
||||||
let (front_matter, content) = split_content(file_path, content)?;
|
let (front_matter, content) = split_content(file_path, content)?;
|
||||||
let meta = PageFrontMatter::parse(&front_matter).map_err(|e| {
|
let meta = PageFrontMatter::parse(&front_matter).map_err(|e| {
|
||||||
Error::chain(
|
Error::chain(
|
||||||
|
|
|
@ -37,8 +37,6 @@ pub struct PageFrontMatter {
|
||||||
/// Can't be an empty string if present
|
/// Can't be an empty string if present
|
||||||
pub path: Option<String>,
|
pub path: Option<String>,
|
||||||
pub taxonomies: HashMap<String, Vec<String>>,
|
pub taxonomies: HashMap<String, Vec<String>>,
|
||||||
/// Integer to use to order content. Lowest is at the bottom, highest first
|
|
||||||
pub order: Option<usize>,
|
|
||||||
/// Integer to use to order content. Highest is at the bottom, lowest first
|
/// Integer to use to order content. Highest is at the bottom, lowest first
|
||||||
pub weight: Option<usize>,
|
pub weight: Option<usize>,
|
||||||
/// All aliases for that page. Zola will create HTML templates that will
|
/// All aliases for that page. Zola will create HTML templates that will
|
||||||
|
@ -112,10 +110,6 @@ impl PageFrontMatter {
|
||||||
self.datetime_tuple = self.datetime.map(|dt| (dt.year(), dt.month(), dt.day()));
|
self.datetime_tuple = self.datetime.map(|dt| (dt.year(), dt.month(), dt.day()));
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn order(&self) -> usize {
|
|
||||||
self.order.unwrap()
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn weight(&self) -> usize {
|
pub fn weight(&self) -> usize {
|
||||||
self.weight.unwrap()
|
self.weight.unwrap()
|
||||||
}
|
}
|
||||||
|
@ -134,7 +128,6 @@ impl Default for PageFrontMatter {
|
||||||
slug: None,
|
slug: None,
|
||||||
path: None,
|
path: None,
|
||||||
taxonomies: HashMap::new(),
|
taxonomies: HashMap::new(),
|
||||||
order: None,
|
|
||||||
weight: None,
|
weight: None,
|
||||||
aliases: Vec::new(),
|
aliases: Vec::new(),
|
||||||
in_search_index: true,
|
in_search_index: true,
|
||||||
|
|
|
@ -28,6 +28,9 @@ pub struct SectionFrontMatter {
|
||||||
/// How many pages to be displayed per paginated page. No pagination will happen if this isn't set
|
/// How many pages to be displayed per paginated page. No pagination will happen if this isn't set
|
||||||
#[serde(skip_serializing)]
|
#[serde(skip_serializing)]
|
||||||
pub paginate_by: Option<usize>,
|
pub paginate_by: Option<usize>,
|
||||||
|
/// Whether to reverse the order of the pages before segmenting into pagers
|
||||||
|
#[serde(skip_serializing)]
|
||||||
|
pub paginate_reversed: bool,
|
||||||
/// Path to be used by pagination: the page number will be appended after it. Defaults to `page`.
|
/// Path to be used by pagination: the page number will be appended after it. Defaults to `page`.
|
||||||
#[serde(skip_serializing)]
|
#[serde(skip_serializing)]
|
||||||
pub paginate_path: String,
|
pub paginate_path: String,
|
||||||
|
@ -100,6 +103,7 @@ impl Default for SectionFrontMatter {
|
||||||
weight: 0,
|
weight: 0,
|
||||||
template: None,
|
template: None,
|
||||||
paginate_by: None,
|
paginate_by: None,
|
||||||
|
paginate_reversed: false,
|
||||||
paginate_path: DEFAULT_PAGINATE_PATH.to_string(),
|
paginate_path: DEFAULT_PAGINATE_PATH.to_string(),
|
||||||
render: true,
|
render: true,
|
||||||
redirect_to: None,
|
redirect_to: None,
|
||||||
|
|
|
@ -150,6 +150,11 @@ impl<'a> SerializingPage<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// currently only used in testing
|
||||||
|
pub fn get_title(&'a self) -> &'a Option<String> {
|
||||||
|
&self.title
|
||||||
|
}
|
||||||
|
|
||||||
/// Same as from_page but does not fill sibling pages
|
/// Same as from_page but does not fill sibling pages
|
||||||
pub fn from_page_basic(page: &'a Page, library: Option<&'a Library>) -> Self {
|
pub fn from_page_basic(page: &'a Page, library: Option<&'a Library>) -> Self {
|
||||||
let mut year = None;
|
let mut year = None;
|
||||||
|
|
|
@ -12,6 +12,8 @@ use crate::content::{Section, SerializingPage, SerializingSection};
|
||||||
use crate::library::Library;
|
use crate::library::Library;
|
||||||
use crate::taxonomies::{Taxonomy, TaxonomyItem};
|
use crate::taxonomies::{Taxonomy, TaxonomyItem};
|
||||||
|
|
||||||
|
use std::borrow::Cow;
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq)]
|
#[derive(Clone, Debug, PartialEq)]
|
||||||
enum PaginationRoot<'a> {
|
enum PaginationRoot<'a> {
|
||||||
Section(&'a Section),
|
Section(&'a Section),
|
||||||
|
@ -45,11 +47,13 @@ impl<'a> Pager<'a> {
|
||||||
#[derive(Clone, Debug, PartialEq)]
|
#[derive(Clone, Debug, PartialEq)]
|
||||||
pub struct Paginator<'a> {
|
pub struct Paginator<'a> {
|
||||||
/// All pages in the section/taxonomy
|
/// All pages in the section/taxonomy
|
||||||
all_pages: &'a [DefaultKey],
|
all_pages: Cow<'a, [DefaultKey]>,
|
||||||
/// Pages split in chunks of `paginate_by`
|
/// Pages split in chunks of `paginate_by`
|
||||||
pub pagers: Vec<Pager<'a>>,
|
pub pagers: Vec<Pager<'a>>,
|
||||||
/// How many content pages on a paginated page at max
|
/// How many content pages on a paginated page at max
|
||||||
paginate_by: usize,
|
paginate_by: usize,
|
||||||
|
/// whether to reverse before grouping
|
||||||
|
paginate_reversed: bool,
|
||||||
/// The thing we are creating the paginator for: section or taxonomy
|
/// The thing we are creating the paginator for: section or taxonomy
|
||||||
root: PaginationRoot<'a>,
|
root: PaginationRoot<'a>,
|
||||||
// Those below can be obtained from the root but it would make the code more complex than needed
|
// Those below can be obtained from the root but it would make the code more complex than needed
|
||||||
|
@ -66,10 +70,12 @@ impl<'a> Paginator<'a> {
|
||||||
/// It will always at least create one pager (the first) even if there are not enough pages to paginate
|
/// It will always at least create one pager (the first) even if there are not enough pages to paginate
|
||||||
pub fn from_section(section: &'a Section, library: &'a Library) -> Paginator<'a> {
|
pub fn from_section(section: &'a Section, library: &'a Library) -> Paginator<'a> {
|
||||||
let paginate_by = section.meta.paginate_by.unwrap();
|
let paginate_by = section.meta.paginate_by.unwrap();
|
||||||
|
let paginate_reversed = section.meta.paginate_reversed;
|
||||||
let mut paginator = Paginator {
|
let mut paginator = Paginator {
|
||||||
all_pages: §ion.pages,
|
all_pages: Cow::from(§ion.pages[..]),
|
||||||
pagers: Vec::with_capacity(section.pages.len() / paginate_by),
|
pagers: Vec::with_capacity(section.pages.len() / paginate_by),
|
||||||
paginate_by,
|
paginate_by,
|
||||||
|
paginate_reversed,
|
||||||
root: PaginationRoot::Section(section),
|
root: PaginationRoot::Section(section),
|
||||||
permalink: section.permalink.clone(),
|
permalink: section.permalink.clone(),
|
||||||
path: section.path.clone(),
|
path: section.path.clone(),
|
||||||
|
@ -91,9 +97,10 @@ impl<'a> Paginator<'a> {
|
||||||
) -> Paginator<'a> {
|
) -> Paginator<'a> {
|
||||||
let paginate_by = taxonomy.kind.paginate_by.unwrap();
|
let paginate_by = taxonomy.kind.paginate_by.unwrap();
|
||||||
let mut paginator = Paginator {
|
let mut paginator = Paginator {
|
||||||
all_pages: &item.pages,
|
all_pages: Cow::Borrowed(&item.pages),
|
||||||
pagers: Vec::with_capacity(item.pages.len() / paginate_by),
|
pagers: Vec::with_capacity(item.pages.len() / paginate_by),
|
||||||
paginate_by,
|
paginate_by,
|
||||||
|
paginate_reversed: false,
|
||||||
root: PaginationRoot::Taxonomy(taxonomy, item),
|
root: PaginationRoot::Taxonomy(taxonomy, item),
|
||||||
permalink: item.permalink.clone(),
|
permalink: item.permalink.clone(),
|
||||||
path: format!("/{}/{}/", taxonomy.kind.name, item.slug),
|
path: format!("/{}/{}/", taxonomy.kind.name, item.slug),
|
||||||
|
@ -106,6 +113,7 @@ impl<'a> Paginator<'a> {
|
||||||
template: format!("{}/single.html", taxonomy.kind.name),
|
template: format!("{}/single.html", taxonomy.kind.name),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// taxonomy paginators have no sorting so we won't have to reverse
|
||||||
paginator.fill_pagers(library);
|
paginator.fill_pagers(library);
|
||||||
paginator
|
paginator
|
||||||
}
|
}
|
||||||
|
@ -116,8 +124,12 @@ impl<'a> Paginator<'a> {
|
||||||
// the pages in the current pagers
|
// the pages in the current pagers
|
||||||
let mut current_page = vec![];
|
let mut current_page = vec![];
|
||||||
|
|
||||||
for key in self.all_pages {
|
if self.paginate_reversed {
|
||||||
let page = library.get_page_by_key(*key);
|
self.all_pages.to_mut().reverse();
|
||||||
|
}
|
||||||
|
|
||||||
|
for key in self.all_pages.to_mut().iter_mut() {
|
||||||
|
let page = library.get_page_by_key(key.clone());
|
||||||
current_page.push(page.to_serialized_basic(library));
|
current_page.push(page.to_serialized_basic(library));
|
||||||
|
|
||||||
if current_page.len() == self.paginate_by {
|
if current_page.len() == self.paginate_by {
|
||||||
|
@ -246,10 +258,11 @@ mod tests {
|
||||||
|
|
||||||
use super::Paginator;
|
use super::Paginator;
|
||||||
|
|
||||||
fn create_section(is_index: bool) -> Section {
|
fn create_section(is_index: bool, paginate_reversed: bool) -> Section {
|
||||||
let mut f = SectionFrontMatter::default();
|
let mut f = SectionFrontMatter::default();
|
||||||
f.paginate_by = Some(2);
|
f.paginate_by = Some(2);
|
||||||
f.paginate_path = "page".to_string();
|
f.paginate_path = "page".to_string();
|
||||||
|
f.paginate_reversed = paginate_reversed;
|
||||||
let mut s = Section::new("content/_index.md", f, &PathBuf::new());
|
let mut s = Section::new("content/_index.md", f, &PathBuf::new());
|
||||||
if !is_index {
|
if !is_index {
|
||||||
s.path = "/posts/".to_string();
|
s.path = "/posts/".to_string();
|
||||||
|
@ -262,15 +275,22 @@ mod tests {
|
||||||
s
|
s
|
||||||
}
|
}
|
||||||
|
|
||||||
fn create_library(is_index: bool) -> (Section, Library) {
|
fn create_library(
|
||||||
let mut library = Library::new(3, 0, false);
|
is_index: bool,
|
||||||
library.insert_page(Page::default());
|
num_pages: usize,
|
||||||
library.insert_page(Page::default());
|
paginate_reversed: bool,
|
||||||
library.insert_page(Page::default());
|
) -> (Section, Library) {
|
||||||
|
let mut library = Library::new(num_pages, 0, false);
|
||||||
|
for i in 1..=num_pages {
|
||||||
|
let mut page = Page::default();
|
||||||
|
page.meta.title = Some(i.to_string());
|
||||||
|
library.insert_page(page);
|
||||||
|
}
|
||||||
|
|
||||||
let mut draft = Page::default();
|
let mut draft = Page::default();
|
||||||
draft.meta.draft = true;
|
draft.meta.draft = true;
|
||||||
library.insert_page(draft);
|
library.insert_page(draft);
|
||||||
let mut section = create_section(is_index);
|
let mut section = create_section(is_index, paginate_reversed);
|
||||||
section.pages = library.pages().keys().collect();
|
section.pages = library.pages().keys().collect();
|
||||||
library.insert_section(section.clone());
|
library.insert_section(section.clone());
|
||||||
|
|
||||||
|
@ -279,7 +299,7 @@ mod tests {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_can_create_paginator() {
|
fn test_can_create_paginator() {
|
||||||
let (section, library) = create_library(false);
|
let (section, library) = create_library(false, 3, false);
|
||||||
let paginator = Paginator::from_section(§ion, &library);
|
let paginator = Paginator::from_section(§ion, &library);
|
||||||
assert_eq!(paginator.pagers.len(), 2);
|
assert_eq!(paginator.pagers.len(), 2);
|
||||||
|
|
||||||
|
@ -294,9 +314,56 @@ mod tests {
|
||||||
assert_eq!(paginator.pagers[1].path, "/posts/page/2/");
|
assert_eq!(paginator.pagers[1].path, "/posts/page/2/");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_can_create_reversed_paginator() {
|
||||||
|
// 6 pages, 5 normal and 1 draft
|
||||||
|
let (section, library) = create_library(false, 5, true);
|
||||||
|
let paginator = Paginator::from_section(§ion, &library);
|
||||||
|
assert_eq!(paginator.pagers.len(), 3);
|
||||||
|
|
||||||
|
assert_eq!(paginator.pagers[0].index, 1);
|
||||||
|
assert_eq!(paginator.pagers[0].pages.len(), 2);
|
||||||
|
assert_eq!(paginator.pagers[0].permalink, "https://vincent.is/posts/");
|
||||||
|
assert_eq!(paginator.pagers[0].path, "/posts/");
|
||||||
|
assert_eq!(
|
||||||
|
vec!["".to_string(), "5".to_string()],
|
||||||
|
paginator.pagers[0]
|
||||||
|
.pages
|
||||||
|
.iter()
|
||||||
|
.map(|p| p.get_title().as_ref().unwrap_or(&"".to_string()).to_string())
|
||||||
|
.collect::<Vec<String>>()
|
||||||
|
);
|
||||||
|
|
||||||
|
assert_eq!(paginator.pagers[1].index, 2);
|
||||||
|
assert_eq!(paginator.pagers[1].pages.len(), 2);
|
||||||
|
assert_eq!(paginator.pagers[1].permalink, "https://vincent.is/posts/page/2/");
|
||||||
|
assert_eq!(paginator.pagers[1].path, "/posts/page/2/");
|
||||||
|
assert_eq!(
|
||||||
|
vec!["4".to_string(), "3".to_string()],
|
||||||
|
paginator.pagers[1]
|
||||||
|
.pages
|
||||||
|
.iter()
|
||||||
|
.map(|p| p.get_title().as_ref().unwrap_or(&"".to_string()).to_string())
|
||||||
|
.collect::<Vec<String>>()
|
||||||
|
);
|
||||||
|
|
||||||
|
assert_eq!(paginator.pagers[2].index, 3);
|
||||||
|
assert_eq!(paginator.pagers[2].pages.len(), 2);
|
||||||
|
assert_eq!(paginator.pagers[2].permalink, "https://vincent.is/posts/page/3/");
|
||||||
|
assert_eq!(paginator.pagers[2].path, "/posts/page/3/");
|
||||||
|
assert_eq!(
|
||||||
|
vec!["2".to_string(), "1".to_string()],
|
||||||
|
paginator.pagers[2]
|
||||||
|
.pages
|
||||||
|
.iter()
|
||||||
|
.map(|p| p.get_title().as_ref().unwrap_or(&"".to_string()).to_string())
|
||||||
|
.collect::<Vec<String>>()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_can_create_paginator_for_index() {
|
fn test_can_create_paginator_for_index() {
|
||||||
let (section, library) = create_library(true);
|
let (section, library) = create_library(true, 3, false);
|
||||||
let paginator = Paginator::from_section(§ion, &library);
|
let paginator = Paginator::from_section(§ion, &library);
|
||||||
assert_eq!(paginator.pagers.len(), 2);
|
assert_eq!(paginator.pagers.len(), 2);
|
||||||
|
|
||||||
|
@ -313,7 +380,7 @@ mod tests {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_can_build_paginator_context() {
|
fn test_can_build_paginator_context() {
|
||||||
let (section, library) = create_library(false);
|
let (section, library) = create_library(false, 3, false);
|
||||||
let paginator = Paginator::from_section(§ion, &library);
|
let paginator = Paginator::from_section(§ion, &library);
|
||||||
assert_eq!(paginator.pagers.len(), 2);
|
assert_eq!(paginator.pagers.len(), 2);
|
||||||
|
|
||||||
|
@ -337,7 +404,7 @@ mod tests {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_can_create_paginator_for_taxonomy() {
|
fn test_can_create_paginator_for_taxonomy() {
|
||||||
let (_, library) = create_library(false);
|
let (_, library) = create_library(false, 3, false);
|
||||||
let taxonomy_def = TaxonomyConfig {
|
let taxonomy_def = TaxonomyConfig {
|
||||||
name: "tags".to_string(),
|
name: "tags".to_string(),
|
||||||
paginate_by: Some(2),
|
paginate_by: Some(2),
|
||||||
|
@ -367,7 +434,7 @@ mod tests {
|
||||||
// https://github.com/getzola/zola/issues/866
|
// https://github.com/getzola/zola/issues/866
|
||||||
#[test]
|
#[test]
|
||||||
fn works_with_empty_paginate_path() {
|
fn works_with_empty_paginate_path() {
|
||||||
let (mut section, library) = create_library(false);
|
let (mut section, library) = create_library(false, 3, false);
|
||||||
section.meta.paginate_path = String::new();
|
section.meta.paginate_path = String::new();
|
||||||
let paginator = Paginator::from_section(§ion, &library);
|
let paginator = Paginator::from_section(§ion, &library);
|
||||||
assert_eq!(paginator.pagers.len(), 2);
|
assert_eq!(paginator.pagers.len(), 2);
|
||||||
|
|
|
@ -19,7 +19,7 @@ fn can_parse_site() {
|
||||||
let library = site.library.read().unwrap();
|
let library = site.library.read().unwrap();
|
||||||
|
|
||||||
// Correct number of pages (sections do not count as pages, draft are ignored)
|
// Correct number of pages (sections do not count as pages, draft are ignored)
|
||||||
assert_eq!(library.pages().len(), 23);
|
assert_eq!(library.pages().len(), 32);
|
||||||
let posts_path = path.join("content").join("posts");
|
let posts_path = path.join("content").join("posts");
|
||||||
|
|
||||||
// Make sure the page with a url doesn't have any sections
|
// Make sure the page with a url doesn't have any sections
|
||||||
|
@ -32,11 +32,11 @@ fn can_parse_site() {
|
||||||
assert_eq!(asset_folder_post.file.components, vec!["posts".to_string()]);
|
assert_eq!(asset_folder_post.file.components, vec!["posts".to_string()]);
|
||||||
|
|
||||||
// That we have the right number of sections
|
// That we have the right number of sections
|
||||||
assert_eq!(library.sections().len(), 11);
|
assert_eq!(library.sections().len(), 12);
|
||||||
|
|
||||||
// And that the sections are correct
|
// And that the sections are correct
|
||||||
let index_section = library.get_section(&path.join("content").join("_index.md")).unwrap();
|
let index_section = library.get_section(&path.join("content").join("_index.md")).unwrap();
|
||||||
assert_eq!(index_section.subsections.len(), 4);
|
assert_eq!(index_section.subsections.len(), 5);
|
||||||
assert_eq!(index_section.pages.len(), 3);
|
assert_eq!(index_section.pages.len(), 3);
|
||||||
assert!(index_section.ancestors.is_empty());
|
assert!(index_section.ancestors.is_empty());
|
||||||
|
|
||||||
|
@ -582,7 +582,7 @@ fn can_build_site_with_pagination_for_taxonomy() {
|
||||||
"tags/a/page/1/index.html",
|
"tags/a/page/1/index.html",
|
||||||
"http-equiv=\"refresh\" content=\"0; url=https://replace-this-with-your-url.com/tags/a/\""
|
"http-equiv=\"refresh\" content=\"0; url=https://replace-this-with-your-url.com/tags/a/\""
|
||||||
));
|
));
|
||||||
assert!(file_contains!(public, "tags/a/index.html", "Num pagers: 6"));
|
assert!(file_contains!(public, "tags/a/index.html", "Num pagers: 8"));
|
||||||
assert!(file_contains!(public, "tags/a/index.html", "Page size: 2"));
|
assert!(file_contains!(public, "tags/a/index.html", "Page size: 2"));
|
||||||
assert!(file_contains!(public, "tags/a/index.html", "Current index: 1"));
|
assert!(file_contains!(public, "tags/a/index.html", "Current index: 1"));
|
||||||
assert!(!file_contains!(public, "tags/a/index.html", "has_prev"));
|
assert!(!file_contains!(public, "tags/a/index.html", "has_prev"));
|
||||||
|
@ -595,7 +595,7 @@ fn can_build_site_with_pagination_for_taxonomy() {
|
||||||
assert!(file_contains!(
|
assert!(file_contains!(
|
||||||
public,
|
public,
|
||||||
"tags/a/index.html",
|
"tags/a/index.html",
|
||||||
"Last: https://replace-this-with-your-url.com/tags/a/page/6/"
|
"Last: https://replace-this-with-your-url.com/tags/a/page/8/"
|
||||||
));
|
));
|
||||||
assert_eq!(file_contains!(public, "tags/a/index.html", "has_prev"), false);
|
assert_eq!(file_contains!(public, "tags/a/index.html", "has_prev"), false);
|
||||||
|
|
||||||
|
@ -603,7 +603,7 @@ fn can_build_site_with_pagination_for_taxonomy() {
|
||||||
assert!(file_contains!(
|
assert!(file_contains!(
|
||||||
public,
|
public,
|
||||||
"sitemap.xml",
|
"sitemap.xml",
|
||||||
"<loc>https://replace-this-with-your-url.com/tags/a/page/6/</loc>"
|
"<loc>https://replace-this-with-your-url.com/tags/a/page/8/</loc>"
|
||||||
));
|
));
|
||||||
|
|
||||||
// current_path
|
// current_path
|
||||||
|
@ -721,7 +721,11 @@ fn can_build_site_with_html_minified() {
|
||||||
|
|
||||||
assert!(&public.exists());
|
assert!(&public.exists());
|
||||||
assert!(file_exists!(public, "index.html"));
|
assert!(file_exists!(public, "index.html"));
|
||||||
assert!(file_contains!(public, "index.html", "<!DOCTYPE html><html lang=en><head><meta charset=UTF-8>"));
|
assert!(file_contains!(
|
||||||
|
public,
|
||||||
|
"index.html",
|
||||||
|
"<!DOCTYPE html><html lang=en><head><meta charset=UTF-8>"
|
||||||
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|
|
@ -156,6 +156,7 @@ This will be sort all pages by their `weight` field, from lightest weight
|
||||||
page gets `page.lighter` and `page.heavier` variables that contain the
|
page gets `page.lighter` and `page.heavier` variables that contain the
|
||||||
pages with lighter and heavier weights, respectively.
|
pages with lighter and heavier weights, respectively.
|
||||||
|
|
||||||
|
### Reversed sorting
|
||||||
When iterating through pages, you may wish to use the Tera `reverse` filter,
|
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,
|
which reverses the order of the pages. For example, after using the `reverse` filter,
|
||||||
pages sorted by weight will be sorted from lightest (at the top) to heaviest
|
pages sorted by weight will be sorted from lightest (at the top) to heaviest
|
||||||
|
@ -164,6 +165,8 @@ to newest (at the bottom).
|
||||||
|
|
||||||
`reverse` has no effect on `page.later`/`page.earlier` or `page.heavier`/`page.lighter`.
|
`reverse` has no effect on `page.later`/`page.earlier` or `page.heavier`/`page.lighter`.
|
||||||
|
|
||||||
|
If the section is paginated the `paginate_reversed=true` in the front matter of the relevant section should be set instead of using the filter.
|
||||||
|
|
||||||
## Sorting subsections
|
## Sorting subsections
|
||||||
Sorting sections is a bit less flexible: sections can only be sorted by `weight`,
|
Sorting sections is a bit less flexible: sections can only be sorted by `weight`,
|
||||||
and do not have variables that point to the heavier/lighter sections.
|
and do not have variables that point to the heavier/lighter sections.
|
||||||
|
|
|
@ -132,7 +132,6 @@ include_content = true
|
||||||
# become too big to load on the site. Defaults to not being set.
|
# become too big to load on the site. Defaults to not being set.
|
||||||
# truncate_content_length = 100
|
# truncate_content_length = 100
|
||||||
|
|
||||||
|
|
||||||
# Optional translation object. Keys should be language codes.
|
# Optional translation object. Keys should be language codes.
|
||||||
# Optional translation object. The key if present should be a language code.
|
# Optional translation object. The key if present should be a language code.
|
||||||
# Example:
|
# Example:
|
||||||
|
|
4
test_site/content/reverse-paginated/1.md
Normal file
4
test_site/content/reverse-paginated/1.md
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
+++
|
||||||
|
title="Page number: 1"
|
||||||
|
weight=1
|
||||||
|
+++
|
4
test_site/content/reverse-paginated/2.md
Normal file
4
test_site/content/reverse-paginated/2.md
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
+++
|
||||||
|
title="Page number: 2"
|
||||||
|
weight=2
|
||||||
|
+++
|
4
test_site/content/reverse-paginated/3.md
Normal file
4
test_site/content/reverse-paginated/3.md
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
+++
|
||||||
|
title="Page number: 3"
|
||||||
|
weight=3
|
||||||
|
+++
|
4
test_site/content/reverse-paginated/4.md
Normal file
4
test_site/content/reverse-paginated/4.md
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
+++
|
||||||
|
title="Page number: 4"
|
||||||
|
weight=4
|
||||||
|
+++
|
4
test_site/content/reverse-paginated/5.md
Normal file
4
test_site/content/reverse-paginated/5.md
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
+++
|
||||||
|
title="Page number: 5"
|
||||||
|
weight=5
|
||||||
|
+++
|
4
test_site/content/reverse-paginated/6.md
Normal file
4
test_site/content/reverse-paginated/6.md
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
+++
|
||||||
|
title="Page number: 6"
|
||||||
|
weight=6
|
||||||
|
+++
|
4
test_site/content/reverse-paginated/7.md
Normal file
4
test_site/content/reverse-paginated/7.md
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
+++
|
||||||
|
title="Page number: 7"
|
||||||
|
weight=7
|
||||||
|
+++
|
4
test_site/content/reverse-paginated/8.md
Normal file
4
test_site/content/reverse-paginated/8.md
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
+++
|
||||||
|
title="Page number: 8"
|
||||||
|
weight=8
|
||||||
|
+++
|
4
test_site/content/reverse-paginated/9.md
Normal file
4
test_site/content/reverse-paginated/9.md
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
+++
|
||||||
|
title="Page number: 9"
|
||||||
|
weight=9
|
||||||
|
+++
|
6
test_site/content/reverse-paginated/_index.md
Normal file
6
test_site/content/reverse-paginated/_index.md
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
+++
|
||||||
|
paginate_by = 2
|
||||||
|
template = "section_paginated.html"
|
||||||
|
sort_by = "weight"
|
||||||
|
paginate_reversed = true
|
||||||
|
+++
|
Loading…
Reference in a new issue