From c09cfe2de44441562211d733491b8fa6aabd4ee5 Mon Sep 17 00:00:00 2001 From: Vincent Prouillet Date: Tue, 13 Dec 2016 18:05:59 +0900 Subject: [PATCH] Render section pages --- Cargo.lock | 8 ++++---- src/cmd/build.rs | 44 +++++++++++++++++++++++++++++++++++++------- src/page.rs | 17 ++++++++++++++--- 3 files changed, 55 insertions(+), 14 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 2825a1a..0240215 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -49,7 +49,7 @@ name = "backtrace-sys" version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "gcc 0.3.39 (registry+https://github.com/rust-lang/crates.io-index)", + "gcc 0.3.40 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -129,7 +129,7 @@ dependencies = [ [[package]] name = "gcc" -version = "0.3.39" +version = "0.3.40" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -330,7 +330,7 @@ dependencies = [ [[package]] name = "tera" version = "0.4.1" -source = "git+https://github.com/Keats/tera.git?branch=v0.5#6fc3c61fc58c010abc26f3272badea1b9bc13963" +source = "git+https://github.com/Keats/tera.git?branch=v0.5#f6047453e06ea507f4b0d9a4c9b1cb3f3f874aac" dependencies = [ "error-chain 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", "glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", @@ -472,7 +472,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum dbghelp-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "97590ba53bcb8ac28279161ca943a924d1fd4a8fb3fa63302591647c4fc5b850" "checksum dtoa 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "0dd841b58510c9618291ffa448da2e4e0f699d984d436122372f446dae62263d" "checksum error-chain 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1cd681735364a04cd5d69f01a4f6768e70473941f8d86d8c224faf6955a75799" -"checksum gcc 0.3.39 (registry+https://github.com/rust-lang/crates.io-index)" = "771e4a97ff6f237cf0f7d5f5102f6e28bb9743814b6198d684da5c58b76c11e0" +"checksum gcc 0.3.40 (registry+https://github.com/rust-lang/crates.io-index)" = "872db9e59486ef2b14f8e8c10e9ef02de2bccef6363d7f34835dedb386b3d950" "checksum getopts 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)" = "d9047cfbd08a437050b363d35ef160452c5fe8ea5187ae0a624708c91581d685" "checksum glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "8be18de09a56b60ed0edf84bc9df007e30040691af7acd1c41874faac5895bfb" "checksum humansize 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3ec9e8cc78ff5f1f18be53b9a0295dce25c668c10cd60c4d3e535b8882a88f77" diff --git a/src/cmd/build.rs b/src/cmd/build.rs index 1f93417..58621a8 100644 --- a/src/cmd/build.rs +++ b/src/cmd/build.rs @@ -1,12 +1,13 @@ +use std::collections::HashMap; use std::fs::{create_dir, remove_dir_all}; use std::path::Path; use glob::glob; -use tera::Tera; +use tera::{Tera, Context}; use config:: Config; use errors::{Result, ResultExt}; -use page::Page; +use page::{Page, order_pages}; use utils::create_file; @@ -18,33 +19,62 @@ pub fn build(config: Config) -> Result<()> { } let tera = Tera::new("layouts/**/*").chain_err(|| "Error parsing templates")?; - // let mut pages: Vec = vec![]; // ok we got all the pages HTML, time to write them down to disk create_dir("public")?; let public = Path::new("public"); + let mut pages: Vec = vec![]; + let mut sections: HashMap> = HashMap::new(); + // First step: do all the articles and group article by sections // hardcoded pattern so can't error for entry in glob("content/**/*.md").unwrap().filter_map(|e| e.ok()) { let path = entry.as_path(); let mut page = Page::from_file(&path)?; let mut current_path = public.clone().to_path_buf(); + for section in &page.sections { current_path.push(section); - //current_path = current_path.join(section).as_path(); + if !current_path.exists() { - println!("Creating {:?} folder", current_path); create_dir(¤t_path)?; - // TODO: create section index.html - // create_file(current_path.join("index.html"), ""); } + + let str_path = current_path.as_path().to_string_lossy().to_string(); + if sections.contains_key(&str_path) { + sections.get_mut(&str_path).unwrap().push(page.clone()); + } else { + sections.insert(str_path, vec![page.clone()]); + } + } + current_path.push(&page.filename); create_dir(¤t_path)?; create_file(current_path.join("index.html"), &page.render_html(&tera, &config)?)?; + pages.push(page); + } + + for (section, pages) in sections { + render_section_index(section, pages, &tera, &config)?; } Ok(()) } + + +fn render_section_index(section: String, pages: Vec, tera: &Tera, config: &Config) -> Result<()> { + let path = Path::new(§ion); + let mut context = Context::new(); + context.add("pages", &order_pages(pages)); + context.add("config", &config); + + let section_name = match path.components().into_iter().last() { + Some(s) => s.as_ref().to_string_lossy().to_string(), + None => bail!("Couldn't find a section name in {:?}", path.display()) + }; + + create_file(path.join("index.html"), &tera.render(&format!("{}.html", section_name), context)?) +} diff --git a/src/page.rs b/src/page.rs index 99ec127..a7f5752 100644 --- a/src/page.rs +++ b/src/page.rs @@ -20,23 +20,27 @@ lazy_static! { } -#[derive(Debug, PartialEq, Serialize, Deserialize)] +#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)] pub struct Page { // .md filepath, excluding the content/ bit + #[serde(skip_serializing)] pub filepath: String, // the name of the .md file + #[serde(skip_serializing)] pub filename: String, // the directories above our .md file are called sections // for example a file at content/kb/solutions/blabla.md will have 2 sections: // `kb` and `solutions` + #[serde(skip_serializing)] pub sections: Vec, + // the actual content of the page, in markdown + #[serde(skip_serializing)] + pub raw_content: String, // of the page pub title: String, // The page slug pub slug: String, - // the actual content of the page - pub raw_content: String, // the HTML rendered of the page pub content: String, @@ -55,6 +59,7 @@ pub struct Page { // optional date if we want to order pages (ie blog post) pub date: Option<String>, // optional layout, if we want to specify which tpl to render for that page + #[serde(skip_serializing)] pub layout: Option<String>, // description that appears when linked, e.g. on twitter pub description: Option<String>, @@ -158,6 +163,12 @@ impl Page { } +// Order pages by date, no-op for now +pub fn order_pages(pages: Vec<Page>) -> Vec<Page> { + pages +} + + #[cfg(test)] mod tests { use super::{Page};