Fix some theme extension

Closes #937
This commit is contained in:
Vincent Prouillet 2020-02-10 23:09:22 +01:00
parent 0d5fefd446
commit 855d2376df
4 changed files with 44 additions and 13 deletions

View file

@ -76,17 +76,19 @@ impl Site {
); );
let mut tera_theme = Tera::parse(&theme_tpl_glob) let mut tera_theme = Tera::parse(&theme_tpl_glob)
.map_err(|e| Error::chain("Error parsing templates from themes", e))?; .map_err(|e| Error::chain("Error parsing templates from themes", e))?;
rewrite_theme_paths(&mut tera_theme, &theme); rewrite_theme_paths(
&mut tera_theme,
tera.templates.values().map(|v| v.name.as_ref()).collect(),
&theme,
);
// TODO: we do that twice, make it dry? // TODO: we do that twice, make it dry?
if theme_path.join("templates").join("robots.txt").exists() { if theme_path.join("templates").join("robots.txt").exists() {
tera_theme tera_theme
.add_template_file(theme_path.join("templates").join("robots.txt"), None)?; .add_template_file(theme_path.join("templates").join("robots.txt"), None)?;
} }
tera_theme.build_inheritance_chains()?;
tera.extend(&tera_theme)?; tera.extend(&tera_theme)?;
} }
tera.extend(&ZOLA_TERA)?; tera.extend(&ZOLA_TERA)?;
// the `extend` above already does it but hey
tera.build_inheritance_chains()?; tera.build_inheritance_chains()?;
// TODO: Tera doesn't use globset right now so we can load the robots.txt as part // TODO: Tera doesn't use globset right now so we can load the robots.txt as part

View file

@ -67,17 +67,21 @@ pub fn render_template(
/// or macros is always better anyway for themes /// or macros is always better anyway for themes
/// This will also rename the shortcodes to NOT have the themes in the path /// This will also rename the shortcodes to NOT have the themes in the path
/// so themes shortcodes can be used. /// so themes shortcodes can be used.
pub fn rewrite_theme_paths(tera: &mut Tera, theme: &str) { pub fn rewrite_theme_paths(tera_theme: &mut Tera, site_templates: Vec<&str>, theme: &str) {
let mut shortcodes_to_move = vec![]; let mut shortcodes_to_move = vec![];
let mut templates = HashMap::new(); let mut templates = HashMap::new();
let old_templates = ::std::mem::replace(&mut tera.templates, HashMap::new()); let old_templates = ::std::mem::replace(&mut tera_theme.templates, HashMap::new());
// We want to match the paths in the templates to the new names // We want to match the paths in the templates to the new names
for (key, mut tpl) in old_templates { for (key, mut tpl) in old_templates {
tpl.name = format!("{}/templates/{}", theme, tpl.name); tpl.name = format!("{}/templates/{}", theme, tpl.name);
// First the parent if there is none // First the parent if there is one
// If a template with the same name is also in site, assumes it overrides the theme one
// and do not change anything
if let Some(ref p) = tpl.parent.clone() { if let Some(ref p) = tpl.parent.clone() {
tpl.parent = Some(format!("{}/templates/{}", theme, p)); if !site_templates.contains(&p.as_ref()) {
tpl.parent = Some(format!("{}/templates/{}", theme, p));
}
} }
// Next the macros import // Next the macros import
@ -96,12 +100,12 @@ pub fn rewrite_theme_paths(tera: &mut Tera, theme: &str) {
templates.insert(tpl.name.clone(), tpl); templates.insert(tpl.name.clone(), tpl);
} }
tera.templates = templates; tera_theme.templates = templates;
// and then replace shortcodes in the Tera instance using the new names // and then replace shortcodes in the Tera instance using the new names
for (old_name, new_name) in shortcodes_to_move { for (old_name, new_name) in shortcodes_to_move {
let tpl = tera.templates.remove(&old_name).unwrap(); let tpl = tera_theme.templates.remove(&old_name).unwrap();
tera.templates.insert(new_name, tpl); tera_theme.templates.insert(new_name, tpl);
} }
} }
@ -113,12 +117,23 @@ mod tests {
#[test] #[test]
fn can_rewrite_all_paths_of_theme() { fn can_rewrite_all_paths_of_theme() {
let mut tera = Tera::parse("test-templates/*.html").unwrap(); let mut tera = Tera::parse("test-templates/*.html").unwrap();
rewrite_theme_paths(&mut tera, "hyde"); rewrite_theme_paths(&mut tera, vec!["base.html"], "hyde");
// special case to make the test work: we also rename the files to // special case to make the test work: we also rename the files to
// match the imports // match the imports
for (key, val) in tera.templates.clone() { for (key, val) in &tera.templates.clone() {
tera.templates.insert(format!("hyde/templates/{}", key), val.clone()); tera.templates.insert(format!("hyde/templates/{}", key), val.clone());
} }
// Adding our fake base
tera.add_raw_template("base.html", "Hello").unwrap();
tera.build_inheritance_chains().unwrap(); tera.build_inheritance_chains().unwrap();
assert_eq!(
tera.templates["hyde/templates/index.html"].parent,
Some("base.html".to_string())
);
assert_eq!(
tera.templates["hyde/templates/child.html"].parent,
Some("hyde/templates/index.html".to_string())
);
} }
} }

View file

@ -0,0 +1,10 @@
<!DOCTYPE html>
<html lang="en">
<head>
</head>
<body>
{% block body %}
{% endblock body %}
</body>
</html>

View file

@ -1 +1,5 @@
Some base template, used in tests to check whether path rewriting works. {% extends "base.html" %}
{% block body %}
The default text
{% endblock body %}