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, pub template: DynDir,
// `static` directories // `static` directories
pub pics: DynDir, pub pic: DynDir,
pub emoji: DynDir, pub emoji: DynDir,
pub syntax: DynDir, pub syntax: DynDir,
} }

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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