pub trait HelperDef {
    fn call_inner<'reg, 'rc>(
        &Helper<'reg, 'rc>,
        &'reg Registry<'reg>,
        &'rc Context,
        &mut RenderContext<'reg, 'rc>
    ) -> Result<ScopedJson<'reg, 'rc>, RenderError>
        'reg: 'rc
, { ... } fn call<'reg, 'rc>(
        h: &Helper<'reg, 'rc>,
        r: &'reg Registry<'reg>,
        ctx: &'rc Context,
        rc: &mut RenderContext<'reg, 'rc>,
        out: &mut dyn Output
    ) -> Result<(), RenderError>
        'reg: 'rc
, { ... } }
Expand description

Helper Definition

Implement HelperDef to create custom helpers. You can retrieve useful information from these arguments.

  • &Helper: current helper template information, contains name, params, hashes and nested template
  • &Registry: the global registry, you can find templates by name from registry
  • &Context: the whole data to render, in most case you can use data from Helper
  • &mut RenderContext: you can access data or modify variables (starts with @)/partials in render context, for example, @index of #each. See its document for detail.
  • &mut dyn Output: where you write output to

By default, you can use a bare function as a helper definition because we have supported unboxed_closure. If you have stateful or configurable helper, you can create a struct to implement HelperDef.

Define an inline helper

use handlebars::*;

fn upper(h: &Helper<'_, '_>, _: &Handlebars<'_>, _: &Context, rc:
&mut RenderContext<'_, '_>, out: &mut dyn Output)
    -> HelperResult {
   // get parameter from helper or throw an error
   let param = h.param(0).and_then(|v| v.value().as_str()).unwrap_or("");

Define block helper

Block helper is like #if or #each which has a inner template and an optional inverse template (the template in else branch). You can access the inner template by helper.template() and helper.inverse(). In most cases you will just call render on it.

use handlebars::*;

fn dummy_block<'reg, 'rc>(
    h: &Helper<'reg, 'rc>,
    r: &'reg Handlebars<'reg>,
    ctx: &'rc Context,
    rc: &mut RenderContext<'reg, 'rc>,
    out: &mut dyn Output,
) -> HelperResult {
        .map(|t| t.render(r, ctx, rc, out))

Define helper function using macro

In most cases you just need some simple function to call from templates. We have a handlebars_helper! macro to simplify the job.

use handlebars::*;

handlebars_helper!(plus: |x: i64, y: i64| x + y);

let mut hbs = Handlebars::new();
hbs.register_helper("plus", Box::new(plus));

Provided Methods

A simplified api to define helper

To implement your own call_inner, you will return a new ScopedJson which has a JSON value computed from current context.

Calling from subexpression

When calling the helper as a subexpression, the value and its type can be received by upper level helpers.

Note that the value can be json!(null) which is treated as false in helpers like if and rendered as empty string.

A complex version of helper interface.

This function offers Output, which you can write custom string into and render child template. Helpers like if and each are implemented with this. Because the data written into Output are typically without type information. So helpers defined by this function are not composable.

Calling from subexpression

Although helpers defined by this are not composable, when called from subexpression, handlebars tries to parse the string output as JSON to re-build its type. This can be buggy with numrical and other literal values. So it is not recommended to use these helpers in subexpression.


implement HelperDef for bare function so we can use function as helper