@@ -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" | |||
@@ -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<Page> = 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<Page> = vec![]; | |||
let mut sections: HashMap<String, Vec<Page>> = 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<Page>, 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)?) | |||
} |
@@ -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<String>, | |||
// the actual content of the page, in markdown | |||
#[serde(skip_serializing)] | |||
pub raw_content: String, | |||
// <title> 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}; | |||