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


mod helper;
pub use helper::FluentHandlebars;

#[cfg(test)]
mod tests;