Browse Source

Roughly working page rendering

index-subcmd
Vincent Prouillet 8 years ago
parent
commit
efa58e7de8
3 changed files with 77 additions and 17 deletions
  1. +11
    -1
      src/cmd/build.rs
  2. +16
    -4
      src/front_matter.rs
  3. +50
    -12
      src/page.rs

+ 11
- 1
src/cmd/build.rs 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(())
} }


+ 16
- 4
src/front_matter.rs 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 == "" {
bail!("Front matter is missing required fields (title, slug or both)");
if page.title == "" || (page.slug == "" && page.url == "") {
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);


+ 50
- 12
src/page.rs 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");
}
} }

Loading…
Cancel
Save