use derive_more::Constructor; use serde::Serialize; use serde_json::value::Value; use std::collections::HashMap; use tera::{Context, Tera}; #[derive(Constructor, Debug, Serialize)] pub struct BlogPost { pub title: String, pub human_date: String, pub sort_date: i64, // Sort date = unix timestamp pub content: String, // Unformatted Content of blog post can be used to display a preview or reading time estimate. Will be html when assigned but later turned into raw text pub output_file_name: String, } pub fn generate(mut blog_posts: Vec, template_dir: &String) -> String { for post in &mut blog_posts { post.content = get_unformatted_text(post.content.clone()); } let mut tera = Tera::new(&format!("{}/*", template_dir)).unwrap(); tera.autoescape_on(vec![]); tera.register_filter("truncate", truncate); let mut context = Context::new(); context.insert("blog_posts", &blog_posts); tera.render("index.html", &context).unwrap() } fn get_unformatted_text(html: String) -> String { let frag = scraper::Html::parse_fragment(&html); let mut unformatted_text = String::new(); for node in frag.tree { if let scraper::node::Node::Text(text) = node { unformatted_text.push_str(&text); } } unformatted_text } fn truncate(value: &Value, args: &HashMap) -> Result { let mut value = value.as_str().unwrap().to_string(); let new_len:usize = args.get("len").unwrap().as_str().unwrap().parse().unwrap(); value .truncate(new_len); Ok(Value::String(value.to_string())) }