2024-04-06 21:39:27 +02:00
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 > {
2024-04-06 22:32:11 +02:00
let mut value = value . as_str ( ) . unwrap ( ) . to_string ( ) ;
let new_len :usize = args . get ( " len " ) . unwrap ( ) . as_str ( ) . unwrap ( ) . parse ( ) . unwrap ( ) ;
2024-04-06 21:39:27 +02:00
value
2024-04-06 22:32:11 +02:00
. truncate ( new_len ) ;
2024-04-06 21:39:27 +02:00
Ok ( Value ::String ( value . to_string ( ) ) )
}
2024-04-06 22:32:11 +02:00