Roughly working page rendering

This commit is contained in:
Vincent Prouillet 2016-12-13 19:14:49 +09:00
parent c09cfe2de4
commit efa58e7de8
3 changed files with 77 additions and 17 deletions

View file

@ -50,7 +50,11 @@ pub fn build(config: Config) -> Result<()> {
} }
current_path.push(&page.filename); if page.slug != "" {
current_path.push(&page.slug);
} else {
current_path.push(&page.url);
}
create_dir(&current_path)?; create_dir(&current_path)?;
create_file(current_path.join("index.html"), &page.render_html(&tera, &config)?)?; create_file(current_path.join("index.html"), &page.render_html(&tera, &config)?)?;
pages.push(page); pages.push(page);
@ -60,6 +64,12 @@ pub fn build(config: Config) -> Result<()> {
render_section_index(section, pages, &tera, &config)?; render_section_index(section, pages, &tera, &config)?;
} }
// and now the index page
let mut context = Context::new();
context.add("pages", &order_pages(pages));
context.add("config", &config);
create_file(public.join("index.html"), &tera.render("index.html", context)?)?;
Ok(()) Ok(())
} }

View file

@ -44,7 +44,7 @@ pub fn parse_front_matter(front_matter: &str, page: &mut Page) -> Result<()> {
} else if key == "slug" { } else if key == "slug" {
page.slug = s.to_string(); page.slug = s.to_string();
} else if key == "url" { } else if key == "url" {
page.url = Some(s.to_string()); page.url = s.to_string();
} else if key == "category" { } else if key == "category" {
page.category = Some(s.to_string()); page.category = Some(s.to_string());
} else if key == "layout" { } else if key == "layout" {
@ -86,8 +86,8 @@ pub fn parse_front_matter(front_matter: &str, page: &mut Page) -> Result<()> {
bail!("Errors parsing front matter: {:?}", parser.errors); bail!("Errors parsing front matter: {:?}", parser.errors);
} }
if page.title == "" || page.slug == "" { if page.title == "" || (page.slug == "" && page.url == "") {
bail!("Front matter is missing required fields (title, slug or both)"); bail!("Front matter is missing required fields (title, slug/url or both)");
} }
Ok(()) Ok(())
@ -149,7 +149,19 @@ authors = ["Bob", "Alice"]"#;
} }
#[test] #[test]
fn test_ignores_pages_with_empty_front_matter() { fn test_is_ok_with_url_instead_of_slug() {
let content = r#"
title = "Hello"
url = "hello-world""#;
let mut page = Page::default();
let res = parse_front_matter(content, &mut page);
assert!(res.is_ok());
assert_eq!(page.slug, "".to_string());
assert_eq!(page.url, "hello-world".to_string());
}
#[test]
fn test_errors_with_empty_front_matter() {
let content = r#" "#; let content = r#" "#;
let mut page = Page::default(); let mut page = Page::default();
let res = parse_front_matter(content, &mut page); let res = parse_front_matter(content, &mut page);

View file

@ -41,6 +41,9 @@ pub struct Page {
pub title: String, pub title: String,
// The page slug // The page slug
pub slug: String, pub slug: String,
// the url the page appears at, overrides the slug if set in the frontmatter
// otherwise is set after parsing front matter and sections
pub url: String,
// the HTML rendered of the page // the HTML rendered of the page
pub content: String, pub content: String,
@ -52,8 +55,6 @@ pub struct Page {
// it will be passed to the template context // it will be passed to the template context
pub extra: HashMap<String, Value>, pub extra: HashMap<String, Value>,
// the url the page appears at, overrides the slug if set
pub url: Option<String>,
// only one category allowed // only one category allowed
pub category: Option<String>, pub category: Option<String>,
// optional date if we want to order pages (ie blog post) // optional date if we want to order pages (ie blog post)
@ -75,13 +76,13 @@ impl Default for Page {
title: "".to_string(), title: "".to_string(),
slug: "".to_string(), slug: "".to_string(),
url: "".to_string(),
raw_content: "".to_string(), raw_content: "".to_string(),
content: "".to_string(), content: "".to_string(),
tags: vec![], tags: vec![],
is_draft: false, is_draft: false,
extra: HashMap::new(), extra: HashMap::new(),
url: None,
category: None, category: None,
date: None, date: None,
layout: None, layout: None,
@ -109,14 +110,6 @@ impl Page {
// 2. create our page, parse front matter and assign all of that // 2. create our page, parse front matter and assign all of that
let mut page = Page::default(); let mut page = Page::default();
page.filepath = filepath.to_string(); page.filepath = filepath.to_string();
let path = Path::new(filepath);
page.filename = path.file_stem().expect("Couldn't get file stem").to_string_lossy().to_string();
// find out if we have sections
for section in path.parent().unwrap().components() {
page.sections.push(section.as_ref().to_string_lossy().to_string());
}
page.raw_content = content.to_string(); page.raw_content = content.to_string();
parse_front_matter(front_matter, &mut page) parse_front_matter(front_matter, &mut page)
.chain_err(|| format!("Error when parsing front matter of file `{}`", filepath))?; .chain_err(|| format!("Error when parsing front matter of file `{}`", filepath))?;
@ -128,6 +121,26 @@ impl Page {
html html
}; };
// next find sections
// Pages with custom urls exists outside of sections
if page.url == "" {
let path = Path::new(filepath);
page.filename = path.file_stem().expect("Couldn't get file stem").to_string_lossy().to_string();
// find out if we have sections
for section in path.parent().unwrap().components() {
page.sections.push(section.as_ref().to_string_lossy().to_string());
}
// now the url
// it's either set in the front matter OR we get it from a combination of sections + slug
if page.sections.len() > 0 {
page.url = format!("/{}/{}", page.sections.join("/"), page.slug);
} else {
page.url = format!("/{}", page.slug);
};
}
Ok(page) Ok(page)
} }
@ -205,7 +218,7 @@ Hello world"#;
} }
#[test] #[test]
fn test_can_find_multiplie_parent_directories() { fn test_can_find_multiple_parent_directories() {
let content = r#" let content = r#"
title = "Hello" title = "Hello"
slug = "hello-world" slug = "hello-world"
@ -217,4 +230,29 @@ Hello world"#;
assert_eq!(page.sections, vec!["posts".to_string(), "intro".to_string()]); assert_eq!(page.sections, vec!["posts".to_string(), "intro".to_string()]);
} }
#[test]
fn test_can_make_url_from_sections_and_slug() {
let content = r#"
title = "Hello"
slug = "hello-world"
+++
Hello world"#;
let res = Page::from_str("posts/intro/start.md", content);
assert!(res.is_ok());
let page = res.unwrap();
assert_eq!(page.url, "/posts/intro/hello-world");
}
#[test]
fn test_can_make_url_from_sections_and_slug_root() {
let content = r#"
title = "Hello"
slug = "hello-world"
+++
Hello world"#;
let res = Page::from_str("start.md", content);
assert!(res.is_ok());
let page = res.unwrap();
assert_eq!(page.url, "/hello-world");
}
} }