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
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
//! # Fluent Templates: Templating for Fluent
//!
//! This crate provides "loaders" that are able to load fluent strings based on
//! simple language negotiation, and the `FluentHelper` which is an opague
//! type that provides the integration between a given templating engine such as
//! handlebars or tera.
//!
//! ## Loaders
//! Currently this crate provides two different kinds of loaders that cover two
//! main use cases.
//!
//! - [`static_loader!`] — A macro that generates a loader that loads the
//!   localisations into static memory. Useful for when your localisations are
//!   known at **compile-time**.
//! - [`ArcLoader`] — A struct that atomically stores and reference counts the
//!   localisations. Useful for when your localisations are only known at
//!   **run-time**.
//!
//! ## Example
//! The easiest way to use `fluent-templates` is to use the [`static_loader!`]
//! macro:
//!
//! ```rust
//! fluent_templates::static_loader!(create_loader, "./locales/", "en-US");
//! ```
//!
//! ### Tera
//! ```rust
//! # #[cfg(feature = "handlebars")] {
//! use tera::Tera;
//!
//! fluent_templates::static_loader!(create_loader, "./locales/", "en-US");
//!
//! fn init(tera: &mut Tera) {
//!     let loader = create_loader();
//!     let helper = fluent_templates::FluentHelper::new(loader);
//!     tera.register_function("fluent", helper);
//! }
//!
//! fn render_page(tera: &mut Tera, ctx: &tera::Context) -> String {
//!     tera.render_str(r#"{{ fluent(key="foo-bar", lang="en") }} baz"#, ctx).unwrap()
//! }
//! # }
//! ```
//!
//! ### Handlebars
//! ```rust
//! # #[cfg(feature = "handlebars")] {
//! use handlebars::Handlebars;
//!
//! fluent_templates::static_loader!(create_loader, "./locales/", "en-US");
//!
//! fn init(handlebars: &mut Handlebars) {
//!     let loader = create_loader();
//!     let helper = fluent_templates::FluentHelper::new(loader);
//!     handlebars.register_helper("fluent", Box::new(helper));
//! }
//!
//! fn render_page(handlebars: &Handlebars) -> String {
//!     let data = serde_json::json!({"lang": "zh-CN"});
//!     handlebars.render_template("{{fluent \"foo-bar\"}} baz", &data).unwrap()
//! }
//! # }
//! ```
//!
//! You should have a `locales/` folder somewhere with one folder per language
//! code, containing all of your FTL files. See the [`static_loader!`] macro
//! for more options.
//!
//! Make sure the [`handlebars::Context`] has a top-level `"lang"` field when rendering.
//!
//! ### Handlebars helper syntax.
//!
//! The main helper provided is the `{{fluent}}` helper. If you have the following Fluent
//! file:
//!
//! ```fluent
//! foo-bar = "foo bar"
//! placeholder = this has a placeholder { $variable }
//! ```
//!
//! You can include the strings in your template with
//!
//! ```hbs
//! {{fluent "foo-bar"}} <!-- will render "foo bar" -->
//! {{fluent "placeholder" variable="baz"}} <!-- will render "this has a placeholder baz" -->
//!```
//!
//! You may also use the `{{fluentparam}}` helper to specify [variables], especially if you need
//! them to be multiline, like so:
//!
//! ```hbs
//! {{#fluent "placeholder"}}
//!     {{#fluentparam "variable"}}
//!         first line
//!         second line
//!     {{/fluentparam}}
//! {{/fluent}}
//! ```
//!
//! Multiple `{{fluentparam}}`s may be specified
//!
//! [variables]: https://projectfluent.org/fluent/guide/variables.html
//! [`static_loader!`]: ./macro.static_loader.html
#![warn(missing_docs)]

#[doc(hidden)]
pub extern crate lazy_static;

#[doc(hidden)]
pub extern crate fluent_bundle;

pub use error::LoaderError;
pub use helper::FluentHelper;
pub use loader::{ArcLoader, ArcLoaderBuilder, Loader, StaticLoader};

mod error;
mod fs;
mod helper;
pub mod loader;

/// A convenience `Result` type that defaults to `error::Loader`.
pub type Result<T, E = error::LoaderError> = std::result::Result<T, E>;