[][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, statement is empty
 --> examples/files/document.md:3:3
  |
3 | {{}}
  | --^

Templates

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)?;

To load files from disc requires the fs feature which is enabled by default; first load some files and assign them to a templates collection which is used to create the registry:

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

Render

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(
    "dynamic-template.md",
    "# {{title}}",
    json!({"title": "Document Title"}))?;
println!("{}", result);

Lint

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}}")?;

Escape

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;
registry.set_escape(escape::noop);

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
registry.set_strict(true);

Helpers

Helper functions are what 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.

Re-exports

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

Modules

error

Error types.

escape

Escape function trait and default functions.

helper

Helper trait and types for the default set of helpers.

lexer

Iterator for grammar tokens.

output

Trait and type for rendering to destinations.

parser

Convert the lexer token stream to AST nodes.

registry

Primary entry point for compiling and rendering templates.

render

Render a template to output using the data.

template

Templates add rendering capability to nodes.

trim

Types that control how whitespace is trimmed.

Type Definitions

RenderResult

Result type returned when rendering templates.

Result

Result type returned by the registry.

SyntaxResult

Result type returned when compiling templates.