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_template
function.
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 = "2021"
# 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 = "2021"
# 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 = "2021"
# 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 = "2021"
# 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 = "2021"
# 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 = "2021"
# 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"