Add context object

main
trivernis 1 year ago
parent d6783d3e6b
commit a0a8b20138
Signed by: Trivernis
GPG Key ID: DFFFCC2C7A02DB45

@ -13,6 +13,7 @@ pub struct Config {
pub struct Folders { pub struct Folders {
pub content: Option<PathBuf>, pub content: Option<PathBuf>,
pub templates: Option<PathBuf>, pub templates: Option<PathBuf>,
pub stylesheets: Option<PathBuf>,
pub output: Option<PathBuf>, pub output: Option<PathBuf>,
} }

@ -0,0 +1,8 @@
use std::path::PathBuf;
pub struct Context {
pub content_dir: PathBuf,
pub template_dir: PathBuf,
pub stylesheet_dir: PathBuf,
pub output_dir: PathBuf,
}

@ -1,6 +1,12 @@
use std::{
path::{Path, PathBuf},
sync::Arc,
};
use args::BuildArgs; use args::BuildArgs;
use clap::Parser; use clap::Parser;
use config::{read_config, Config}; use config::{read_config, Config};
use context::Context;
use data::DirLoader; use data::DirLoader;
use miette::Result; use miette::Result;
use rendering::ContentRenderer; use rendering::ContentRenderer;
@ -11,6 +17,7 @@ use crate::args::Args;
mod args; mod args;
mod config; mod config;
mod context;
pub mod data; pub mod data;
mod processors; mod processors;
mod rendering; mod rendering;
@ -29,24 +36,33 @@ async fn main() -> Result<()> {
} }
async fn build(args: &Args, _build_args: &BuildArgs, cfg: Config) -> Result<()> { async fn build(args: &Args, _build_args: &BuildArgs, cfg: Config) -> Result<()> {
let folders = cfg.folders;
let base_path = &args.directory; let base_path = &args.directory;
let content_dir = base_path.join(folders.content.unwrap_or("content".into())); let ctx = Arc::new(build_context(&base_path, &cfg));
let template_dir = base_path.join(folders.templates.unwrap_or("templates".into()));
let out_dir = base_path.join(folders.output.unwrap_or("dist".into()));
let dirs = DirLoader::new(content_dir.to_owned()) let dirs = DirLoader::new(ctx.content_dir.to_owned())
.read_content() .read_content()
.await?; .await?;
let template_glob = format!("{}/**/*", template_dir.to_string_lossy()); ContentRenderer::new(ctx).render_all(dirs).await?;
ContentRenderer::new(template_glob, content_dir, out_dir)
.render_all(dirs)
.await?;
Ok(()) Ok(())
} }
fn build_context(base_path: &Path, config: &Config) -> Context {
let folders = config.folders.clone();
let content_dir = base_path.join(folders.content.unwrap_or("content".into()));
let template_dir = base_path.join(folders.templates.unwrap_or("templates".into()));
let output_dir = base_path.join(folders.output.unwrap_or("dist".into()));
let stylesheet_dir = base_path.join(folders.stylesheets.unwrap_or("style".into()));
Context {
content_dir,
template_dir,
stylesheet_dir,
output_dir,
}
}
fn init_tracing() { fn init_tracing() {
tracing_subscriber::fmt::SubscriberBuilder::default() tracing_subscriber::fmt::SubscriberBuilder::default()
.with_max_level(LevelFilter::TRACE) .with_max_level(LevelFilter::TRACE)

@ -1,32 +1,33 @@
use std::path::PathBuf; use std::{path::PathBuf, sync::Arc};
use futures::future; use futures::future;
use miette::{IntoDiagnostic, Result}; use miette::{IntoDiagnostic, Result};
use tera::{Context, Tera}; use tera::{Context as TeraContext, Tera};
use tokio::fs; use tokio::fs;
use crate::data::{load_page, FolderData}; use crate::{
context::Context,
data::{load_page, FolderData},
};
// renders content using the given template folder // renders content using the given template folder
pub struct ContentRenderer { pub struct ContentRenderer {
template_glob: String, template_glob: String,
out_dir: PathBuf, ctx: Arc<Context>,
content_dir: PathBuf,
} }
impl ContentRenderer { impl ContentRenderer {
pub fn new(template_glob: String, content_dir: PathBuf, out_dir: PathBuf) -> Self { pub fn new(ctx: Arc<Context>) -> Self {
Self { let template_glob = format!("{}/**/*", ctx.template_dir.to_string_lossy());
template_glob, Self { template_glob, ctx }
content_dir,
out_dir,
}
} }
#[tracing::instrument(level = "trace", skip_all)] #[tracing::instrument(level = "trace", skip_all)]
pub async fn render_all(&self, dirs: Vec<FolderData>) -> Result<()> { pub async fn render_all(&self, dirs: Vec<FolderData>) -> Result<()> {
if self.out_dir.exists() { if self.ctx.output_dir.exists() {
fs::remove_dir_all(&self.out_dir).await.into_diagnostic()?; fs::remove_dir_all(&self.ctx.output_dir)
.await
.into_diagnostic()?;
} }
let mut tera = Tera::new(&self.template_glob).into_diagnostic()?; let mut tera = Tera::new(&self.template_glob).into_diagnostic()?;
super::processors::register_all(&mut tera); super::processors::register_all(&mut tera);
@ -70,7 +71,7 @@ impl ContentRenderer {
tracing::debug!("Rendering {page_path:?}"); tracing::debug!("Rendering {page_path:?}");
let page = load_page(&page_path).await?; let page = load_page(&page_path).await?;
let mut context = Context::new(); let mut context = TeraContext::new();
let mut template_name = default_template; let mut template_name = default_template;
match page { match page {
@ -87,9 +88,9 @@ impl ContentRenderer {
let html = tera.render(&template_name, &context).into_diagnostic()?; let html = tera.render(&template_name, &context).into_diagnostic()?;
let rel_path = page_path let rel_path = page_path
.strip_prefix(&self.content_dir) .strip_prefix(&self.ctx.content_dir)
.into_diagnostic()?; .into_diagnostic()?;
let mut out_path = self.out_dir.join(rel_path); let mut out_path = self.ctx.output_dir.join(rel_path);
out_path.set_extension("html"); out_path.set_extension("html");
let parent = out_path.parent().unwrap(); let parent = out_path.parent().unwrap();

Loading…
Cancel
Save