extern crate handlebars; #[macro_use] extern crate serde_json; use handlebars::Handlebars; fn main() -> Result<(), Box<Error>> { let mut reg = Handlebars::new(); // render without register println!( "{}", reg.render_template("Hello {{name}}", &json!({"name": "foo"}))? ); // register template using given name reg.register_template_string("tpl_1", "Good afternoon, {{name}}")?; println!("{}", reg.render("tpl_1", &json!({"name": "foo"}))?); }
If you are not familiar with handlebars language syntax, it is recommended to walk through their introduction first.
Check render
example in the source tree. The example shows you how to:
Handlebars
registry and register the template from files;HelperDef
, and register it;Run cargo run --example render
to see results. (or RUST_LOG=handlebars=info cargo run --example render
for logging output).
Checkout examples/
for more concrete demos of current API.
Handlebars will track Rust nightly and stable channel. When dropping support for previous stable versions, I will bump minor version and clarify in CHANGELOG.
Handlebars version range | Minimum Rust version |
---|---|
~1.1.0 | 1.30 |
~1.0.0 | 1.23 |
Change log is available in the source tree named as CHANGELOG.md
.
Any contribution to this library is welcomed. To get started into development, I have several Help Wanted issue, with difficult level labeled. When running into any problem, feel free to contact me on github.
I'm always looking for maintainers to work together on this library, also let me know (via email or anywhere in the issue tracker) if you want to join.
I'm now accepting donation on liberapay, if you find my work helpful and want to keep it going.
Handlebars is a real-world templating system that you can use to build your application without pain.
This library doesn‘t attempt to use some macro magic to allow you to write your template within your rust code. I admit that it’s fun to do that but it doesn't fit real-world use case.
Only essential control directive if
and each
were built-in. This prevents you to put too much application logic into your template.
You can write your own helper with Rust! It can be a block helper or inline helper. Put your logic into the helper and don't repeat yourself.
A helper can be as a simple as a Rust function like:
handlebars_helper!(hex: |v: i64| format!("0x{:x}", v)); /// register the helper handlebars.register_helper("hex", Box::new(hex));
And using it in your template:
{{hex 16}}
Every time I look into a templating system, I will investigate its support for template inheritance.
Template include is not sufficient for template reuse. In most case you will need a skeleton of page as parent (header, footer, etc.), and embed you page into this parent.
You can find a real example for template inheritance in examples/partials.rs
, and templates used by this file.
Handlebars 1.0 can be used in WebAssembly projects with directory source feature disabled. Adding handlebars to your project like this:
handlebars = { version = "1", features = ["no_dir_source"], default-features = false }
Handlebars, the language designed to work with JavaScript, has no strict restriction on accessing non-existed fields or index. It generates empty string for such case. However, in Rust we want a little bit strict sometime.
By enabling strict_mode
on handlebars:
handlebars.set_strict_mode(true);
You will get a RenderError
when accessing field that not exists.
#each
and #if
for same behavior.Serializable
on serde. We don't actually serialize data into JSON string or similar. However, we use JSON data type system in template render process.~
{{(foo bar)}}
a.b.[0]
and a.b.[c]
{{{{raw-helper}}}}...{{{{/raw-helper}}}}
if
/each
instead)Feel free to report an issue if you find something broken. We aren‘t going to implement all features of handlebars-js, but we should have a workaround for cases we don’t support.
Add your project to our adopters.
This library (handlebars-rust) is open sourced under MIT License.