right now very barebones! - doesn't sort pages quite correctly - no search function - still not sure about the UI design aspects includes refactor of tree generation code
111 lines
2.8 KiB
Rust
111 lines
2.8 KiB
Rust
use anyhow::{ensure, Context};
|
|
use handlebars::Handlebars;
|
|
use serde::Serialize;
|
|
use tracing::{info_span, instrument};
|
|
|
|
use crate::{
|
|
dirs::Dirs,
|
|
generate::BaseTemplateData,
|
|
html::{breadcrumbs::breadcrumbs_to_html, tree},
|
|
sources::Sources,
|
|
state::FileId,
|
|
};
|
|
|
|
#[derive(Serialize)]
|
|
struct Page {
|
|
title: String,
|
|
thumbnail: Option<Thumbnail>,
|
|
scripts: Vec<String>,
|
|
styles: Vec<String>,
|
|
breadcrumbs: String,
|
|
tree_path: Option<String>,
|
|
tree: String,
|
|
}
|
|
|
|
#[derive(Serialize)]
|
|
struct Thumbnail {
|
|
url: String,
|
|
alt: Option<String>,
|
|
}
|
|
|
|
#[derive(Serialize)]
|
|
struct PageTemplateData<'a> {
|
|
#[serde(flatten)]
|
|
base: &'a BaseTemplateData<'a>,
|
|
page: Page,
|
|
}
|
|
|
|
#[instrument(skip(sources, dirs, handlebars))]
|
|
pub fn generate(
|
|
sources: &Sources,
|
|
dirs: &Dirs,
|
|
handlebars: &Handlebars,
|
|
file_id: FileId,
|
|
) -> anyhow::Result<String> {
|
|
let breadcrumbs = breadcrumbs_to_html(&sources.config, &sources.navigation_map, file_id);
|
|
|
|
let roots = sources
|
|
.treehouse
|
|
.roots
|
|
.get(&file_id)
|
|
.expect("tree should have been added to the treehouse");
|
|
|
|
let tree = {
|
|
let _span = info_span!("generate_tree::root_to_html").entered();
|
|
let renderer = tree::Renderer {
|
|
sources,
|
|
dirs,
|
|
file_id,
|
|
};
|
|
let mut tree = String::new();
|
|
renderer.root(&mut tree);
|
|
tree
|
|
};
|
|
|
|
let template_data = PageTemplateData {
|
|
base: &BaseTemplateData::new(sources),
|
|
page: Page {
|
|
title: roots.attributes.title.clone(),
|
|
thumbnail: roots
|
|
.attributes
|
|
.thumbnail
|
|
.as_ref()
|
|
.map(|thumbnail| Thumbnail {
|
|
url: sources.config.pic_url(&*dirs.pic, &thumbnail.id),
|
|
alt: thumbnail.alt.clone(),
|
|
}),
|
|
scripts: roots.attributes.scripts.clone(),
|
|
styles: roots.attributes.styles.clone(),
|
|
breadcrumbs,
|
|
tree_path: sources.treehouse.tree_path(file_id).map(|s| s.to_string()),
|
|
tree,
|
|
},
|
|
};
|
|
let template_name = roots
|
|
.attributes
|
|
.template
|
|
.clone()
|
|
.unwrap_or_else(|| "_tree.hbs".into());
|
|
|
|
ensure!(
|
|
handlebars.has_template(&template_name),
|
|
"template {template_name} does not exist"
|
|
);
|
|
|
|
let _span = info_span!("handlebars::render").entered();
|
|
handlebars
|
|
.render(&template_name, &template_data)
|
|
.context("template rendering failed")
|
|
}
|
|
|
|
pub fn generate_or_error(
|
|
sources: &Sources,
|
|
dirs: &Dirs,
|
|
handlebars: &Handlebars,
|
|
file_id: FileId,
|
|
) -> String {
|
|
match generate(sources, dirs, handlebars, file_id) {
|
|
Ok(html) => html,
|
|
Err(error) => format!("error: {error:?}"),
|
|
}
|
|
}
|