From ea5ce83658c335228d29723192893b2bfce051c6 Mon Sep 17 00:00:00 2001 From: Mylloon Date: Sun, 9 Apr 2023 16:58:21 +0200 Subject: [PATCH] Template minification * use dist/template when exists * move the minification in config.rs * load askama.toml for the templates dirs name * extract the minification of file to minify_and_copy --- askama.toml | 3 ++ src/config.rs | 101 +++++++++++++++++++++++++++++++++++++++++++++++++- src/main.rs | 56 +--------------------------- 3 files changed, 105 insertions(+), 55 deletions(-) create mode 100644 askama.toml diff --git a/askama.toml b/askama.toml new file mode 100644 index 0000000..4c5d332 --- /dev/null +++ b/askama.toml @@ -0,0 +1,3 @@ +[general] +# Directories to search for templates, relative to the crate root. +dirs = ["dist/templates", "templates"] diff --git a/src/config.rs b/src/config.rs index 02380f4..4427086 100644 --- a/src/config.rs +++ b/src/config.rs @@ -1,5 +1,12 @@ use serde::Deserialize; -use std::fs; +use std::{ + fs::{self, read_to_string, remove_dir_all}, + path::PathBuf, +}; + +use glob::glob; +use minify_html::{minify, Cfg}; +use std::{fs::File, io::Write, path::Path}; #[derive(Deserialize, Clone, Default)] pub struct FileConfig { @@ -13,6 +20,17 @@ pub struct FileConfig { #[derive(Clone)] pub struct Config { pub fc: FileConfig, + pub static_location: String, +} + +#[derive(Deserialize)] +struct AskamaConfig { + general: AskamaConfigGeneral, +} + +#[derive(Deserialize)] +struct AskamaConfigGeneral { + dirs: Vec, } impl FileConfig { @@ -63,10 +81,91 @@ fn get_file_config(file_path: &str) -> FileConfig { } } +fn get_askama_config() -> AskamaConfig { + toml::from_str(&read_to_string("askama.toml").unwrap()).unwrap() +} + pub fn get_config(file_path: &str) -> Config { let internal_config = get_file_config(file_path); + let static_dir = "static".to_string(); + let templates_dir = get_askama_config().general.dirs.last().unwrap().to_string(); + let files_root = init(static_dir.clone(), templates_dir); + Config { fc: internal_config, + static_location: format!("{}/{}", files_root, static_dir), + } +} + +fn init(static_dir: String, templates_dir: String) -> String { + let dist_folder = "dist".to_string(); + + // println!("static = {}/{}", dist_folder, static_dir); + // println!("templates = {}/{}", dist_folder, templates_dir); + + // The static folder is minimized only in release mode + if cfg!(debug_assertions) { + // Be sure that we not gonna use the dist folder by deleting it + remove_dir_all(dist_folder).unwrap_or_default(); + + ".".to_string() + } else { + let cfg = Cfg::spec_compliant(); + + // Static files + for entry in glob(&format!("{static_dir}/**/*.*")).unwrap() { + let path = entry.unwrap(); + let path_with_dist = path + .to_string_lossy() + .replace(&static_dir, &format!("{dist_folder}/{static_dir}")); + + minify_and_copy(&cfg, path, path_with_dist); + } + + // Template files + for entry in glob(&format!("{templates_dir}/**/*.*")).unwrap() { + let path = entry.unwrap(); + let path_with_dist = path + .to_string_lossy() + .replace(&templates_dir, &format!("{dist_folder}/{templates_dir}")); + + minify_and_copy(&cfg, path, path_with_dist); + } + + dist_folder + } +} + +fn minify_and_copy(cfg: &Cfg, path: PathBuf, path_with_dist: String) { + // Create folders + let new_path = Path::new(&path_with_dist); + fs::create_dir_all(new_path.parent().unwrap()).unwrap(); + + let mut copy = true; + if let Some(ext) = path.extension() { + // List of files who should be minified + if ["html", "css", "js", "svg", "webmanifest", "xml"] + .iter() + .any(|item| ext.to_string_lossy().to_lowercase().contains(item)) + { + // We won't copy, we'll minify + copy = false; + + // Minify + let data = fs::read(&path).unwrap(); + let minified = minify(&data, cfg); + + // Write files + let file = File::create(&path_with_dist); + file.expect("Error when minify the file") + .write_all(&minified) + .unwrap(); + } + } + + if copy { + // If no minification is needed + fs::copy(path, path_with_dist).unwrap(); } } diff --git a/src/main.rs b/src/main.rs index 25874f6..00e7570 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,12 +1,6 @@ use actix_files::Files; use actix_web::{middleware::DefaultHeaders, web, App, HttpServer}; -use glob::glob; -use minify_html::{minify, Cfg}; -use std::{ - fs::{self, File}, - io::{self, Write}, - path::Path, -}; +use std::io; mod config; mod template; @@ -35,52 +29,6 @@ async fn main() -> io::Result<()> { let addr = ("0.0.0.0", config.fc.port.unwrap()); - let static_folder = "static"; - let dist_folder = format!("dist/{static_folder}"); - - // The static folder is minimized only in release mode - let folder = if cfg!(debug_assertions) { - format!("{static_folder}/") - } else { - let cfg = Cfg::spec_compliant(); - - for entry in glob(&format!("{static_folder}/**/*.*")).unwrap() { - let path = entry.unwrap(); - let path_with_dist = path.to_string_lossy().replace(static_folder, &dist_folder); - - // Create folders - let new_path = Path::new(&path_with_dist); - fs::create_dir_all(new_path.parent().unwrap()).unwrap(); - - let mut copy = true; - if let Some(ext) = path.extension() { - // List of files who should be minified - if ["html", "css", "js", "svg", "webmanifest", "xml"] - .iter() - .any(|item| ext.to_string_lossy().to_lowercase().contains(item)) - { - // We won't copy, we'll minify - copy = false; - - // Minify - let data = fs::read(&path).unwrap(); - let minified = minify(&data, &cfg); - - // Write files - let mut file = File::create(&path_with_dist)?; - file.write_all(&minified)?; - } - } - - if copy { - // If no minification is needed - fs::copy(path, path_with_dist)?; - } - } - - format!("{dist_folder}/") - }; - println!( "Listening to {}://{}:{}", config.clone().fc.scheme.unwrap(), @@ -103,7 +51,7 @@ async fn main() -> io::Result<()> { .service(networks::page) .service(portfolio::page) .service(contrib::page) - .service(Files::new("/", &folder)) + .service(Files::new("/", config.static_location.clone())) .default_service(web::to(not_found::page)) }) .bind(addr)?