mirror of
https://github.com/Noratrieb/website.git
synced 2026-01-14 17:05:02 +01:00
switch templating to tera
This commit is contained in:
parent
2d2c820510
commit
fa7baa71cc
8 changed files with 603 additions and 151 deletions
|
|
@ -16,8 +16,8 @@ pub fn build(config: &SlidesConfig, slides: &Path, dist: &Path) -> Result<()> {
|
|||
utils::cp_r(&slides.join("plugin"), &dist.join("plugin")).wrap_err("copying reveal.js dist")?;
|
||||
|
||||
for talk in &config.talks {
|
||||
let path = slides.join(talk.dirname());
|
||||
let dist = dist.join(talk.dirname());
|
||||
let path = slides.join(talk.dir_name());
|
||||
let dist = dist.join(talk.dir_name());
|
||||
|
||||
utils::cp_r(&path, &dist).wrap_err("copying slide data")?;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,18 +1,11 @@
|
|||
//! Root index.html and some other static stuff
|
||||
|
||||
use std::{fs, path::Path};
|
||||
use std::path::Path;
|
||||
|
||||
use askama::Template;
|
||||
use color_eyre::{eyre::WrapErr, Result};
|
||||
use rand::seq::SliceRandom;
|
||||
|
||||
use crate::{utils, SlidesConfig, Talk};
|
||||
|
||||
#[derive(askama::Template)]
|
||||
#[template(path = "slides.html")]
|
||||
struct Slides {
|
||||
talks: Vec<Talk>,
|
||||
}
|
||||
use crate::{utils, SlidesConfig};
|
||||
|
||||
pub fn build(
|
||||
rng: &mut rand::rngs::StdRng,
|
||||
|
|
@ -27,28 +20,30 @@ pub fn build(
|
|||
|
||||
let back_alley_name = format!("back-alley-{back_alley_name}.html");
|
||||
|
||||
utils::cp_content(&statics.join("root"), dist).wrap_err("copying root files")?;
|
||||
let mut context = tera::Context::new();
|
||||
|
||||
let back_alley = dist.join("back-alley.html");
|
||||
std::fs::copy(&back_alley, dist.join(&back_alley_name)).wrap_err("copying back-alley.html")?;
|
||||
fs::remove_file(back_alley).wrap_err("deleting normal back-alley.html")?;
|
||||
context.insert("back_alley_name", back_alley_name.as_str());
|
||||
context.insert("talks", &config.talks);
|
||||
|
||||
let index_html = dist.join("index.html");
|
||||
let index = fs::read_to_string(&index_html).wrap_err("reading index.html")?;
|
||||
fs::write(
|
||||
index_html,
|
||||
index.replace("back-alley.html", &back_alley_name),
|
||||
)
|
||||
.wrap_err("writing back index.html")?;
|
||||
utils::copy_fn(&statics.join("root"), dist, |content, ext, opts| {
|
||||
if ext.is_some_and(|ext| matches!(ext, "html" | "css")) {
|
||||
if opts.dest_path.ends_with("back-alley.html") {
|
||||
opts.dest_path.set_file_name(&back_alley_name);
|
||||
}
|
||||
|
||||
let slide_html = Slides {
|
||||
talks: config.talks.clone(),
|
||||
}
|
||||
.render()
|
||||
.wrap_err("rendering slide index")?;
|
||||
let content = String::from_utf8(content).wrap_err("HTML or CSS is invalid UTF-8")?;
|
||||
let mut tera = tera::Tera::default();
|
||||
tera.add_raw_template("template", &content)
|
||||
.wrap_err("parsing template")?;
|
||||
return tera
|
||||
.render("template", &context)
|
||||
.wrap_err("failed to render")
|
||||
.map(String::into_bytes);
|
||||
}
|
||||
|
||||
fs::write(dist.join("slides").join("index.html"), slide_html)
|
||||
.wrap_err("writing slides index.html")?;
|
||||
Ok(content)
|
||||
})
|
||||
.wrap_err("copying root files")?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
|||
15
src/main.rs
15
src/main.rs
|
|
@ -18,6 +18,7 @@ use color_eyre::{
|
|||
use notify::{RecursiveMode, Watcher};
|
||||
use rand::SeedableRng;
|
||||
use serde::Deserialize;
|
||||
use serde_derive::Serialize;
|
||||
use tracing::level_filters::LevelFilter;
|
||||
use tracing_subscriber::EnvFilter;
|
||||
|
||||
|
|
@ -28,20 +29,22 @@ struct Config {
|
|||
slides: SlidesConfig,
|
||||
}
|
||||
|
||||
#[derive(Deserialize)]
|
||||
#[derive(Deserialize, Serialize)]
|
||||
struct SlidesConfig {
|
||||
talks: Vec<Talk>,
|
||||
}
|
||||
|
||||
#[derive(Deserialize, Clone)]
|
||||
#[derive(Deserialize, Serialize, Clone)]
|
||||
struct Talk {
|
||||
name: String,
|
||||
date: String,
|
||||
location: String,
|
||||
#[serde(skip_deserializing)]
|
||||
dir_name: String,
|
||||
}
|
||||
|
||||
impl Talk {
|
||||
fn dirname(&self) -> String {
|
||||
fn dir_name(&self) -> String {
|
||||
format!(
|
||||
"{}-{}",
|
||||
self.date,
|
||||
|
|
@ -147,7 +150,11 @@ fn watch(root: &'static Path) -> Result<()> {
|
|||
fn build(rng: &mut rand::rngs::StdRng, root: &Path) -> Result<()> {
|
||||
let config =
|
||||
std::fs::read_to_string(root.join("config.toml")).wrap_err("reading config.toml")?;
|
||||
let config = toml::from_str::<Config>(&config).wrap_err("parsing config.toml")?;
|
||||
|
||||
let mut config = toml::from_str::<Config>(&config).wrap_err("parsing config.toml")?;
|
||||
config.slides.talks.iter_mut().for_each(|talk| {
|
||||
talk.dir_name = talk.dir_name();
|
||||
});
|
||||
|
||||
let sub_config = std::fs::read_to_string(root.join("submodules.toml"))
|
||||
.wrap_err("reading submodules.toml")?;
|
||||
|
|
|
|||
77
src/utils.rs
77
src/utils.rs
|
|
@ -2,8 +2,7 @@ use color_eyre::{
|
|||
eyre::{bail, Context},
|
||||
Result,
|
||||
};
|
||||
use fs_extra::dir::CopyOptions;
|
||||
use std::{path::Path, process::Command};
|
||||
use std::{fs, io, os::unix::ffi::OsStrExt, path::{Path, PathBuf}, process::Command};
|
||||
|
||||
pub fn run_process(cmd: &mut Command) -> Result<String> {
|
||||
fn run_process_inner(cmd: &mut Command) -> Result<String> {
|
||||
|
|
@ -41,30 +40,58 @@ pub fn create_dir_if_not_exist(p: &Path) -> Result<()> {
|
|||
}
|
||||
|
||||
pub fn cp_r(from: &Path, to: &Path) -> Result<()> {
|
||||
fs_extra::copy_items(
|
||||
&[from],
|
||||
to,
|
||||
&CopyOptions {
|
||||
overwrite: true,
|
||||
copy_inside: true,
|
||||
..CopyOptions::default()
|
||||
},
|
||||
)
|
||||
.wrap_err(format!("copying to {}", to.display()))?;
|
||||
Ok(())
|
||||
copy_fn(from, to, |content, _, _| Ok(content))
|
||||
}
|
||||
|
||||
pub fn cp_content(from: &Path, to: &Path) -> Result<()> {
|
||||
fs_extra::dir::copy(
|
||||
from,
|
||||
to,
|
||||
&CopyOptions {
|
||||
overwrite: true,
|
||||
copy_inside: true,
|
||||
content_only: true,
|
||||
..CopyOptions::default()
|
||||
},
|
||||
)
|
||||
.wrap_err(format!("copying to {}", to.display()))?;
|
||||
pub struct CopyOpts {
|
||||
pub dest_path: PathBuf,
|
||||
}
|
||||
|
||||
pub fn copy_fn(
|
||||
from: &Path,
|
||||
to: &Path,
|
||||
mut map: impl FnMut(Vec<u8>, Option<&str>, &mut CopyOpts) -> Result<Vec<u8>>,
|
||||
) -> Result<()> {
|
||||
let mut worklist = vec![from.to_owned()];
|
||||
|
||||
while let Some(ref item) = worklist.pop() {
|
||||
let mut process = || -> Result<()> {
|
||||
let meta = fs::metadata(item).wrap_err("getting metadata")?;
|
||||
let relative = item.strip_prefix(from).wrap_err("subpath stripping")?;
|
||||
let dest = to.join(relative);
|
||||
|
||||
if meta.is_dir() {
|
||||
let items = fs::read_dir(item).wrap_err("read_dir")?;
|
||||
for item in items {
|
||||
let item = item.wrap_err("entry")?;
|
||||
worklist.push(item.path());
|
||||
}
|
||||
|
||||
match fs::create_dir_all(&dest) {
|
||||
Ok(()) => {}
|
||||
Err(e) if e.kind() == io::ErrorKind::AlreadyExists => {}
|
||||
e => return e.wrap_err_with(|| format!("creating {}", dest.display())),
|
||||
}
|
||||
} else {
|
||||
let content = fs::read(item).wrap_err("reading file")?;
|
||||
let ext = match item.extension() {
|
||||
Some(ext) => Some(
|
||||
std::str::from_utf8(ext.as_bytes())
|
||||
.wrap_err("file extension is invalid UTF-8")?,
|
||||
),
|
||||
None => None,
|
||||
};
|
||||
let mut opts = CopyOpts {
|
||||
dest_path: dest.clone(),
|
||||
};
|
||||
let result = map(content, ext, &mut opts).wrap_err("applying mapping")?;
|
||||
fs::write(opts.dest_path, result)
|
||||
.wrap_err_with(|| format!("creating {}", dest.display()))?;
|
||||
}
|
||||
Ok(())
|
||||
};
|
||||
process().wrap_err_with(|| format!("copying {}", item.display()))?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue