Crates.io | wearte_derive |
lib.rs | wearte_derive |
version | 0.0.2 |
source | src |
created_at | 2019-02-24 18:27:24.479914 |
updated_at | 2019-03-05 23:50:58.332747 |
description | Procedural macro package for wearte |
homepage | https://github.com/dgriffen/wearte |
repository | https://github.com/dgriffen/wearte |
max_upload_size | |
id | 116931 |
size | 92,709 |
wearte stands for Wow Even Another Rust Template Engine, it is one of the fastest rust template engines. It uses a Handlebars-like syntax.
This crate was forked from yarte with fixes for the snarky licensing issues. yarte itself is a direct descendant of askama. You can find copies of their licenses in LICENSE-MIT.
There are many templates engines based on mustache or/and handlebars,
I have not known any that derives the compilation of templates to the compiler (like askama).
By deriving this task from another process, we can optimize the instructions
generated with our own tools or those of third parties such as LLVM.
This is impossible in other cases creating a bottleneck in our web servers
that reaches milliseconds. Because of this, wearte
puts the template in priority
by allocating its needs statically. Thus, we write faster than the macro write!
,
easy parallelism and with simd in its default html escape.
In conclusion a derive is used to be the fastest and simplest.
Add wearte dependency to your Cargo.toml file:
[dependencies]
wearte = "0.0.1"
In order to use a struct in the template you will have to call
the procedural macro Template
. For example, in the following
code we are going to use struct CardTemplate
, to then
define s
as a CardTemplate
with content.
use wearte::Template;
#[derive(Template)]
#[template(path = "hello.html")]
struct CardTemplate<'a> {
title: &'a str,
body: &'a str,
}
let template = CardTemplate {
title: "My Title",
body: "My Body",
};
Now that our struct is defined lets use it in a template. wearte templates look like regular text, with embedded wearte expressions.
Let's say file hello.html
looks like this:
<div class="entry">
<h1>{{title}}</h1>
<div class="body">
{{body}}
</div>
</div>
And call your template for allocate the result in String
and return
it wrapped with wearte::Result
template.call()
<div class="entry">
<h1> My Title </h1>
<div class="body">
My Body
</div>
</div>
wearte uses opening characters {{
and closing
characters }}
to parse the inside depending
on the feature used. Most of the features are
defined by Handlebars such as paths, comments,
html, helpers and partials. Others such as
adding rust code to a template, are obviously
defined by wearte.
// precompile your template
#[derive(Template)]
#[template(source = "Hello, {{ name }}!", ext = "txt")]
struct HelloTemplate<'a> {
name: &'a str,
}
assert_eq!(
"Hello, world!",
HelloTemplate { name: "world" }.call().unwrap() // then call it.
);
{{! Comments can be written }}
{{!-- in two different ways --}}
wearte HTML-escapes values returned by a {{expression}}
.
If you don't want wearte to escape a value, use the
"triple-stash", {{{
. For example having the following
struct:
let t = CardTemplate {
title: "All about <p> Tags",
body: "<p>This is a post about <p> tags</p>"
};
and the following template:
<div class="entry">
<h1>{{title}}</h1>
<div class="body">
{{{body}}}
</div>
</div>
will result in:
<div class="entry">
<h1>All About <p> Tags</h1>
<div class="body">
<p>This is a post about <p> tags</p>
</div>
</div>
{{#if isLiked}}
Liked!
{{else if isSeen}}
Seen!
{{else}}
Sorry ...
{{\if}}
let author = Author {
name: "J. R. R. Tolkien"
};
{{#with author}}
<p>{{name}}</p>
{{/with}}
{{#each into_iter}}
{{#- if first || last -}}
{{ index }}
{{- else -}}
{{ index0 }}
{{/-if }} {{ key }}
{{\-each}}
{{#unless isAdministrator-}}
Ask administrator.
{{\-unless}}
{{#log }} {{log\}}
{{#lookup }} {{\lookup}}
In order to create a user-defined helper ..
Booleans, integers, floating points, ... are not escaped for better performance. It is recomended to use these types if possible.
Partials can be used to generate faster code using a pre defined functions.
{{> path/to/file }}
wearte provides you with the possibility to use raw rust code within the HTML files. This is limited, but most of essential syntax is supported.
{{#with getUser(id)?-}}
Hello, {{#if isAdmin || isDev }}Mr. {{\if}}{{ user }}
{{/-with}}
Hello, {{#each conditions}}
{{#-if let Some(check) = cond }}
{{#-if check }}
{{ let cond = if check { "&foo" } else { "&"} }}
{{
if check {
cond
} else if let Some(cond) = key.cond {
if cond {
"1"
} else {
"2"
}
} else {
"for"
}
}}
{{- else if let Some(_) = cond }}
{{- else if let Some(cond) = key.check }}
{{#-if cond -}}
baa
{{/-if }}
{{- else -}}
{{ cond.is_some() }}
{{/-if-}}
{{ cond.is_some() && true }}
{{-else if let Some(cond) = check }}
{{#-if cond -}}
bar
{{/-if}}
{{- else -}}
None
{{/-if
}}{{/each}}!
{{ let mut a = name.chars() }}
{{
let b: String = loop {
if a.next().is_none() && true {
let mut a = name.repeat(1);
a.push('!');
break a.repeat(2);
} else {
continue;
}
}
}}
{{ b }}
{{ let doubled = a.iter().map(|x| x * 2).collect::<Vec<_>>() }}
{{ let doubled: Vec<usize> = a.iter().map(|x| x * 2).collect() }}
{{#each doubled -}}
{{ key + 1 }}
{{/-each}}
>|
filters on fmt::Formatter