1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171
use std::path; use std::fs; use std::io::Write; use liquid; use error::*; use config::Config; use datetime; use files; use legacy::wildwest; use slug; const COBALT_YML: &'static str = "name: cobalt blog source: \".\" dest: \"./_site\" "; const DEFAULT_LAYOUT: &'static str = "<!DOCTYPE html> <html> <head> <meta charset=\"utf-8\"> {% if is_post %} <title>{{ title }}</title> {% else %} <title>Cobalt.rs Blog</title> {% endif %} </head> <body> <div> {% if is_post %} {% include '_layouts/post.liquid' %} {% else %} {{ content }} {% endif %} </div> </body> </html> "; const POST_LAYOUT: &'static str = "<div> <h2>{{ title }}</h2> <p> {{content}} </p> </div> "; const POST_MD: &'static str = "extends: default.liquid title: First Post draft: true --- # This is our first Post! Welcome to the first post ever on cobalt.rs! "; const INDEX_MD: &'static str = "extends: default.liquid --- ## Blog! {% for post in posts %} #### {{post.title}} #### [{{ post.title }}]({{ post.path }}) {% endfor %} "; pub fn create_new_project<P: AsRef<path::Path>>(dest: P) -> Result<()> { create_new_project_for_path(dest.as_ref()) } pub fn create_new_project_for_path(dest: &path::Path) -> Result<()> { fs::create_dir_all(dest)?; create_file(&dest.join(".cobalt.yml"), COBALT_YML)?; create_file(&dest.join("index.md"), INDEX_MD)?; fs::create_dir_all(&dest.join("_layouts"))?; create_file(&dest.join("_layouts/default.liquid"), DEFAULT_LAYOUT)?; create_file(&dest.join("_layouts/post.liquid"), POST_LAYOUT)?; fs::create_dir_all(&dest.join("posts"))?; create_file(&dest.join("posts/post-1.md"), POST_MD)?; Ok(()) } pub fn create_new_document(config: &Config, title: &str, file: path::PathBuf) -> Result<()> { let file = if file.extension().is_none() { let file_name = format!("{}.md", slug::slugify(title)); let mut file = file; file.push(path::Path::new(&file_name)); file } else { file }; let rel_file = file.strip_prefix(&config.source) .map_err(|_| { format!("New file {:?} not project directory ({:?})", file, config.source) })?; let (file_type, doc) = if rel_file.starts_with(path::Path::new(&config.posts.dir)) || config .posts .drafts_dir .as_ref() .map(|dir| rel_file.starts_with(path::Path::new(dir))) .unwrap_or(false) { ("post", POST_MD) } else { ("page", INDEX_MD) }; let doc = wildwest::DocumentBuilder::parse(doc)?; let wildwest::DocumentBuilder { front, content } = doc; let mut front = front.object(); front.insert("title".to_owned(), liquid::Value::str(title)); let front = wildwest::FrontmatterBuilder::with_object(front); let doc = wildwest::DocumentBuilder { front, content }; let doc = doc.to_string(); create_file(&file, &doc)?; info!("Created new {} {:?}", file_type, rel_file); Ok(()) } fn create_file<P: AsRef<path::Path>>(path: P, content: &str) -> Result<()> { create_file_for_path(path.as_ref(), content) } fn create_file_for_path(path: &path::Path, content: &str) -> Result<()> { trace!("Creating file {:?}", path); let mut file = fs::OpenOptions::new() .write(true) .create_new(true) .open(path) .chain_err(|| format!("Failed to create file {:?}", path))?; file.write_all(content.as_bytes())?; Ok(()) } pub fn publish_document(file: &path::Path) -> Result<()> { let doc = files::read_file(file)?; let doc = wildwest::DocumentBuilder::parse(&doc)?; let wildwest::DocumentBuilder { front, content } = doc; let date = datetime::DateTime::now(); let date = date.format(); let mut front = front.object(); front.remove("draft"); front.insert("date".to_owned(), liquid::Value::Str(date)); let front = wildwest::FrontmatterBuilder::with_object(front); let doc = wildwest::DocumentBuilder { front, content }; let doc = doc.to_string(); files::write_document_file(doc, file)?; Ok(()) }