implement generation of simple templates (/sandbox)

This commit is contained in:
liquidex 2024-11-22 23:12:57 +01:00
parent 377fbe4dab
commit 32f25ce863
7 changed files with 63 additions and 35 deletions

View file

@ -9,7 +9,7 @@ pub struct Dirs {
pub template: DynDir,
// `static` directories
pub pics: DynDir,
pub pic: DynDir,
pub emoji: DynDir,
pub syntax: DynDir,
}

View file

@ -180,31 +180,32 @@ fn parse_trees(
Ok((treehouse, parsed_trees))
}
// TODO: Generation of pages in static/html
//
// for (name, &file_id) in &template_file_ids {
// let filename = name.rsplit_once('/').unwrap_or(("", name)).1;
// if !filename.starts_with('_') {
// let templated_html = match handlebars.render(name, &base_template_data) {
// Ok(html) => html,
// Err(error) => {
// Self::wrangle_handlebars_error_into_diagnostic(
// treehouse,
// &mut global_diagnostics,
// file_id,
// error.line_no,
// error.column_no,
// error.desc,
// )?;
// continue;
// }
// };
// std::fs::write(
// paths.template_target_dir.join(name).with_extension("html"),
// templated_html,
// )?;
// }
// }
fn generate_simple_template(
sources: &Sources,
handlebars: &Handlebars,
template_name: &str,
) -> anyhow::Result<String> {
let base_template_data = BaseTemplateData {
config: &sources.config,
import_map: serde_json::to_string_pretty(&sources.import_map)
.expect("import map should be serializable to JSON"),
season: Season::current(),
};
handlebars
.render(template_name, &base_template_data)
.context("failed to render template")
}
fn generate_simple_template_or_error(
sources: &Sources,
handlebars: &Handlebars,
template_name: &str,
) -> String {
match generate_simple_template(sources, handlebars, template_name) {
Ok(html) => html,
Err(error) => format!("error: {error:?}"),
}
}
fn generate_tree(
sources: &Sources,
@ -249,7 +250,7 @@ fn generate_tree(
.thumbnail
.as_ref()
.map(|thumbnail| Thumbnail {
url: sources.config.pic_url(&*dirs.pics, &thumbnail.id),
url: sources.config.pic_url(&*dirs.pic, &thumbnail.id),
alt: thumbnail.alt.clone(),
}),
scripts: roots.attributes.scripts.clone(),
@ -311,7 +312,7 @@ impl Sources {
.context("failed to deserialize config")?;
config.site = std::env::var("TREEHOUSE_SITE").unwrap_or(config.site);
config.autopopulate_emoji(&*dirs.emoji)?;
config.autopopulate_pics(&*dirs.pics)?;
config.autopopulate_pics(&*dirs.pic)?;
config.load_syntaxes(&*dirs.syntax)?;
info!("parsing tree files");
@ -391,6 +392,8 @@ impl TreehouseDir {
impl Dir for TreehouseDir {
fn dir(&self, path: &VPath) -> Vec<DirEntry> {
// NOTE: This does not include simple templates, because that's not really needed right now.
let mut index = &self.dir_index;
for component in path.segments() {
if let Some(child) = index.children.get(component) {
@ -424,8 +427,28 @@ impl Dir for TreehouseDir {
path.set_extension("");
}
self.sources.parsed_trees.get(&path).map(|parsed_tree| {
generate_tree_or_error(&self.sources, &self.dirs, &self.handlebars, parsed_tree).into()
self.sources
.parsed_trees
.get(&path)
.map(|parsed_tree| {
generate_tree_or_error(&self.sources, &self.dirs, &self.handlebars, parsed_tree)
.into()
})
.or_else(|| {
if path.file_name().is_some_and(|s| !s.starts_with('_')) {
let template_name = path.with_extension("hbs");
if self.handlebars.has_template(template_name.as_str()) {
return Some(
generate_simple_template_or_error(
&self.sources,
&self.handlebars,
template_name.as_str(),
)
.into(),
);
}
}
None
})
}

View file

@ -375,7 +375,7 @@ impl<'a> Writer<'a> {
let pic_url = self
.renderer
.config
.pic_url(&*self.renderer.dirs.pics, placeholder_pic_id);
.pic_url(&*self.renderer.dirs.pic, placeholder_pic_id);
write_attr(&pic_url, out);
out.push('"');
@ -648,7 +648,7 @@ impl<'a> Writer<'a> {
)
}),
"page" => Some(config.page_url(linked)),
"pic" => Some(config.pic_url(&*self.renderer.dirs.pics, linked)),
"pic" => Some(config.pic_url(&*self.renderer.dirs.pic, linked)),
_ => None,
})
}

View file

@ -54,7 +54,7 @@ async fn fallible_main() -> anyhow::Result<()> {
content: Cd::new(src.clone(), VPathBuf::new("content")).to_dyn(),
static_: Cd::new(src.clone(), VPathBuf::new("static")).to_dyn(),
template: Cd::new(src.clone(), VPathBuf::new("template")).to_dyn(),
pics: Cd::new(src.clone(), VPathBuf::new("static/pics")).to_dyn(),
pic: Cd::new(src.clone(), VPathBuf::new("static/pic")).to_dyn(),
emoji: Cd::new(src.clone(), VPathBuf::new("static/emoji")).to_dyn(),
syntax: Cd::new(src.clone(), VPathBuf::new("static/syntax")).to_dyn(),
});

View file

@ -203,7 +203,7 @@ impl Renderer<'_> {
) -> Result<String, InvalidTemplate> {
let (function, arguments) = template.split_once(' ').unwrap_or((template, ""));
match function {
"pic" => Ok(config.pic_url(&*dirs.pics, arguments)),
"pic" => Ok(config.pic_url(&*dirs.pic, arguments)),
"include_static" => VPath::try_new(arguments)
.ok()
.and_then(|vpath| dirs.static_.content(vpath))

View file

@ -217,6 +217,9 @@ impl VPathBuf {
let range = self.path.len() - chop_len..;
self.path.replace_range(range, new_extension);
} else {
self.path.push('.');
self.path.push_str(new_extension);
}
}
}

View file

@ -3,6 +3,8 @@
<html>
<head>
<meta charset="UTF-8">
<title>treehouse iframe sandbox</title>
<link rel="stylesheet" href="{{ asset 'css/base.css' }}">