feat: Added config
This commit is contained in:
@@ -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,
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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,3 +1,2 @@
|
|||||||
pub mod compiler;
|
pub mod compiler;
|
||||||
pub mod models;
|
pub mod models;
|
||||||
pub mod config;
|
|
||||||
|
|||||||
+17
-1
@@ -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>,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+86
-38
@@ -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;
|
||||||
|
|
||||||
const newElement = temp.content.firstElementChild;
|
// Remove old
|
||||||
|
const oldElement = document.querySelector('.' + {scope_class});
|
||||||
|
if(oldElement) oldElement.remove();
|
||||||
|
|
||||||
targetElement.replaceWith(newElement);
|
targetElement.replaceWith(newElement);
|
||||||
|
newElement.classList.add({scope_class});
|
||||||
|
|
||||||
newElement.classList.add({scope_class});
|
(function() {
|
||||||
|
{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;
|
||||||
|
|
||||||
targetElement.after(newElement);
|
// Remove old
|
||||||
|
const oldElement = document.querySelector('.' + {scope_class});
|
||||||
|
if(oldElement) oldElement.remove();
|
||||||
|
|
||||||
newElement.classList.add({scope_class});
|
targetElement.after(newElement);
|
||||||
|
newElement.classList.add({scope_class});
|
||||||
|
|
||||||
(function() {
|
(function() {
|
||||||
{script}
|
{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(),
|
||||||
|
|||||||
Reference in New Issue
Block a user