fluent_handlebars_runtime/lib.rs
1//! # Fluent Handlebars runtime helper: An extension crate for Fluent Templates
2//!
3//! The [`fluent_templates`](https://docs.rs/fluent-templates) crate includes a helper for the
4//! [Handlebars](https://docs.rs/handlebars) template framework that lets you provide values for
5//! [Fluent placeables](https://www.projectfluent.org/fluent/guide/placeables.html) at build time.
6//! `fluent-handlebars-runtime` adds a helper that resolves placeables using the data hash you pass
7//! into the Handlebars [`render_template`](https://docs.rs/handlebars/3.3.0/handlebars/struct.Handlebars.html#method.render_template)
8//! method.
9//!
10//! For example, if your FTL files look like this:
11//!
12//! ```ftl
13//! # /resources/locale/en-US/app.ftl
14//! into-place = One does not simply walk into {$place}
15//!
16//! # /resources/locale/fr/app.ftl
17//! into-place = On ne marche pas simplement à {$place}
18//! ```
19//!
20//! You can then pass the replacement values at runtime:
21//! ```rust
22//! # use handlebars::Handlebars;
23//! # use fluent_handlebars_runtime::FluentHandlebars;
24//! # use fluent_templates::ArcLoader;
25//! # use unic_langid::langid;
26//! # let loader = ArcLoader::builder(
27//! # "resources/locales",
28//! # langid!("en-US"),
29//! # )
30//! # .customize(|b| b.set_use_isolating(false))
31//! # .build()
32//! # .unwrap();
33//! #
34//! let data = serde_json::json!({
35//! "lang": "en-US",
36//! "place": "Mordor"
37//! });
38//!
39//! let mut handlebars = Handlebars::new();
40//! handlebars.register_helper("t", Box::from(FluentHandlebars::new(&loader)));
41//! assert_eq!(
42//! format!("{}", handlebars.render_template(r#"{{t "into-place"}}"#, &data).unwrap()),
43//! "One does not simply walk into Mordor"
44//! );
45//!
46//! let data = serde_json::json!({
47//! "lang": "fr",
48//! "place": "Mordor"
49//! });
50//!
51//! assert_eq!(
52//! format!("{}", handlebars.render_template(r#"{{t "into-place"}}"#, &data).unwrap()),
53//! "On ne marche pas simplement à Mordor"
54//! );
55//! ```
56//!
57//! This allows you to substitute values into your localized strings that can only be known at
58//! runtime.
59//!
60//! By convention, we call this helper "t" in the interest of keeping templates terse, but you can
61//! use a more verbose identifier (e.g. "translate" or "localize") if you find that more readable.
62//!
63//! ```rust
64//! # use handlebars::Handlebars;
65//! # use fluent_handlebars_runtime::FluentHandlebars;
66//! # use fluent_templates::ArcLoader;
67//! # use unic_langid::langid;
68//! # let loader = ArcLoader::builder(
69//! # "resources/locales",
70//! # langid!("en-US"),
71//! # )
72//! # .customize(|b| b.set_use_isolating(false))
73//! # .build()
74//! # .unwrap();
75//! #
76//! # let data = serde_json::json!({
77//! # "lang": "en-US",
78//! # "place": "Mordor"
79//! # });
80//! #
81//! # let mut handlebars = Handlebars::new();
82//! handlebars.register_helper("translate", Box::from(FluentHandlebars::new(&loader)));
83//! assert_eq!(
84//! format!("{}",
85//! handlebars.render_template(r#"{{translate "into-place"}}"#, &data).unwrap()
86//! ),
87//! "One does not simply walk into Mordor"
88//! );
89//! ```
90
91
92mod helper;
93pub use helper::FluentHandlebars;
94
95#[cfg(test)]
96mod tests;