Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Preprocessor #394

Draft
wants to merge 2 commits into
base: master
Choose a base branch
from
Draft
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
33 changes: 33 additions & 0 deletions src/registry.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,11 @@ use crate::helpers::scripting::ScriptHelper;
/// parameters (and because traits cannot be aliased using `type`).
pub type EscapeFn = Box<dyn Fn(&str) -> String + Send + Sync>;

/// A template preprocess function that takes template string and its name (if given)
/// as input and returns processed template string. The processed string will be registered
/// into registry instead of the original.
pub type PreprocessFn = Box<dyn Fn(&str, Option<&str>) -> String>;

/// The default *escape fn* replaces the characters `&"<>`
/// with the equivalent html / xml entities.
pub fn html_escape(data: &str) -> String {
Expand All @@ -56,6 +61,7 @@ pub struct Registry<'reg> {
helpers: HashMap<String, Box<dyn HelperDef + Send + Sync + 'reg>>,
decorators: HashMap<String, Box<dyn DecoratorDef + Send + Sync + 'reg>>,
escape_fn: EscapeFn,
preprocess_fn: Option<PreprocessFn>,
source_map: bool,
strict_mode: bool,
#[cfg(feature = "script_helper")]
Expand Down Expand Up @@ -106,6 +112,7 @@ impl<'reg> Registry<'reg> {
helpers: HashMap::new(),
decorators: HashMap::new(),
escape_fn: Box::new(html_escape),
preprocess_fn: None,
source_map: true,
strict_mode: false,
#[cfg(feature = "script_helper")]
Expand Down Expand Up @@ -190,6 +197,7 @@ impl<'reg> Registry<'reg> {
where
S: AsRef<str>,
{
// TODO: preprocess
let template = Template::compile_with_name(tpl_str, name.to_owned(), self.source_map)?;
self.register_template(name, template);
Ok(())
Expand Down Expand Up @@ -382,6 +390,29 @@ impl<'reg> Registry<'reg> {
&*self.escape_fn
}

/// Register a *preprocess fn* to transform all template string.
///
/// The template content and its name (if given) is provided for this function.
/// The function has to return the transformed content which will be registered
/// into handlebars registry eventually.
pub fn register_preprocess_fn<F: 'static + Fn(&str, Option<&str>) -> String + Send + Sync>(
&mut self,
preprocess_fn: F,
) {
self.preprocess_fn = Some(Box::new(preprocess_fn));
}

/// Remove the template preprocessor. Note that this won't affect template that
/// has been registered.
pub fn unregister_preprocess_fn(&mut self) {
self.preprocess_fn = None;
}

/// Get a reference to *preprocess fn*
pub fn get_preprocess_fn(&self) -> Option<&dyn Fn(&str, Option<&str>) -> String> {
self.preprocess_fn.as_ref().map(|b| b.as_ref())
}

/// Return `true` if a template is registered for the given name
pub fn has_template(&self, name: &str) -> bool {
self.get_template(name).is_some()
Expand Down Expand Up @@ -488,6 +519,7 @@ impl<'reg> Registry<'reg> {
template_string: &str,
ctx: &Context,
) -> Result<String, TemplateRenderError> {
// TODO: preprocess
let tpl = Template::compile2(template_string, self.source_map)?;

let mut out = StringOutput::new();
Expand All @@ -511,6 +543,7 @@ impl<'reg> Registry<'reg> {
T: Serialize,
W: Write,
{
// TODO: preprocess
let tpl = Template::compile2(template_string, self.source_map)?;
let ctx = Context::wraps(data)?;
let mut render_context = RenderContext::new(None);
Expand Down