47 lines
1.6 KiB
Rust
47 lines
1.6 KiB
Rust
|
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<BlogPost>, 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<String, Value>) -> Result<Value, tera::Error> {
|
||
|
let value = value.as_str().unwrap();
|
||
|
value
|
||
|
.to_string()
|
||
|
.truncate(args.get("len").unwrap().as_str().unwrap().parse().unwrap());
|
||
|
Ok(Value::String(value.to_string()))
|
||
|
}
|