Streamline render pipeline by moving everything to submodules
parent
3655ad2c5f
commit
a2eeb4fe73
@ -0,0 +1,2 @@
|
||||
mod save_file;
|
||||
pub use save_file::*;
|
@ -0,0 +1,36 @@
|
||||
use std::path::PathBuf;
|
||||
|
||||
use async_trait::async_trait;
|
||||
use miette::{IntoDiagnostic, Result};
|
||||
use tokio::fs;
|
||||
|
||||
use crate::pipeline::ProcessingStep;
|
||||
|
||||
pub struct SaveFile;
|
||||
|
||||
pub struct SaveFileParams {
|
||||
pub path: PathBuf,
|
||||
pub contents: Vec<u8>,
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
impl ProcessingStep for SaveFile {
|
||||
type Input = SaveFileParams;
|
||||
type Output = ();
|
||||
|
||||
#[tracing::instrument(name = "save file", level = "trace", skip_all)]
|
||||
async fn process(
|
||||
&self,
|
||||
SaveFileParams { path, contents }: Self::Input,
|
||||
) -> Result<Self::Output> {
|
||||
if let Some(parent) = path.parent() {
|
||||
if !parent.exists() {
|
||||
fs::create_dir_all(parent).await.into_diagnostic()?;
|
||||
}
|
||||
}
|
||||
|
||||
fs::write(path, contents).await.into_diagnostic()?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
@ -0,0 +1,36 @@
|
||||
use std::path::PathBuf;
|
||||
|
||||
use async_trait::async_trait;
|
||||
use miette::Result;
|
||||
|
||||
use crate::{data::FolderData, pipeline::ProcessingStep};
|
||||
|
||||
pub struct LoadDirContent;
|
||||
|
||||
#[async_trait]
|
||||
impl ProcessingStep for LoadDirContent {
|
||||
type Input = FolderData;
|
||||
type Output = Vec<(PathBuf, String)>;
|
||||
|
||||
#[tracing::instrument(name = "load dir", level = "trace", skip_all)]
|
||||
async fn process(&self, input: Self::Input) -> Result<Self::Output> {
|
||||
let dir_name = input
|
||||
.path
|
||||
.components()
|
||||
.last()
|
||||
.unwrap()
|
||||
.as_os_str()
|
||||
.to_string_lossy();
|
||||
let default_template = input
|
||||
.index
|
||||
.default_template
|
||||
.to_owned()
|
||||
.unwrap_or(dir_name.into());
|
||||
|
||||
Ok(input
|
||||
.pages
|
||||
.into_iter()
|
||||
.map(|p| (p, default_template.clone()))
|
||||
.collect())
|
||||
}
|
||||
}
|
@ -0,0 +1,60 @@
|
||||
use std::{path::PathBuf, sync::Arc};
|
||||
|
||||
use async_trait::async_trait;
|
||||
use miette::{IntoDiagnostic, Result};
|
||||
use tera::{Context as TeraContext, Tera};
|
||||
use tokio::sync::Mutex;
|
||||
|
||||
use crate::{context::Context, data::load_page, pipeline::ProcessingStep};
|
||||
|
||||
use super::style::Stylesheets;
|
||||
|
||||
pub struct RenderPage {
|
||||
pub tera: Tera,
|
||||
pub styles: Arc<Mutex<Stylesheets>>,
|
||||
pub ctx: Arc<Context>,
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
impl ProcessingStep for RenderPage {
|
||||
type Input = (PathBuf, String);
|
||||
type Output = (PathBuf, String);
|
||||
|
||||
#[tracing::instrument(name = "render page", level = "trace", skip_all)]
|
||||
async fn process(&self, (page_path, default_template): Self::Input) -> Result<Self::Output> {
|
||||
let page = load_page(&page_path).await?;
|
||||
let mut context = TeraContext::new();
|
||||
let mut template_name = default_template;
|
||||
let mut style_name = template_name.to_owned();
|
||||
|
||||
match page {
|
||||
crate::data::Page::Data(data) => {
|
||||
if let Some(tmpl) = data.metadata.template {
|
||||
template_name = tmpl.to_owned();
|
||||
style_name = tmpl;
|
||||
}
|
||||
context.insert("data", &data.data);
|
||||
}
|
||||
crate::data::Page::Content(content) => context.insert("content", &content),
|
||||
}
|
||||
{
|
||||
let mut styles = self.styles.lock().await;
|
||||
let style_embed = styles
|
||||
.get_style_embed(&style_name, &self.ctx.dirs.output_dir)
|
||||
.await?;
|
||||
context.insert("style", &style_embed);
|
||||
};
|
||||
|
||||
tracing::debug!("context = {context:?}");
|
||||
|
||||
let html = self
|
||||
.tera
|
||||
.render(&format!("{template_name}.html"), &context)
|
||||
.into_diagnostic()?;
|
||||
let rel_path = page_path
|
||||
.strip_prefix(&self.ctx.dirs.content_dir)
|
||||
.into_diagnostic()?;
|
||||
|
||||
Ok((rel_path.to_owned(), html))
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue