zola/src/cmd/build.rs

81 lines
2.5 KiB
Rust
Raw Normal View History

2016-12-13 09:05:59 +00:00
use std::collections::HashMap;
2016-12-13 06:22:24 +00:00
use std::fs::{create_dir, remove_dir_all};
use std::path::Path;
use glob::glob;
2016-12-13 09:05:59 +00:00
use tera::{Tera, Context};
2016-12-06 08:27:03 +00:00
use config:: Config;
use errors::{Result, ResultExt};
2016-12-13 09:05:59 +00:00
use page::{Page, order_pages};
2016-12-13 06:22:24 +00:00
use utils::create_file;
2016-12-06 12:48:23 +00:00
2016-12-06 08:27:03 +00:00
pub fn build(config: Config) -> Result<()> {
2016-12-13 06:22:24 +00:00
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("layouts/**/*").chain_err(|| "Error parsing templates")?;
2016-12-13 06:22:24 +00:00
// ok we got all the pages HTML, time to write them down to disk
create_dir("public")?;
let public = Path::new("public");
2016-12-13 09:05:59 +00:00
let mut pages: Vec<Page> = vec![];
let mut sections: HashMap<String, Vec<Page>> = HashMap::new();
2016-12-13 09:05:59 +00:00
// 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();
2016-12-13 06:22:24 +00:00
let mut page = Page::from_file(&path)?;
2016-12-13 06:22:24 +00:00
let mut current_path = public.clone().to_path_buf();
2016-12-13 09:05:59 +00:00
2016-12-13 06:22:24 +00:00
for section in &page.sections {
current_path.push(section);
2016-12-13 09:05:59 +00:00
2016-12-13 06:22:24 +00:00
if !current_path.exists() {
create_dir(&current_path)?;
}
2016-12-13 09:05:59 +00:00
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()]);
}
2016-12-13 06:22:24 +00:00
}
2016-12-13 09:05:59 +00:00
2016-12-13 06:22:24 +00:00
current_path.push(&page.filename);
create_dir(&current_path)?;
create_file(current_path.join("index.html"), &page.render_html(&tera, &config)?)?;
2016-12-13 09:05:59 +00:00
pages.push(page);
}
for (section, pages) in sections {
render_section_index(section, pages, &tera, &config)?;
}
2016-12-06 08:27:03 +00:00
2016-12-13 06:22:24 +00:00
2016-12-06 08:27:03 +00:00
Ok(())
}
2016-12-13 09:05:59 +00:00
fn render_section_index(section: String, pages: Vec<Page>, tera: &Tera, config: &Config) -> Result<()> {
let path = Path::new(&section);
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)?)
}