Handlebars templating
Handlebars
Quick start - unregistered template
-
Handlebars
-
render_template
-
json
-
Handlebars is templating language implemented in Rust. It is based on the ideas of the original HandlebarsJS but it is not 100% compatible.
-
We have a very simple template embedded in our Rust code. It has one placeholder
{{name}}. -
We pass a JSON string to the
render_templatefunction.
use handlebars::Handlebars;
use serde_json::json;
use std::error::Error;
fn main() {
match render() {
Ok(_) => println!(),
Err(_) => println!("error"),
}
}
fn render() -> Result<(), Box<dyn Error>> {
let reg = Handlebars::new();
println!(
"{}",
reg.render_template("Hello {{name}}", &json!({"name": "foo"}))?
);
Ok(())
}
- The generated output looks like this:
Hello foo
[package]
name = "handlebars-quick"
version = "0.1.0"
edition = "2024"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
handlebars = "4.3.7"
serde_json = "1.0.97"
Quick start - registered template
-
register_template_string
-
render
-
In this example we register a template to make it easier to reuse it and then use it twice.
use handlebars::Handlebars;
use serde_json::json;
use std::error::Error;
fn main() {
match render() {
Ok(_) => println!(),
Err(_) => println!("error"),
}
}
fn render() -> Result<(), Box<dyn Error>> {
let mut reg = Handlebars::new();
reg.register_template_string("tpl_1", "Good afternoon, {{name}}")?;
println!("{}", reg.render("tpl_1", &json!({"name": "foo"}))?);
println!("{}", reg.render("tpl_1", &json!({"name": "bar"}))?);
Ok(())
}
Good afternoon, foo
Good afternoon, bar
[package]
name = "handlebars-quick"
version = "0.1.0"
edition = "2024"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
handlebars = "4.3.7"
serde_json = "1.0.97"
Handlebars - render to file
- In some cases we would like to save the generated string in a file.
use handlebars::Handlebars;
use serde_json::json;
use std::error::Error;
use std::fs::File;
use std::io::Write;
fn main() {
match render_without_register("hello.html") {
Ok(_) => println!(),
Err(_) => println!("error"),
}
}
fn render_without_register(filename: &str) -> Result<(), Box<dyn Error>> {
let reg = Handlebars::new();
let html = reg.render_template("Hello {{name}}", &json!({"name": "foo"}))?;
let mut file = File::create(filename).unwrap();
writeln!(&mut file, "{}", html).unwrap();
Ok(())
}
Hello foo
[package]
name = "handlebars-quick"
version = "0.1.0"
edition = "2024"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
handlebars = "4.3.7"
serde_json = "1.0.97"
Handlebars - read template from file
- We have a separate function to read the content of the template file.
Hello {{name}} from the template file.
use handlebars::Handlebars;
use serde_json::json;
use std::error::Error;
use std::fs::File;
use std::io::Read;
use std::io::Write;
fn main() {
let filename = "hello.html";
let template = "template.html";
match render_without_register(template, filename) {
Ok(_) => println!(),
Err(_) => println!("error"),
}
}
fn render_without_register(template_file: &str, filename: &str) -> Result<(), Box<dyn Error>> {
let template = read_template(template_file);
let reg = Handlebars::new();
let html = reg.render_template(&template, &json!({"name": "foo"}))?;
let mut file = File::create(filename).unwrap();
writeln!(&mut file, "{}", html).unwrap();
Ok(())
}
fn read_template(template_file: &str) -> String {
let mut template = String::new();
match File::open(template_file) {
Ok(mut file) => {
file.read_to_string(&mut template).unwrap();
}
Err(error) => {
println!("Error opening file {}: {}", template_file, error);
}
}
template
}
Hello foo from the template file.
[package]
name = "handlebars-quick"
version = "0.1.0"
edition = "2024"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
handlebars = "4.3.7"
serde_json = "1.0.97"
Handlebars - show time of generation
use chrono::{DateTime, Utc};
use handlebars::Handlebars;
use serde_json::json;
use std::error::Error;
use std::fs::File;
use std::io::Read;
use std::io::Write;
fn main() {
let filename = "hello.html";
let template = "template.html";
match render_without_register(template, filename) {
Ok(_) => println!(),
Err(_) => println!("error"),
}
}
fn render_without_register(template_file: &str, filename: &str) -> Result<(), Box<dyn Error>> {
let template = read_template(template_file);
let utc: DateTime<Utc> = Utc::now();
let reg = Handlebars::new();
let html = reg.render_template(&template, &json!({"utc": format!("{}", utc)}))?;
let mut file = File::create(filename).unwrap();
writeln!(&mut file, "{}", html).unwrap();
Ok(())
}
fn read_template(template_file: &str) -> String {
let mut template = String::new();
match File::open(template_file) {
Ok(mut file) => {
file.read_to_string(&mut template).unwrap();
}
Err(error) => {
println!("Error opening file {}: {}", template_file, error);
}
}
template
}
Hello. This page was generated at {{utc}}.
Hello. This page was generated at 2023-10-08 12:17:47.976870543 UTC.
[package]
name = "handlebars-quick"
version = "0.1.0"
edition = "2024"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
handlebars = "4.3.7"
serde_json = "1.0.97"
chrono = "0.4.26"
Handlebars loop (each) on array
<h1>Fruits</h1>
<ul>
{{#each fruits as |fruit|}}
<li>{{fruit}}</li>
{{/each}}
</ul>
<h1>Fruits</h1>
<ul>
<li>apple</li>
<li>banana</li>
<li>peach</li>
</ul>
use handlebars::Handlebars;
use serde_json::json;
use std::error::Error;
use std::fs::File;
use std::io::Read;
use std::io::Write;
fn main() {
let filename = "hello.html";
let template = "template.html";
match render_without_register(template, filename) {
Ok(_) => println!(),
Err(_) => println!("error"),
}
}
fn render_without_register(template_file: &str, filename: &str) -> Result<(), Box<dyn Error>> {
let mut template = String::new();
match File::open(template_file) {
Ok(mut file) => {
file.read_to_string(&mut template).unwrap();
}
Err(error) => {
println!("Error opening file {}: {}", template_file, error);
}
}
let reg = Handlebars::new();
let fruits = ["apple", "banana", "peach"];
let html = reg.render_template(&template, &json!({"fruits": fruits}))?;
let mut file = File::create(filename).unwrap();
writeln!(&mut file, "{}", html).unwrap();
Ok(())
}
[package]
name = "handlebars-quick"
version = "0.1.0"
edition = "2024"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
handlebars = "4.3.7"
serde_json = "1.0.97"