swap to tera in place of handlebars

This commit is contained in:
zyl 2024-11-04 17:09:11 -08:00
parent 76c75a40d9
commit ee48eae327
Signed by: zyl
SSH key fingerprint: SHA256:uxxbSXbdroP/OnKBGnEDk5q7EKB2razvstC/KmzdXXs
25 changed files with 407 additions and 184 deletions

View file

@ -3,10 +3,10 @@
use std::{collections::HashMap, path::PathBuf};
use eyre::{eyre, Context, OptionExt};
use handlebars::Handlebars;
use lol_html::{element, html_content::ContentType, HtmlRewriter, Settings};
use pulldown_cmark::{Options, Parser};
use serde::Serialize;
use tera::Tera;
use url::Url;
use crate::{resource::ResourceBuilder, util, PageMetadata, Site, ROOT_PATH, SASS_PATH};
@ -30,9 +30,9 @@ struct TemplateData<'a, T> {
}
/// Struct used to build the site.
pub struct SiteBuilder<'a> {
pub struct SiteBuilder {
/// The Handlebars registry used to render templates.
pub(crate) reg: Handlebars<'a>,
pub(crate) tera: Tera,
/// The site info used to build the site.
pub site: Site,
/// The path to the build directory.
@ -44,7 +44,7 @@ pub struct SiteBuilder<'a> {
pub resource_builders: HashMap<String, ResourceBuilder>,
}
impl<'a> SiteBuilder<'a> {
impl SiteBuilder {
/// Creates a new site builder.
pub fn new(site: Site, serving: bool) -> Self {
let mut build_path = match &site.config.build {
@ -55,8 +55,17 @@ impl<'a> SiteBuilder<'a> {
build_path = site.site_path.join("build");
}
let mut tera = Tera::new(
site.site_path
.join("templates/**/*.tera")
.to_str()
.expect("failed to convert path to string"),
)
.expect("failed to create tera instance");
tera.autoescape_on(vec![".tera"]);
Self {
reg: Handlebars::new(),
tera,
resource_builders: HashMap::new(),
site,
build_path,
@ -66,6 +75,7 @@ impl<'a> SiteBuilder<'a> {
/// Prepares the site builder for use and sets up the build directory.
pub fn prepare(mut self) -> eyre::Result<Self> {
self.tera.full_reload()?;
if self.build_path.exists() {
for entry in self.build_path.read_dir()? {
let path = &entry?.path();
@ -82,12 +92,6 @@ impl<'a> SiteBuilder<'a> {
std::fs::create_dir(&self.build_path).wrap_err("Failed to create build directory")?;
}
for (template_name, template_path) in &self.site.template_index {
self.reg
.register_template_file(template_name, template_path)
.wrap_err("Failed to register template file")?;
}
let root_path = self.site.site_path.join(ROOT_PATH);
if root_path.exists() {
for entry in walkdir::WalkDir::new(&root_path) {
@ -272,16 +276,18 @@ impl<'a> SiteBuilder<'a> {
embed.build()
});
let out = self.reg.render(
&page_metadata.template.unwrap_or_else(|| "base".to_string()),
&TemplateData {
let out = self.tera.render(
&page_metadata
.template
.unwrap_or_else(|| "base.tera".to_string()),
&tera::Context::from_serialize(TemplateData {
page: page_html,
title: &title,
head,
scripts: &page_metadata.scripts,
styles: &page_metadata.styles,
extra_data,
},
})?,
)?;
// Modify HTML output

View file

@ -30,7 +30,7 @@ impl Extra {
match self {
Self::Basic => {
let data: BasicData = serde_yml::from_value(data.inner.clone())?;
let content = builder.reg.render(&data.template, &())?;
let content = builder.tera.render(&data.template, &tera::Context::new())?;
append_to(&page, &content, "main.page")
}
Self::HtmlModification(f) => (f)(page, builder, data),
@ -91,9 +91,9 @@ fn resource_list_outside(
let data: ResourceListData = serde_yml::from_value(data.inner.clone())?;
let resource_list = builder.reg.render(
let resource_list = builder.tera.render(
&data.template,
&ResourceListTemplateData {
&tera::Context::from_serialize(ResourceListTemplateData {
resources: builder
.resource_builders
.get(&data.resource)
@ -107,7 +107,7 @@ fn resource_list_outside(
timestamp: v.timestamp,
})
.collect(),
},
})?,
)?;
append_to(&page, &resource_list, "#content")

View file

@ -29,7 +29,10 @@ pub fn render_basic_link_list(
title: &str,
) -> eyre::Result<String> {
let data = LinkTemplateData { links, title };
let out = builder.reg.render("basic-link-list", &data)?;
let out = builder.tera.render(
"basic-link-list.tera",
&tera::Context::from_serialize(data)?,
)?;
let out = builder.build_page_raw(
PageMetadata {
title: Some(title.to_owned()),

View file

@ -258,7 +258,10 @@ impl ResourceBuilder {
id,
timestamp: resource.timestamp,
};
builder.reg.render(&self.config.resource_template, &data)?
builder.tera.render(
&self.config.resource_template,
&tera::Context::from_serialize(data)?,
)?
};
let out = builder.build_page_raw_with_extra_data(
@ -341,7 +344,10 @@ impl ResourceBuilder {
previous,
next,
};
let out = builder.reg.render(&config.resource_list_template, &data)?;
let out = builder.tera.render(
&config.resource_list_template,
&tera::Context::from_serialize(data)?,
)?;
let out = builder.build_page_raw(
PageMetadata {
title: Some(title.to_owned()),
@ -437,9 +443,10 @@ impl ResourceBuilder {
))
.description(resource.resource.desc.clone())
.pub_date(Some(resource.timestamp.format(&Rfc2822)?))
.content(Some(
builder.reg.render(&self.config.rss_template, &resource)?,
))
.content(Some(builder.tera.render(
&self.config.rss_template,
&tera::Context::from_serialize(resource)?,
)?))
.build(),
)
}

View file

@ -79,9 +79,8 @@ fn create(
if build {
builder.build_page(&page_name_str)?;
}
} else if let Ok(template_path) = relative_path.strip_prefix(TEMPLATES_PATH) {
let (_template_name, template_name_str) = get_name(template_path);
builder.refresh_template(&template_name_str, path)?;
} else if let Ok(_template_path) = relative_path.strip_prefix(TEMPLATES_PATH) {
builder.tera.full_reload()?;
if build {
builder.site.build_all_pages(builder)?;
builder.build_all_resources()?;
@ -118,7 +117,7 @@ fn remove(builder: &mut SiteBuilder, path: &Path, relative_path: &Path) -> eyre:
} else if let Ok(template_path) = relative_path.strip_prefix(TEMPLATES_PATH) {
let (_template_name, template_name_str) = get_name(template_path);
builder.site.template_index.remove(&template_name_str);
builder.reg.unregister_template(&template_name_str);
builder.tera.full_reload()?;
builder
.site
.build_all_pages(builder)
@ -324,17 +323,3 @@ impl Site {
Ok(())
}
}
impl<'a> SiteBuilder<'a> {
/// Refreshes a template to ensure it's up to date.
pub fn refresh_template(
&mut self,
template_name: &str,
template_path: &Path,
) -> eyre::Result<()> {
self.reg
.register_template_file(template_name, template_path)?;
Ok(())
}
}