upon
A simple, powerful template engine.
Features
Syntax
- Expressions:
{{ user.name }} - Conditionals:
{% if user.enabled %} ... {% endif %} - Loops:
{% for user in users %} ... {% endfor %} - Configurable delimiters:
<? user.name ?>,(( if user.enabled )) - Arbitrary filter functions:
{{ user.name | replace: "\t", " " }}
Engine
- Clear and well documented API
- Customizable value formatters:
{{ user.name | escape_html }} - Render to a
Stringor anystd::io::Writeimplementor - Render using any
serdeserializable values - Convenient macro for quick rendering:
upon::value!{ name: "John", age: 42 } - Minimal dependencies and decent runtime performance
Getting started
Your entry point is the Engine struct. The engine stores the syntax
config, filter functions, and compiled templates. Generally, you only need
to construct one engine during the lifetime of a program.
let engine = new;
Next, .add_template is used to compile and store a
template in the engine.
engine.add_template?;
Finally, the template is rendered by fetching it using
.get_template and calling
.render.
let template = engine.get_template.unwrap;
let result = template.render?;
assert_eq!;
If the lifetime of the template source is shorter than the engine lifetime
or you don’t need to store the compiled template then you can also use the
.compile function to return the template directly.
let template = engine.compile?;
let result = template.render?;
assert_eq!;
Examples
Render using structured data
Here is the same example as above except using derived data.
let ctx = Context ;
let result = new
.compile?
.render?;
assert_eq!;
Transform data using filters
Data can be transformed using registered filters.
let mut engine = new;
engine.add_filter;
let result = engine
.compile?
.render?;
assert_eq!;
See the Filter trait documentation for more information on filters.
Render a template using custom syntax
The template syntax can be set by constructing an engine using
Engine::with_syntax.
let syntax = builder.expr.block.build;
let result = with_syntax
.compile?
.render?;
assert_eq!;
Render a template to an impl io::Write
You can render a template directly to a buffer implementing io::Write
by using .render_to_writer().
use io;
let stdout = new;
new
.compile?
.render_to_writer?;
Add and use a custom formatter
You can add your own custom formatter’s or even override the default
formatter using Engine::set_default_formatter. The following example
shows how you could add debug formatter to the engine.
use Write;
use ;
let mut engine = new;
engine.add_formatter;
let result = engine
.compile?
.render?;
assert_eq!;
Benchmarks
The following shows a violin plot of the benchmark results for upon compared
to the following template rendering engines.
Obviously, each of these engines has a completely different feature set so this just compares the performance of some of the features that they share.
Host
- MacBook Pro (14-inch, 2021)
- Chipset: Apple M1 Pro
- Memory: 16 GB
License
Licensed under either of
- Apache License, Version 2.0 (LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0)
- MIT license (LICENSE-MIT or http://opensource.org/licenses/MIT)
at your option.