feat: Added config

This commit is contained in:
2026-05-22 14:25:29 +02:00
parent 0e8876eede
commit 9fef261f80
5 changed files with 112 additions and 94 deletions
+6 -1
View File
@@ -118,12 +118,17 @@ fn construct_template(template_path: &str) -> Template {
}); });
let config_path = format!("{}/config.yaml", template_path); let config_path = format!("{}/config.yaml", template_path);
let config = if let Ok(config_str) = fs::read_to_string(&config_path) {
serde_yaml::from_str(&config_str).ok()
} else {
None
};
Template::TemplateInjector { Template::TemplateInjector {
template: template_content, template: template_content,
replace_selector: replace_selector.trim().to_string(), replace_selector: replace_selector.trim().to_string(),
scraper, scraper,
config_path: Some(config_path), config,
script: post_script, script: post_script,
style, style,
} }
-50
View File
@@ -1,50 +0,0 @@
use serde::Deserialize;
#[derive(Debug, Deserialize, PartialEq)]
pub enum ReplaceType {
#[serde(rename = "hide")]
Hide,
#[serde(rename = "replace")]
Replace,
}
impl Default for ReplaceType {
fn default() -> Self {
ReplaceType::Replace
}
}
#[derive(Debug, Deserialize, Default)]
pub struct TemplateReplacer {
#[serde(default)]
pub replace_type: ReplaceType,
}
#[derive(Debug, Deserialize, Default)]
pub struct Scraper {
#[serde(default)]
pub rerender_key: String,
}
#[derive(Debug, Deserialize, Default)]
pub struct Config {
#[serde(default)]
pub template_replacer: TemplateReplacer,
#[serde(default)]
pub scraper: Scraper,
}
impl Config {
pub fn load(path: &Option<String>) -> Self {
match path {
Some(path_str) => match std::fs::File::open(path_str) {
Ok(file) => {
let reader = std::io::BufReader::new(file);
serde_yaml::from_reader(reader).unwrap_or_default()
}
Err(_) => Config::default(),
},
None => Config::default(),
}
}
}
-1
View File
@@ -1,3 +1,2 @@
pub mod compiler; pub mod compiler;
pub mod models; pub mod models;
pub mod config;
+17 -1
View File
@@ -19,6 +19,22 @@ pub enum PageRoute {
CustomScript(String), CustomScript(String),
} }
#[derive(serde::Deserialize, Clone)]
pub struct TemplateConfig {
pub template_replacer: Option<TemplateReplacer>,
pub scraper: Option<ScraperConfig>,
}
#[derive(serde::Deserialize, Clone)]
pub struct TemplateReplacer {
pub replace_type: String, // "hide" or "replace"
}
#[derive(serde::Deserialize, Clone)]
pub struct ScraperConfig {
pub rerender_key: Option<String>,
}
pub enum Template { pub enum Template {
CustomScript { CustomScript {
script: String, script: String,
@@ -31,7 +47,7 @@ pub enum Template {
scraper: Option<String>, scraper: Option<String>,
style: Option<String>, style: Option<String>,
script: Option<String>, script: Option<String>,
config_path: Option<String>, config: Option<TemplateConfig>,
}, },
} }
+89 -41
View File
@@ -1,16 +1,25 @@
use indoc::indoc; use indoc::indoc;
use serde_json; use serde_json;
use crate::compiler::config::{Config, ReplaceType}; // use crate::compiler::config::{Config, ReplaceType}; // Removed unused imports
use crate::css::{minify_css, scope_css}; use crate::css::{minify_css, scope_css};
use crate::compiler::models::{PageRoute, Project, Template}; use crate::compiler::models::{PageRoute, Project, Template, TemplateConfig};
use crate::js::minify_javascript; use crate::js::minify_javascript;
impl Project { impl Project {
pub fn compile_script(&self) -> String { pub fn compile_script(&self) -> String {
let template = indoc! { r#" let template = indoc! { r#"
(function() { (function() {
window.Rerender = window.Rerender || {
components: {},
rerenderComponent: function(key) {
if (this.components[key]) {
this.components[key]();
}
}
};
if (typeof Handlebars === 'undefined') { if (typeof Handlebars === 'undefined') {
const script = document.createElement('script'); const script = document.createElement('script');
script.src = 'https://cdn.jsdelivr.net/npm/handlebars@latest/dist/handlebars.js'; script.src = 'https://cdn.jsdelivr.net/npm/handlebars@latest/dist/handlebars.js';
@@ -143,7 +152,7 @@ impl Template {
scraper, scraper,
script, script,
style, style,
config_path, config,
} => { } => {
let scope_class = format!("template-style-{}", rand::random::<u32>()); let scope_class = format!("template-style-{}", rand::random::<u32>());
let script = if let Some(script) = script { let script = if let Some(script) = script {
@@ -156,7 +165,34 @@ impl Template {
String::new() String::new()
}; };
let config = Config::load(config_path); // Default config
let config = config.clone().unwrap_or(TemplateConfig {
template_replacer: None,
scraper: None,
});
let rerender_key = config
.scraper
.as_ref()
.and_then(|s| s.rerender_key.as_ref());
let replace_type = config
.template_replacer
.as_ref()
.map(|r| r.replace_type.as_str())
.unwrap_or("replace");
let rerender_registration = if let Some(key) = rerender_key {
format!(
r#"
window.Rerender.components["{key}"] = function() {{
render();
}};
"#,
key = key
)
} else {
String::new()
};
let style_script = if let Some(style) = style { let style_script = if let Some(style) = style {
if style.trim().is_empty() { if style.trim().is_empty() {
@@ -167,7 +203,6 @@ impl Template {
(function() {{ (function() {{
const styleElement = document.createElement('style'); const styleElement = document.createElement('style');
styleElement.textContent = {style}; styleElement.textContent = {style};
console.log(styleElement.textContent);
document.head.appendChild(styleElement); document.head.appendChild(styleElement);
}})(); }})();
"# }, "# },
@@ -179,62 +214,75 @@ impl Template {
String::new() String::new()
}; };
let script_template = let script_template = if replace_type == "replace" {
if config.template_replacer.replace_type == ReplaceType::Replace { indoc! { r#"
indoc! { r#"
(function() { (function() {
{style_script} {style_script}
const parsedData = eval({scraper} || "(() => ({}))"); const render = function() {
const template = Handlebars.compile({template}); const parsedData = eval({scraper} || "(() => ({}))");
const rendered = template(parsedData); const template = Handlebars.compile({template});
const targetElement = document.querySelector({replace_selector}); const rendered = template(parsedData);
const targetElement = document.querySelector({replace_selector});
const temp = document.createElement('template'); const temp = document.createElement('template');
temp.innerHTML = rendered; temp.innerHTML = rendered;
const newElement = temp.content.firstElementChild;
// Remove old
const oldElement = document.querySelector('.' + {scope_class});
if(oldElement) oldElement.remove();
const newElement = temp.content.firstElementChild; targetElement.replaceWith(newElement);
newElement.classList.add({scope_class});
targetElement.replaceWith(newElement);
(function() {
newElement.classList.add({scope_class}); {script}
})();
(function() { };
{script} render();
})(); {rerender_registration}
})(); })();
"# "#
} }
} else { } else {
indoc! { r#" indoc! { r#"
(function() { (function() {
{style_script} {style_script}
const parsedData = eval({scraper} || "(() => ({}))"); const render = function() {
const template = Handlebars.compile({template}); const parsedData = eval({scraper} || "(() => ({}))");
const rendered = template(parsedData); const template = Handlebars.compile({template});
const targetElement = document.querySelector({replace_selector}); const rendered = template(parsedData);
const targetElement = document.querySelector({replace_selector});
targetElement.style.display = 'none'; targetElement.style.display = 'none';
const temp = document.createElement('template'); const temp = document.createElement('template');
temp.innerHTML = rendered; temp.innerHTML = rendered;
const newElement = temp.content.firstElementChild; const newElement = temp.content.firstElementChild;
// Remove old
const oldElement = document.querySelector('.' + {scope_class});
if(oldElement) oldElement.remove();
targetElement.after(newElement); targetElement.after(newElement);
newElement.classList.add({scope_class});
newElement.classList.add({scope_class}); (function() {
{script}
(function() { })();
{script} };
})(); render();
{rerender_registration}
})(); })();
"# } "# }
}; };
script_template script_template
.replace("{style_script}", &style_script.trim()) .replace("{style_script}", &style_script.trim())
.replace("{script}", &script) .replace("{script}", &script)
.replace("{rerender_registration}", &rerender_registration)
.replace( .replace(
"{template}", "{template}",
&serde_json::to_string(&template.trim()).unwrap(), &serde_json::to_string(&template.trim()).unwrap(),