use std::collections::HashMap; use std::fs::{create_dir, remove_dir_all}; use std::path::Path; use glob::glob; use tera::{Tera, Context}; use config:: Config; use errors::{Result, ResultExt}; use page::{Page, order_pages}; use utils::create_file; pub fn build(config: Config) -> Result<()> { if Path::new("public").exists() { // Delete current `public` directory so we can start fresh remove_dir_all("public").chain_err(|| "Couldn't delete `public` directory")?; } let tera = Tera::new("templates/**/*").chain_err(|| "Error parsing templates")?; // 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.to_path_buf(); for section in &page.sections { current_path.push(section); if !current_path.exists() { create_dir(¤t_path)?; } let str_path = current_path.as_path().to_string_lossy().to_string(); sections.entry(str_path).or_insert_with(|| vec![page.clone()]); } if let Some(ref url) = page.meta.url { println!("URL: {:?}", url); current_path.push(url); } else { println!("REMOVE ME IF YOU DONT SEE ME"); current_path.push(&page.get_slug()); } 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)?; } // 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(()) } 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)?) }