Change Site::section and fix empty paginated sections
This commit is contained in:
parent
c565f10cb3
commit
8711c9a3c0
|
@ -149,7 +149,7 @@ impl Default for FrontMatter {
|
||||||
order: None,
|
order: None,
|
||||||
template: None,
|
template: None,
|
||||||
paginate_by: None,
|
paginate_by: None,
|
||||||
paginate_path: None,
|
paginate_path: Some("page".to_string()),
|
||||||
render: Some(true),
|
render: Some(true),
|
||||||
extra: None,
|
extra: None,
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,10 +23,10 @@ pub struct Pager<'a> {
|
||||||
impl<'a> Pager<'a> {
|
impl<'a> Pager<'a> {
|
||||||
fn new(index: usize, pages: Vec<&'a Page>, permalink: String, path: String) -> Pager<'a> {
|
fn new(index: usize, pages: Vec<&'a Page>, permalink: String, path: String) -> Pager<'a> {
|
||||||
Pager {
|
Pager {
|
||||||
index: index,
|
index,
|
||||||
permalink: permalink,
|
permalink,
|
||||||
path: path,
|
path,
|
||||||
pages: pages,
|
pages,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -44,6 +44,8 @@ pub struct Paginator<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> 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> {
|
pub fn new(all_pages: &'a [Page], section: &'a Section) -> Paginator<'a> {
|
||||||
let paginate_by = section.meta.paginate_by.unwrap();
|
let paginate_by = section.meta.paginate_by.unwrap();
|
||||||
let paginate_path = match section.meta.paginate_path {
|
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 {
|
Paginator {
|
||||||
all_pages: all_pages,
|
all_pages: all_pages,
|
||||||
pagers: pagers,
|
pagers: pagers,
|
||||||
|
|
|
@ -149,7 +149,7 @@ impl ser::Serialize for Section {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default 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 {
|
fn default() -> Section {
|
||||||
Section {
|
Section {
|
||||||
file_path: PathBuf::new(),
|
file_path: PathBuf::new(),
|
||||||
|
|
31
src/site.rs
31
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
|
// Insert a default index section so we don't need to create a _index.md to render
|
||||||
// the index page
|
// 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) {
|
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
|
// 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
|
/// Simple wrapper fn to avoid repeating that code in several places
|
||||||
fn add_section(&mut self, path: &Path) -> Result<()> {
|
fn add_section(&mut self, path: &Path) -> Result<()> {
|
||||||
let section = Section::from_file(path, &self.config)?;
|
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(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -239,10 +250,10 @@ impl Site {
|
||||||
|
|
||||||
/// Find out the direct subsections of each subsection if there are some
|
/// Find out the direct subsections of each subsection if there are some
|
||||||
/// as well as the pages for each section
|
/// 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() {
|
for page in self.pages.values() {
|
||||||
if self.sections.contains_key(&page.parent_path) {
|
if self.sections.contains_key(&page.parent_path.join("_index.md")) {
|
||||||
self.sections.get_mut(&page.parent_path).unwrap().pages.push(page.clone());
|
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
|
// TODO: avoid this clone
|
||||||
let (mut sorted_pages, cannot_be_sorted_pages) = sort_pages(section.pages.clone(), section.meta.sort_by());
|
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);
|
sorted_pages = populate_previous_and_next_pages(&sorted_pages);
|
||||||
section.pages = sorted_pages;
|
section.pages = sorted_pages;
|
||||||
section.ignored_pages = cannot_be_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()),
|
Some(paths) => section.subsections.extend(paths.clone()),
|
||||||
None => continue,
|
None => continue,
|
||||||
};
|
};
|
||||||
|
@ -353,7 +364,8 @@ impl Site {
|
||||||
if path.exists() {
|
if path.exists() {
|
||||||
// file exists, either a new one or updating content
|
// file exists, either a new one or updating content
|
||||||
if is_section {
|
if is_section {
|
||||||
self.add_section(path)?;
|
self.add_section_and_render(path)?;
|
||||||
|
self.render_sections()?;
|
||||||
} else {
|
} else {
|
||||||
// probably just an update so just re-parse that page
|
// probably just an update so just re-parse that page
|
||||||
let (frontmatter_changed, page) = self.add_page_and_render(path)?;
|
let (frontmatter_changed, page) = self.add_page_and_render(path)?;
|
||||||
|
@ -661,7 +673,6 @@ impl Site {
|
||||||
};
|
};
|
||||||
|
|
||||||
let paginator = Paginator::new(§ion.pages, section);
|
let paginator = Paginator::new(§ion.pages, section);
|
||||||
|
|
||||||
for (i, pager) in paginator.pagers.iter().enumerate() {
|
for (i, pager) in paginator.pagers.iter().enumerate() {
|
||||||
let folder_path = output_path.join(&paginate_path);
|
let folder_path = output_path.join(&paginate_path);
|
||||||
let page_path = folder_path.join(&format!("{}", i + 1));
|
let page_path = folder_path.join(&format!("{}", i + 1));
|
||||||
|
|
4
test_site/content/paginated/_index.md
Normal file
4
test_site/content/paginated/_index.md
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
+++
|
||||||
|
paginate_by = 10
|
||||||
|
template = "section_paginated.html"
|
||||||
|
+++
|
|
@ -1,4 +1,5 @@
|
||||||
+++
|
+++
|
||||||
title = "Posts"
|
title = "Posts"
|
||||||
description = ""
|
paginate_by = 2
|
||||||
|
template = "section_paginated.html"
|
||||||
+++
|
+++
|
||||||
|
|
|
@ -35,26 +35,26 @@ fn test_can_parse_site() {
|
||||||
assert_eq!(asset_folder_post.components, vec!["posts".to_string()]);
|
assert_eq!(asset_folder_post.components, vec!["posts".to_string()]);
|
||||||
|
|
||||||
// That we have the right number of sections
|
// 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
|
// And that the sections are correct
|
||||||
let index_section = &site.sections[&path.join("content")];
|
let index_section = &site.sections[&path.join("content").join("_index.md")];
|
||||||
assert_eq!(index_section.subsections.len(), 1);
|
assert_eq!(index_section.subsections.len(), 2);
|
||||||
assert_eq!(index_section.pages.len(), 1);
|
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.subsections.len(), 1);
|
||||||
assert_eq!(posts_section.pages.len(), 5);
|
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.subsections.len(), 2);
|
||||||
assert_eq!(tutorials_section.pages.len(), 0);
|
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.subsections.len(), 0);
|
||||||
assert_eq!(devops_section.pages.len(), 2);
|
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.subsections.len(), 0);
|
||||||
assert_eq!(prog_section.pages.len(), 2);
|
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();
|
let mut site = Site::new(&path, "config.toml").unwrap();
|
||||||
site.load().unwrap();
|
site.load().unwrap();
|
||||||
for section in site.sections.values_mut(){
|
for section in site.sections.values_mut(){
|
||||||
|
if section.is_index() {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
section.meta.paginate_by = Some(2);
|
section.meta.paginate_by = Some(2);
|
||||||
section.meta.template = Some("section_paginated.html".to_string());
|
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"));
|
assert!(file_exists!(public, "posts/index.html"));
|
||||||
// And pagination!
|
// And pagination!
|
||||||
assert!(file_exists!(public, "posts/page/1/index.html"));
|
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/
|
// should redirect to posts/
|
||||||
assert!(file_contains!(
|
assert!(file_contains!(
|
||||||
public,
|
public,
|
||||||
|
@ -347,7 +353,7 @@ fn test_can_build_site_with_pagination_for_index() {
|
||||||
let mut site = Site::new(&path, "config.toml").unwrap();
|
let mut site = Site::new(&path, "config.toml").unwrap();
|
||||||
site.load().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.paginate_by = Some(2);
|
||||||
index.meta.template = Some("index_paginated.html".to_string());
|
index.meta.template = Some("index_paginated.html".to_string());
|
||||||
}
|
}
|
||||||
|
@ -368,6 +374,9 @@ fn test_can_build_site_with_pagination_for_index() {
|
||||||
|
|
||||||
// And pagination!
|
// And pagination!
|
||||||
assert!(file_exists!(public, "page/1/index.html"));
|
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
|
// should redirect to index
|
||||||
assert!(file_contains!(
|
assert!(file_contains!(
|
||||||
public,
|
public,
|
||||||
|
|
Loading…
Reference in a new issue