[][src]Crate bracket

Bracket is a fast and correct implementation of the Handlebars general purpose template engine.

It is designed to keep allocations to a minimum by using pointers and string slices into the underlying template wherever possible.

It detects cyclic partials and helper calls and returns an error rather than overflow the stack so should be robust when used with untrusted input.

The lexer generates a stream of tokens which are consumed by a parser that transforms them into AST nodes; these nodes can then be stored as compiled templates or passed directly to a renderer.

The goal is to be 100% compatible with the Javascript handlebars implementation; if you notice a discrepancy please report it as a bug.

The main public API is accessed using a Registry which can be used for compiling, rendering, registering partials and configuring helpers.

Errors generated during compilation are of the SyntaxError type and implement the Debug trait which will include the source code that generated the error.

This example is not tested
Syntax error, expecting identifier
 --> examples/files/document.md:3:3
3 | {{}}
  | --^


Templates must always be named so that useful error messages can be generated; if a name is not available the value of unknown will be used as the template name.

Use the registry to compile a template:

This example is not tested
let registry = Registry::new();
let template = registry.parse("file-name.md", "{{foo}}")?;

If you are extracting a template from a larger document use ParserOptions to set a line and byte offset:

This example is not tested
let registry = Registry::new();
let options = ParserOptions::new(String::from("module.rs"), 12, 2048);
let template = registry.compile("{{foo}}", options)?;

Use insert() to compile and add a template to the registry:

This example is not tested
registry.insert("dynamic", "{{title}}")?;

To load files from disc requires the fs feature which is enabled by default; once the file contents are loaded they are compiled and added to the registry:

This example is not tested
let mut registry = Registry::new();
// Template name is derived from the file stem
registry.read_dir(PathBuf::from("partials/"), "hbs")?;
// Explicit template name
registry.add("info", PathBuf::from("documents/info.md"))?;
// Template name is the file path


If a template has already been registered it can be rendered by name:

This example is not tested
let result = registry.render("info", json!({"title": "Document Title"}))?;
println!("{}", result);

For dynamic templates use the once() function to render a string template directly:

This example is not tested
let result = registry.once(
    "# {{title}}",
    json!({"title": "Document Title"}))?;
println!("{}", result);


Sometimes it is useful to check whether a template is well-formed. The lint function will return a list of syntax errors:

This example is not tested
let errors = registry.lint("file-name.md", "{{.bad.path}}")?;


By default templates are escaped for HTML output; you can call set_escape() on a registry with an escape function to change this behaviour.

For example to disable escaping:

This example is not tested
use bracket::escape;

Strict Mode

By default the handlebars behaviour for variable interpolation is a noop when a variable cannot be found; to always error when a variable or helper is missing enable strict mode:

This example is not tested


Helper functions make handlebars a versatile template engine; all helpers are enabled by default but can be disabled via feature flags if you need to.

By default all the built-in helpers are enabled:

  • log Print log messages.
  • lookup Lookup a field of an object or array.
  • #if Conditional block helper.
  • #unless Negated conditional block helper.
  • #each Iterate arrays and objects.
  • #with Set the block context scope.

Some useful extra helpers are also enabled by default:

  • json Convert values to JSON strings.
  • and Logical boolean AND operation.
  • or Logical boolean OR operation.
  • not Logical boolean NOT operation.

Numerical comparison helpers:

  • eq Test for equality.
  • ne Test for inequality.
  • lt Test for less than.
  • gt Test for greater than.
  • lte Test for less than or equal to.
  • gte Test for greater than or equal to.

To add a helper to the registry use helpers_mut():

This example is not tested
registry.helpers_mut().insert("custom", Box::new(CustomHelper {}));

Then you can call it like any other helper:

This example is not tested
{{custom "Hello world!" param=true}}

See the Helper Module to learn more about creating your own helpers.

The links feature which is enabled by default parses wiki-style links into a Link node. When this feature is enabled the renderer will look for a link handler and it will be invoked with the link href, label and title as arguments.

Note that a link helper is a standard helper implementation but is registered using an event handler as it should not be invoked directly via a template:

This example is not tested
registry.handlers_mut().link = Some(Box::new(LinkHelper {}));

Such that a wiki-style link like this one [[https://example.com|Example Website]] would call the link helper with the first argument as the website URL and the second argument as the label (Example Website).

After the label an optional title can be specified using another pipe delimiter: [[/path/to/page|Link Label|Alternative Title]] this is passed as the third argument to the link helper.

If this feature is disabled or no handler is defined the link is rendered to the output as text.

Links do not accept new lines; to include a new line, vertical pipe or right square bracket it must be preceeded by a backslash, eg: \n, \| or \].

To ignore a wiki-style link from processing prefix it with a backslash \[[Plain Text]] and it will be rendered as text without the backslash.


Support for helperMissing and blockHelperMissing handlers can be enabled using the registry handlers. The handlers should be regular helper implementations:

This example is not tested
registry.handlers_mut().helper_missing = Some(Box::new(HelperMissing {}));
registry.handlers_mut().block_helper_missing = Some(Box::new(BlockHelperMissing {}));

When a block helper missing handler is invoked it also has access to the underlying property().

The rules for when these handlers are invoked are described in the Handlebars Hooks documentation.


pub use error::Error;
pub use registry::Registry;
pub use template::Template;
pub use escape::EscapeFn;



Error types.


Escape function trait and default functions.


Helper trait and types for the default set of helpers.


Iterator for grammar tokens.


Trait and type for rendering to destinations.


Convert the lexer token stream to AST nodes.


Primary entry point for compiling and rendering templates.


Render a template to output using the data.


Templates add rendering capability to nodes.


Types that control how whitespace is trimmed.

Type Definitions


Result type returned when rendering templates.


Result type returned by the registry.


Result type returned when compiling templates.