From 8711c9a3c025c144923cdb863383aaff888d9911 Mon Sep 17 00:00:00 2001 From: Vincent Prouillet Date: Fri, 12 May 2017 20:24:44 +0900 Subject: [PATCH] Change Site::section and fix empty paginated sections --- src/front_matter.rs | 2 +- src/pagination.rs | 15 +++++++++---- src/section.rs | 2 +- src/site.rs | 31 ++++++++++++++++++--------- test_site/content/paginated/_index.md | 4 ++++ test_site/content/posts/_index.md | 3 ++- tests/site.rs | 25 ++++++++++++++------- 7 files changed, 57 insertions(+), 25 deletions(-) create mode 100644 test_site/content/paginated/_index.md diff --git a/src/front_matter.rs b/src/front_matter.rs index 78715306..1c3a82d8 100644 --- a/src/front_matter.rs +++ b/src/front_matter.rs @@ -149,7 +149,7 @@ impl Default for FrontMatter { order: None, template: None, paginate_by: None, - paginate_path: None, + paginate_path: Some("page".to_string()), render: Some(true), extra: None, } diff --git a/src/pagination.rs b/src/pagination.rs index b7215c60..b3481376 100644 --- a/src/pagination.rs +++ b/src/pagination.rs @@ -23,10 +23,10 @@ pub struct Pager<'a> { impl<'a> Pager<'a> { fn new(index: usize, pages: Vec<&'a Page>, permalink: String, path: String) -> Pager<'a> { Pager { - index: index, - permalink: permalink, - path: path, - pages: pages, + index, + permalink, + path, + pages, } } } @@ -44,6 +44,8 @@ pub struct Paginator<'a> { } impl<'a> Paginator<'a> { + /// Create a new paginator + /// It will always at least create one pager (the first) even if there are no pages to paginate pub fn new(all_pages: &'a [Page], section: &'a Section) -> Paginator<'a> { let paginate_by = section.meta.paginate_by.unwrap(); let paginate_path = match section.meta.paginate_path { @@ -87,6 +89,11 @@ impl<'a> Paginator<'a> { )); } + // We always have the index one at least + if pagers.is_empty() { + pagers.push(Pager::new(1, vec![], section.permalink.clone(), section.path.clone())); + } + Paginator { all_pages: all_pages, pagers: pagers, diff --git a/src/section.rs b/src/section.rs index cab8a90c..82c4495d 100644 --- a/src/section.rs +++ b/src/section.rs @@ -149,7 +149,7 @@ impl ser::Serialize for Section { } impl Default for Section { - /// Used to create a default index section if there is no _index.md + /// Used to create a default index section if there is no _index.md in the root content directory fn default() -> Section { Section { file_path: PathBuf::new(), diff --git a/src/site.rs b/src/site.rs index 35eea9ac..11978bd2 100644 --- a/src/site.rs +++ b/src/site.rs @@ -173,9 +173,11 @@ impl Site { } // Insert a default index section so we don't need to create a _index.md to render // the index page - let index_path = self.base_path.join("content"); + let index_path = self.base_path.join("content").join("_index.md"); if !self.sections.contains_key(&index_path) { - self.sections.insert(index_path, Section::default()); + let mut index_section = Section::default(); + index_section.permalink = self.config.make_permalink(""); + self.sections.insert(index_path, index_section); } // A map of all .md files (section and pages) and their permalink @@ -217,7 +219,16 @@ impl Site { /// Simple wrapper fn to avoid repeating that code in several places fn add_section(&mut self, path: &Path) -> Result<()> { let section = Section::from_file(path, &self.config)?; - self.sections.insert(section.parent_path.clone(), section); + self.sections.insert(section.file_path.clone(), section); + Ok(()) + } + + /// Called in serve, add the section and render it + fn add_section_and_render(&mut self, path: &Path) -> Result<()> { + self.add_section(path)?; + let mut section = self.sections.get_mut(path).unwrap(); + self.permalinks.insert(section.relative_path.clone(), section.permalink.clone()); + section.render_markdown(&self.permalinks, &self.tera, &self.config)?; Ok(()) } @@ -239,10 +250,10 @@ impl Site { /// Find out the direct subsections of each subsection if there are some /// as well as the pages for each section - fn populate_sections(&mut self) { + pub fn populate_sections(&mut self) { for page in self.pages.values() { - if self.sections.contains_key(&page.parent_path) { - self.sections.get_mut(&page.parent_path).unwrap().pages.push(page.clone()); + if self.sections.contains_key(&page.parent_path.join("_index.md")) { + self.sections.get_mut(&page.parent_path.join("_index.md")).unwrap().pages.push(page.clone()); } } @@ -253,14 +264,14 @@ impl Site { } } - for (parent_path, section) in &mut self.sections { + for section in self.sections.values_mut() { // TODO: avoid this clone let (mut sorted_pages, cannot_be_sorted_pages) = sort_pages(section.pages.clone(), section.meta.sort_by()); sorted_pages = populate_previous_and_next_pages(&sorted_pages); section.pages = sorted_pages; section.ignored_pages = cannot_be_sorted_pages; - match grandparent_paths.get(parent_path) { + match grandparent_paths.get(§ion.parent_path) { Some(paths) => section.subsections.extend(paths.clone()), None => continue, }; @@ -353,7 +364,8 @@ impl Site { if path.exists() { // file exists, either a new one or updating content if is_section { - self.add_section(path)?; + self.add_section_and_render(path)?; + self.render_sections()?; } else { // probably just an update so just re-parse that page let (frontmatter_changed, page) = self.add_page_and_render(path)?; @@ -661,7 +673,6 @@ impl Site { }; let paginator = Paginator::new(§ion.pages, section); - for (i, pager) in paginator.pagers.iter().enumerate() { let folder_path = output_path.join(&paginate_path); let page_path = folder_path.join(&format!("{}", i + 1)); diff --git a/test_site/content/paginated/_index.md b/test_site/content/paginated/_index.md new file mode 100644 index 00000000..439852e5 --- /dev/null +++ b/test_site/content/paginated/_index.md @@ -0,0 +1,4 @@ ++++ +paginate_by = 10 +template = "section_paginated.html" ++++ diff --git a/test_site/content/posts/_index.md b/test_site/content/posts/_index.md index 93ed2520..1a93762c 100644 --- a/test_site/content/posts/_index.md +++ b/test_site/content/posts/_index.md @@ -1,4 +1,5 @@ +++ title = "Posts" -description = "" +paginate_by = 2 +template = "section_paginated.html" +++ diff --git a/tests/site.rs b/tests/site.rs index def308a2..2c463863 100644 --- a/tests/site.rs +++ b/tests/site.rs @@ -35,26 +35,26 @@ fn test_can_parse_site() { assert_eq!(asset_folder_post.components, vec!["posts".to_string()]); // That we have the right number of sections - assert_eq!(site.sections.len(), 5); + assert_eq!(site.sections.len(), 6); // And that the sections are correct - let index_section = &site.sections[&path.join("content")]; - assert_eq!(index_section.subsections.len(), 1); + let index_section = &site.sections[&path.join("content").join("_index.md")]; + assert_eq!(index_section.subsections.len(), 2); assert_eq!(index_section.pages.len(), 1); - let posts_section = &site.sections[&posts_path]; + let posts_section = &site.sections[&posts_path.join("_index.md")]; assert_eq!(posts_section.subsections.len(), 1); assert_eq!(posts_section.pages.len(), 5); - let tutorials_section = &site.sections[&posts_path.join("tutorials")]; + let tutorials_section = &site.sections[&posts_path.join("tutorials").join("_index.md")]; assert_eq!(tutorials_section.subsections.len(), 2); assert_eq!(tutorials_section.pages.len(), 0); - let devops_section = &site.sections[&posts_path.join("tutorials").join("devops")]; + let devops_section = &site.sections[&posts_path.join("tutorials").join("devops").join("_index.md")]; assert_eq!(devops_section.subsections.len(), 0); assert_eq!(devops_section.pages.len(), 2); - let prog_section = &site.sections[&posts_path.join("tutorials").join("programming")]; + let prog_section = &site.sections[&posts_path.join("tutorials").join("programming").join("_index.md")]; assert_eq!(prog_section.subsections.len(), 0); assert_eq!(prog_section.pages.len(), 2); } @@ -294,6 +294,9 @@ fn test_can_build_site_with_pagination_for_section() { let mut site = Site::new(&path, "config.toml").unwrap(); site.load().unwrap(); for section in site.sections.values_mut(){ + if section.is_index() { + continue; + } section.meta.paginate_by = Some(2); section.meta.template = Some("section_paginated.html".to_string()); } @@ -316,6 +319,9 @@ fn test_can_build_site_with_pagination_for_section() { assert!(file_exists!(public, "posts/index.html")); // And pagination! assert!(file_exists!(public, "posts/page/1/index.html")); + // even if there is no pages, only the section! + assert!(file_exists!(public, "paginated/page/1/index.html")); + assert!(file_exists!(public, "paginated/index.html")); // should redirect to posts/ assert!(file_contains!( public, @@ -347,7 +353,7 @@ fn test_can_build_site_with_pagination_for_index() { let mut site = Site::new(&path, "config.toml").unwrap(); site.load().unwrap(); { - let mut index = site.sections.get_mut(&path.join("content")).unwrap(); + let mut index = site.sections.get_mut(&path.join("content").join("_index.md")).unwrap(); index.meta.paginate_by = Some(2); index.meta.template = Some("index_paginated.html".to_string()); } @@ -368,6 +374,9 @@ fn test_can_build_site_with_pagination_for_index() { // And pagination! assert!(file_exists!(public, "page/1/index.html")); + // even if there is no pages, only the section! + assert!(file_exists!(public, "paginated/page/1/index.html")); + assert!(file_exists!(public, "paginated/index.html")); // should redirect to index assert!(file_contains!( public,