init
This commit is contained in:
+92
@@ -0,0 +1,92 @@
|
||||
//! minijinja environment: the RainTPL templates of Movim were ported to Jinja
|
||||
//! syntax under `templates/`. Helpers available in templates:
|
||||
//!
|
||||
//! * `__("key", args...)` translation (uses the `lang` variable of the context)
|
||||
//! * `route("page", params...)` URL of a page
|
||||
//! * filters: `cleanupId`, `echapJS`, `stringToColor`, `slugify`, `json`,
|
||||
//! `addEmojis`, `implodeCsv`, `mimeToIcon`, `mimeToLabel`, `firstLetter`
|
||||
|
||||
use minijinja::{value::Rest, Environment, State, Value};
|
||||
use std::path::Path;
|
||||
|
||||
use crate::{i18n, utils};
|
||||
|
||||
pub fn environment(dir: &Path) -> Environment<'static> {
|
||||
let mut env = Environment::new();
|
||||
env.set_loader(minijinja::path_loader(dir));
|
||||
env.set_auto_escape_callback(|name| {
|
||||
if name.ends_with(".html") || name.ends_with(".tpl") {
|
||||
minijinja::AutoEscape::Html
|
||||
} else {
|
||||
minijinja::AutoEscape::None
|
||||
}
|
||||
});
|
||||
env.set_trim_blocks(true);
|
||||
env.set_lstrip_blocks(true);
|
||||
// Like PHP's htmlspecialchars: '/' is not escaped, so URLs stay usable in scripts
|
||||
env.set_formatter(|out, state, value| {
|
||||
if state.auto_escape() == minijinja::AutoEscape::None || value.is_safe() {
|
||||
return minijinja::escape_formatter(out, state, value);
|
||||
}
|
||||
if value.is_none() || value.is_undefined() {
|
||||
return Ok(());
|
||||
}
|
||||
let s = match value.as_str() {
|
||||
Some(s) => std::borrow::Cow::Borrowed(s),
|
||||
None => std::borrow::Cow::Owned(value.to_string()),
|
||||
};
|
||||
out.write_str(&html_escape::encode_quoted_attribute(&s))
|
||||
.map_err(|_| minijinja::Error::new(minijinja::ErrorKind::WriteFailure, "write failed"))
|
||||
});
|
||||
|
||||
env.add_function("__", translate);
|
||||
env.add_function("route", route);
|
||||
|
||||
env.add_filter("cleanupId", |s: String| utils::cleanup_id(&s));
|
||||
env.add_filter("cleanupIdHash", |s: String| utils::cleanup_id_hash(&s));
|
||||
env.add_filter("echapJS", |s: String| utils::echap_js(&s));
|
||||
env.add_filter("stringToColor", |s: Option<String>| utils::string_to_color(s.as_deref().unwrap_or("")).to_string());
|
||||
env.add_filter("slugify", |s: String| utils::slugify(&s));
|
||||
env.add_filter("firstLetter", |s: String| utils::first_letter_capitalize(&s, false));
|
||||
env.add_filter("mimeToIcon", |s: Option<String>| utils::mime_to_icon(s.as_deref().unwrap_or("")).to_string());
|
||||
env.add_filter("mimeToLabel", |s: Option<String>| utils::mime_to_label(s.as_deref().unwrap_or("")));
|
||||
env.add_filter("implodeCsv", |v: Vec<String>| v.join(", "));
|
||||
env.add_filter("json", |v: Value| serde_json::to_string(&v).unwrap_or_else(|_| "null".into()));
|
||||
env.add_filter("addEmojis", add_emojis);
|
||||
|
||||
env
|
||||
}
|
||||
|
||||
fn translate(state: &State, key: String, args: Rest<Value>) -> String {
|
||||
let lang = state
|
||||
.lookup("lang")
|
||||
.and_then(|v| v.as_str().map(String::from))
|
||||
.unwrap_or_else(|| "en".into());
|
||||
let args: Vec<String> = args
|
||||
.iter()
|
||||
.map(|a| a.as_str().map(String::from).unwrap_or_else(|| a.to_string()))
|
||||
.collect();
|
||||
i18n::get().translate(&lang, &key, &args)
|
||||
}
|
||||
|
||||
fn route(state: &State, page: String, params: Rest<Value>) -> String {
|
||||
let base = state
|
||||
.lookup("base_uri")
|
||||
.and_then(|v| v.as_str().map(String::from))
|
||||
.unwrap_or_else(|| "/".into());
|
||||
let params: Vec<String> = params
|
||||
.iter()
|
||||
.filter(|v| !v.is_none() && !v.is_undefined())
|
||||
.map(|a| a.as_str().map(String::from).unwrap_or_else(|| a.to_string()))
|
||||
.collect();
|
||||
crate::app::route_with_base(&base, &page, ¶ms)
|
||||
}
|
||||
|
||||
fn add_emojis(state: &State, s: String, no_title: Option<bool>) -> Value {
|
||||
let base = state
|
||||
.lookup("base_uri")
|
||||
.and_then(|v| v.as_str().map(String::from))
|
||||
.unwrap_or_else(|| "/".into());
|
||||
let escaped = utils::html_escape(&s);
|
||||
Value::from_safe_string(utils::replace_emojis(&escaped, &base, no_title.unwrap_or(false)).html)
|
||||
}
|
||||
Reference in New Issue
Block a user