@@ -243,7 +243,7 @@ impl ser::Serialize for Page { | |||||
/// | /// | ||||
/// Any pages that doesn't have a date when the sorting method is date or order | /// Any pages that doesn't have a date when the sorting method is date or order | ||||
/// when the sorting method is order will be ignored. | /// when the sorting method is order will be ignored. | ||||
pub fn sort_pages(pages: Vec<Page>, section: Option<&Section>) -> Vec<Page> { | |||||
pub fn sort_pages(pages: Vec<Page>, section: Option<&Section>) -> (Vec<Page>, Vec<Page>) { | |||||
let sort_by = if let Some(ref sec) = section { | let sort_by = if let Some(ref sec) = section { | ||||
sec.meta.sort_by() | sec.meta.sort_by() | ||||
} else { | } else { | ||||
@@ -262,9 +262,8 @@ pub fn sort_pages(pages: Vec<Page>, section: Option<&Section>) -> Vec<Page> { | |||||
} | } | ||||
} | } | ||||
can_be_sorted.sort_by(|a, b| b.meta.date().unwrap().cmp(&a.meta.date().unwrap())); | can_be_sorted.sort_by(|a, b| b.meta.date().unwrap().cmp(&a.meta.date().unwrap())); | ||||
// can_be_sorted.append(&mut cannot_be_sorted); | |||||
can_be_sorted | |||||
(can_be_sorted, cannot_be_sorted) | |||||
}, | }, | ||||
SortBy::Order => { | SortBy::Order => { | ||||
let mut can_be_sorted = vec![]; | let mut can_be_sorted = vec![]; | ||||
@@ -277,9 +276,8 @@ pub fn sort_pages(pages: Vec<Page>, section: Option<&Section>) -> Vec<Page> { | |||||
} | } | ||||
} | } | ||||
can_be_sorted.sort_by(|a, b| b.meta.order().cmp(&a.meta.order())); | can_be_sorted.sort_by(|a, b| b.meta.order().cmp(&a.meta.order())); | ||||
// can_be_sorted.append(&mut cannot_be_sorted); | |||||
can_be_sorted | |||||
(can_be_sorted, cannot_be_sorted) | |||||
}, | }, | ||||
SortBy::None => { | SortBy::None => { | ||||
let mut p = vec![]; | let mut p = vec![]; | ||||
@@ -287,7 +285,7 @@ pub fn sort_pages(pages: Vec<Page>, section: Option<&Section>) -> Vec<Page> { | |||||
p.push(page); | p.push(page); | ||||
} | } | ||||
p | |||||
(p, vec![]) | |||||
}, | }, | ||||
} | } | ||||
} | } | ||||
@@ -390,7 +388,7 @@ mod tests { | |||||
create_page_with_date("2017-01-01"), | create_page_with_date("2017-01-01"), | ||||
create_page_with_date("2019-01-01"), | create_page_with_date("2019-01-01"), | ||||
]; | ]; | ||||
let pages = sort_pages(input, None); | |||||
let (pages, _) = sort_pages(input, None); | |||||
// Should be sorted by date | // Should be sorted by date | ||||
assert_eq!(pages[0].clone().meta.date.unwrap(), "2019-01-01"); | assert_eq!(pages[0].clone().meta.date.unwrap(), "2019-01-01"); | ||||
assert_eq!(pages[1].clone().meta.date.unwrap(), "2018-01-01"); | assert_eq!(pages[1].clone().meta.date.unwrap(), "2018-01-01"); | ||||
@@ -407,7 +405,7 @@ mod tests { | |||||
let mut front_matter = FrontMatter::default(); | let mut front_matter = FrontMatter::default(); | ||||
front_matter.sort_by = Some(SortBy::Date); | front_matter.sort_by = Some(SortBy::Date); | ||||
let section = Section::new(Path::new("hey"), front_matter); | let section = Section::new(Path::new("hey"), front_matter); | ||||
let pages = sort_pages(input, Some(§ion)); | |||||
let (pages, _) = sort_pages(input, Some(§ion)); | |||||
// Should be sorted by date | // Should be sorted by date | ||||
assert_eq!(pages[0].clone().meta.date.unwrap(), "2019-01-01"); | assert_eq!(pages[0].clone().meta.date.unwrap(), "2019-01-01"); | ||||
assert_eq!(pages[1].clone().meta.date.unwrap(), "2018-01-01"); | assert_eq!(pages[1].clone().meta.date.unwrap(), "2018-01-01"); | ||||
@@ -424,7 +422,7 @@ mod tests { | |||||
let mut front_matter = FrontMatter::default(); | let mut front_matter = FrontMatter::default(); | ||||
front_matter.sort_by = Some(SortBy::Order); | front_matter.sort_by = Some(SortBy::Order); | ||||
let section = Section::new(Path::new("hey"), front_matter); | let section = Section::new(Path::new("hey"), front_matter); | ||||
let pages = sort_pages(input, Some(§ion)); | |||||
let (pages, _) = sort_pages(input, Some(§ion)); | |||||
// Should be sorted by date | // Should be sorted by date | ||||
assert_eq!(pages[0].clone().meta.order.unwrap(), 3); | assert_eq!(pages[0].clone().meta.order.unwrap(), 3); | ||||
assert_eq!(pages[1].clone().meta.order.unwrap(), 2); | assert_eq!(pages[1].clone().meta.order.unwrap(), 2); | ||||
@@ -441,7 +439,7 @@ mod tests { | |||||
let mut front_matter = FrontMatter::default(); | let mut front_matter = FrontMatter::default(); | ||||
front_matter.sort_by = Some(SortBy::None); | front_matter.sort_by = Some(SortBy::None); | ||||
let section = Section::new(Path::new("hey"), front_matter); | let section = Section::new(Path::new("hey"), front_matter); | ||||
let pages = sort_pages(input, Some(§ion)); | |||||
let (pages, _) = sort_pages(input, Some(§ion)); | |||||
// Should be sorted by date | // Should be sorted by date | ||||
assert_eq!(pages[0].clone().meta.order.unwrap(), 2); | assert_eq!(pages[0].clone().meta.order.unwrap(), 2); | ||||
assert_eq!(pages[1].clone().meta.order.unwrap(), 3); | assert_eq!(pages[1].clone().meta.order.unwrap(), 3); | ||||
@@ -458,8 +456,9 @@ mod tests { | |||||
let mut front_matter = FrontMatter::default(); | let mut front_matter = FrontMatter::default(); | ||||
front_matter.sort_by = Some(SortBy::Order); | front_matter.sort_by = Some(SortBy::Order); | ||||
let section = Section::new(Path::new("hey"), front_matter); | let section = Section::new(Path::new("hey"), front_matter); | ||||
let pages = sort_pages(input, Some(§ion)); | |||||
let (pages, unsorted) = sort_pages(input, Some(§ion)); | |||||
assert_eq!(pages.len(), 2); | assert_eq!(pages.len(), 2); | ||||
assert_eq!(unsorted.len(), 1); | |||||
} | } | ||||
#[test] | #[test] | ||||
@@ -201,7 +201,7 @@ impl Site { | |||||
for (parent_path, section) in &mut self.sections { | for (parent_path, section) in &mut self.sections { | ||||
// TODO: avoid this clone | // TODO: avoid this clone | ||||
let sorted_pages = sort_pages(section.pages.clone(), Some(§ion)); | |||||
let (sorted_pages, _) = sort_pages(section.pages.clone(), Some(§ion)); | |||||
section.pages = populate_previous_and_next_pages(sorted_pages.as_slice()); | section.pages = populate_previous_and_next_pages(sorted_pages.as_slice()); | ||||
match grandparent_paths.get(parent_path) { | match grandparent_paths.get(parent_path) { | ||||
@@ -333,41 +333,55 @@ impl Site { | |||||
} | } | ||||
} | } | ||||
pub fn build_pages(&self) -> Result<()> { | |||||
pub fn render_page(&self, page: &Page) -> Result<()> { | |||||
let public = self.output_path.clone(); | let public = self.output_path.clone(); | ||||
if !public.exists() { | if !public.exists() { | ||||
create_directory(&public)?; | create_directory(&public)?; | ||||
} | } | ||||
let mut pages = vec![]; | |||||
// First we render the pages themselves | |||||
for page in self.pages.values() { | |||||
// Copy the nesting of the content directory if we have sections for that page | |||||
let mut current_path = public.to_path_buf(); | |||||
// Copy the nesting of the content directory if we have sections for that page | |||||
let mut current_path = public.to_path_buf(); | |||||
for component in page.path.split('/') { | |||||
current_path.push(component); | |||||
for component in page.path.split('/') { | |||||
current_path.push(component); | |||||
if !current_path.exists() { | |||||
create_directory(¤t_path)?; | |||||
} | |||||
if !current_path.exists() { | |||||
create_directory(¤t_path)?; | |||||
} | } | ||||
} | |||||
// Make sure the folder exists | |||||
create_directory(¤t_path)?; | |||||
// Make sure the folder exists | |||||
create_directory(¤t_path)?; | |||||
// Finally, create a index.html file there with the page rendered | |||||
let output = page.render_html(&self.tera, &self.config)?; | |||||
create_file(current_path.join("index.html"), &self.inject_livereload(output))?; | |||||
// Finally, create a index.html file there with the page rendered | |||||
let output = page.render_html(&self.tera, &self.config)?; | |||||
create_file(current_path.join("index.html"), &self.inject_livereload(output))?; | |||||
// Copy any asset we found previously into the same directory as the index.html | |||||
for asset in &page.assets { | |||||
let asset_path = asset.as_path(); | |||||
copy(&asset_path, ¤t_path.join(asset_path.file_name().unwrap()))?; | |||||
} | |||||
// Copy any asset we found previously into the same directory as the index.html | |||||
for asset in &page.assets { | |||||
let asset_path = asset.as_path(); | |||||
copy(&asset_path, ¤t_path.join(asset_path.file_name().unwrap()))?; | |||||
} | |||||
Ok(()) | |||||
} | |||||
pages.push(page.clone()); | |||||
pub fn build_pages(&self) -> Result<()> { | |||||
let public = self.output_path.clone(); | |||||
if !public.exists() { | |||||
create_directory(&public)?; | |||||
} | |||||
// Sort the pages first | |||||
// TODO: avoid the clone() | |||||
let (mut sorted_pages, cannot_sort_pages) = sort_pages(self.pages.values().map(|p| p.clone()).collect(), self.index.as_ref()); | |||||
sorted_pages = populate_previous_and_next_pages(&sorted_pages); | |||||
for page in &sorted_pages { | |||||
self.render_page(page)?; | |||||
} | |||||
for page in &cannot_sort_pages { | |||||
self.render_page(page)?; | |||||
} | } | ||||
// Outputting categories and pages | // Outputting categories and pages | ||||
@@ -378,13 +392,10 @@ impl Site { | |||||
self.render_categories_and_tags(RenderList::Tags)?; | self.render_categories_and_tags(RenderList::Tags)?; | ||||
} | } | ||||
// Sort the pages | |||||
let sorted_pages = sort_pages(pages, self.index.as_ref()); | |||||
// And finally the index page | // And finally the index page | ||||
let mut context = Context::new(); | let mut context = Context::new(); | ||||
context.add("pages", &populate_previous_and_next_pages(sorted_pages.as_slice())); | |||||
context.add("pages", &sorted_pages); | |||||
context.add("sections", &self.sections.values().collect::<Vec<&Section>>()); | context.add("sections", &self.sections.values().collect::<Vec<&Section>>()); | ||||
context.add("config", &self.config); | context.add("config", &self.config); | ||||
context.add("current_url", &self.config.base_url); | context.add("current_url", &self.config.base_url); | ||||
@@ -2,4 +2,7 @@ | |||||
{% block content %} | {% block content %} | ||||
{{ page.content | safe }} | {{ page.content | safe }} | ||||
{% if page.previous %}Previous article: {{ page.previous.permalink }}{% endif %} | |||||
{% if page.next %}Next article: {{ page.next.permalink }}{% endif %} | |||||
{% endblock content %} | {% endblock content %} |
@@ -126,6 +126,9 @@ fn test_can_build_site_without_live_reload() { | |||||
// Both pages and sections are in the sitemap | // Both pages and sections are in the sitemap | ||||
assert!(file_contains!(public, "sitemap.xml", "<loc>https://replace-this-with-your-url.com/posts/simple</loc>")); | assert!(file_contains!(public, "sitemap.xml", "<loc>https://replace-this-with-your-url.com/posts/simple</loc>")); | ||||
assert!(file_contains!(public, "sitemap.xml", "<loc>https://replace-this-with-your-url.com/posts</loc>")); | assert!(file_contains!(public, "sitemap.xml", "<loc>https://replace-this-with-your-url.com/posts</loc>")); | ||||
assert!(file_contains!(public, "a-fixed-url/index.html", "Previous article: ")); | |||||
assert!(file_contains!(public, "a-fixed-url/index.html", "Next article: ")); | |||||
} | } | ||||
#[test] | #[test] | ||||