Incrust is a template engine inspired by Jinja2 and written in Rust.
In fact it is a Jinja2, Django, Twig, Swig, Liquid (and probably others) template engines constellation, which uses similar methodologies.
The implementation is at a very early stage and the API is a subject of changes.
Note that Incrust currently requires the nightly version of the Rust compiler.
Incrust is available on crates.io and can be included in your Cargo enabled project like this:
[dependencies]
incrust = "=0.2.15"
For ease of use hashmaps you may use the maplit
Then you need to setup your environment:
#[macro_use]
extern crate maplit;
extern crate incrust;
use incrust::ex;
fn create_env() -> Incrust {
use incrust::{Incrust, FilesystemLoader};
let mut instance = Incrust::default();
instance.loaders.push(FilesystemLoader::new("./assets/tpl"));
instance
}
fn main() {
let incrust = create_env();
let args = hashmap!{ "name".into() => ex("World") };
incrust.render("hello", &args).unwrap();
}
Though Incrust has smart loaders, it may be used just as advanced formatter to render directly from string template
let args = hashmap!{ "name".into() => ex("World") };
incrust.render_text("Hello, {{ name | e }}!", &args).unwrap();
// or with prepared template
let hello = incrust.parse("Hello, {{ name | e }}!");
incrust.render_parsed(&hello, &args).unwrap();
<p>Visible {# partially #} paragraph</p>
<p>Visible paragraph</p>
Example: {% raw %}{{ mustaches }}{% endraw %}
Example: {{ mustaches }}
Braces: {{ "{{" }}
Pi: {{ 3.1415926 }}
Braces: {{
Pi: 3.1415926
let args = hashmap!{ "title".into() => ex("<Cats & Dogs>") };
<h1>{{ title | escape }}</h1>
<h1><Cats & Dogs></h1>
let args = hashmap!{
"what".into() => ex("Hello"),
"who".into() => ex("World")
};
Say: "{{ what + ", " + who }}!"
Say: "Hello, World!"
let args = hashmap!{
"alpha".into() => ex(6isize),
"omega".into() => ex(7f64)
};
The answer is {{ alpha * omega }}
The answer is 42
Amount: {{ amount and ("" + amount + " pcs") or "-" }}
assert_eq!("Amount: 6 pcs", incrust.render("tpl", &hashmap!{ "amount".into() => ex(6isize) }).unwrap());
assert_eq!("Amount: -", incrust.render("tpl", &hashmap!{ "amount".into() => ex(0isize) }).unwrap());
String {% if "" %}has chars{% else %}is empty{% endif %}
It's {% if False %}false{% elif True %}true{% endif %}
String is empty
It's true
let args = hashmap!{ "fruits".into() => ex(vec![ex("Orange"), ex("Apple"), ex("Banana")]) };
<ul>
{%- for fruit in fruits %}
<li>{{ loop.index }}. {{ fruit | e }}</li>
{%- endfor %}
</ul>
<ul>
<li>1. Orange</li>
<li>2. Apple</li>
<li>3. Banana</li>
</ul>
let args = hashmap!{ "parent_layout".into() => ex("default") };
incrust.render("template", &args).unwrap()
default.tpl
<body>
<h1>{% block title %}Default title{% endblock %}</h1>
<main>
{%- block body %}
<p>Default body<p>
{%- endblock %}
</main>
</body>
template.tpl
{% extends parent_layout %}
{% block title -%}
New title
{%- endblock %}
Output
<body>
<h1>New title</h1>
<main>
<p>Default body<p>
</main>
</body>
let args = hashmap!{ "menu".into() => ex("default_menu") };
assert_eq!(expected, incrust.render("tpl", &args).unwrap());
default_menu.tpl
<ul>
<li><a href="/">Home</a></li>
<li><a href="/about">About Us</a></li>
</ul>
template.tpl
<nav>
{%- include menu -%}
</nav>
<h1>Body</h1>
Output
<nav>
<ul>
<li><a href="/">Home</a></li>
<li><a href="/about">About Us</a></li>
</ul>
</nav>
<h1>Body</h1>
If you are looking for a template engine for your project, you may also look at these projects.
- cobalt-org/liquid-rust Liquid templating for Rust
- colin-kiegel/twig-rust Rust port of the twig-php template library
- Nercury/twig-rs The Twig templating engine for Rust (work in progress)
- Keats/tera A template engine for Rust
- djc/askama Type-safe, compiled Jinja-like templates for Rust
- sunng87/handlebars-rust Rust templating with Handlebars
- nickel-org/rust-mustache Mustache template library for rust
This project is licensed under either of
- Apache License, Version 2.0 (LICENSE-APACHE or https://www.apache.org/licenses/LICENSE-2.0)
- MIT license (LICENSE-MIT or https://opensource.org/licenses/MIT) at your option.
Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.