Let sections have their own body

This commit is contained in:
Vincent Prouillet 2017-05-12 18:05:00 +09:00
parent 005990a928
commit c565f10cb3
2 changed files with 30 additions and 4 deletions

View file

@ -9,6 +9,7 @@ use config::Config;
use front_matter::{FrontMatter, split_content}; use front_matter::{FrontMatter, split_content};
use errors::{Result, ResultExt}; use errors::{Result, ResultExt};
use utils::{read_file, find_content_components}; use utils::{read_file, find_content_components};
use markdown::markdown_to_html;
use page::{Page}; use page::{Page};
@ -26,6 +27,10 @@ pub struct Section {
pub path: String, pub path: String,
/// The full URL for that page /// The full URL for that page
pub permalink: String, pub permalink: String,
/// The actual content of the page, in markdown
pub raw_content: String,
/// The HTML rendered of the page
pub content: String,
/// The front matter meta-data /// The front matter meta-data
pub meta: FrontMatter, pub meta: FrontMatter,
/// All direct pages of that section /// All direct pages of that section
@ -47,6 +52,8 @@ impl Section {
components: vec![], components: vec![],
path: "".to_string(), path: "".to_string(),
permalink: "".to_string(), permalink: "".to_string(),
raw_content: "".to_string(),
content: "".to_string(),
meta: meta, meta: meta,
pages: vec![], pages: vec![],
ignored_pages: vec![], ignored_pages: vec![],
@ -55,8 +62,9 @@ impl Section {
} }
pub fn parse(file_path: &Path, content: &str, config: &Config) -> Result<Section> { pub fn parse(file_path: &Path, content: &str, config: &Config) -> Result<Section> {
let (meta, _) = split_content(file_path, content)?; let (meta, content) = split_content(file_path, content)?;
let mut section = Section::new(file_path, meta); let mut section = Section::new(file_path, meta);
section.raw_content = content.clone();
section.components = find_content_components(&section.file_path); section.components = find_content_components(&section.file_path);
section.path = section.components.join("/"); section.path = section.components.join("/");
section.permalink = config.make_permalink(&section.path); section.permalink = config.make_permalink(&section.path);
@ -89,6 +97,13 @@ impl Section {
} }
} }
/// We need access to all pages url to render links relative to content
/// so that can't happen at the same time as parsing
pub fn render_markdown(&mut self, permalinks: &HashMap<String, String>, tera: &Tera, config: &Config) -> Result<()> {
self.content = markdown_to_html(&self.raw_content, permalinks, tera, config)?;
Ok(())
}
/// Renders the page using the default layout, unless specified in front-matter /// Renders the page using the default layout, unless specified in front-matter
pub fn render_html(&self, sections: &HashMap<String, Section>, tera: &Tera, config: &Config) -> Result<String> { pub fn render_html(&self, sections: &HashMap<String, Section>, tera: &Tera, config: &Config) -> Result<String> {
let tpl_name = self.get_template_name(); let tpl_name = self.get_template_name();
@ -121,7 +136,8 @@ impl Section {
impl ser::Serialize for Section { impl ser::Serialize for Section {
fn serialize<S>(&self, serializer: S) -> StdResult<S::Ok, S::Error> where S: ser::Serializer { fn serialize<S>(&self, serializer: S) -> StdResult<S::Ok, S::Error> where S: ser::Serializer {
let mut state = serializer.serialize_struct("section", 6)?; let mut state = serializer.serialize_struct("section", 7)?;
state.serialize_field("content", &self.content)?;
state.serialize_field("title", &self.meta.title)?; state.serialize_field("title", &self.meta.title)?;
state.serialize_field("description", &self.meta.description)?; state.serialize_field("description", &self.meta.description)?;
state.serialize_field("path", &format!("/{}", self.path))?; state.serialize_field("path", &format!("/{}", self.path))?;
@ -142,6 +158,8 @@ impl Default for Section {
components: vec![], components: vec![],
path: "".to_string(), path: "".to_string(),
permalink: "".to_string(), permalink: "".to_string(),
raw_content: "".to_string(),
content: "".to_string(),
meta: FrontMatter::default(), meta: FrontMatter::default(),
pages: vec![], pages: vec![],
ignored_pages: vec![], ignored_pages: vec![],

View file

@ -194,6 +194,10 @@ impl Site {
page.render_markdown(&permalinks, &self.tera, &self.config)?; page.render_markdown(&permalinks, &self.tera, &self.config)?;
} }
for section in self.sections.values_mut() {
section.render_markdown(&permalinks, &self.tera, &self.config)?;
}
self.permalinks = permalinks; self.permalinks = permalinks;
self.populate_sections(); self.populate_sections();
self.populate_tags_and_categories(); self.populate_tags_and_categories();
@ -219,14 +223,18 @@ impl Site {
/// Called in serve, add a page again updating permalinks and its content /// Called in serve, add a page again updating permalinks and its content
/// The bool in the result is whether the front matter has been updated or not /// The bool in the result is whether the front matter has been updated or not
/// TODO: the above is very confusing, change that
fn add_page_and_render(&mut self, path: &Path) -> Result<(bool, Page)> { fn add_page_and_render(&mut self, path: &Path) -> Result<(bool, Page)> {
let existing_page = self.pages.get(path).expect("Page was supposed to exist in add_page_and_render").clone(); let existing_page = self.pages.get(path).cloned();
self.add_page(path)?; self.add_page(path)?;
let mut page = self.pages.get_mut(path).unwrap(); let mut page = self.pages.get_mut(path).unwrap();
self.permalinks.insert(page.relative_path.clone(), page.permalink.clone()); self.permalinks.insert(page.relative_path.clone(), page.permalink.clone());
page.render_markdown(&self.permalinks, &self.tera, &self.config)?; page.render_markdown(&self.permalinks, &self.tera, &self.config)?;
Ok((existing_page.meta != page.meta, page.clone())) if let Some(prev_page) = existing_page {
return Ok((prev_page.meta != page.meta, page.clone()));
}
Ok((true, page.clone()))
} }
/// Find out the direct subsections of each subsection if there are some /// Find out the direct subsections of each subsection if there are some