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;