Expand description
Β§fluent-i18n π£οΈπ₯
A declarative and ergonomic internationalization for Rust using Fluent.
Built on top of fluent-templates and inspired by the simplicity of rust-i18n.
Β§Features
- Static file loading via
i18n!()macro - Zero-boilerplate
t!()macro for inline translations - Extensible argument system via
ToFluentValuetrait - Thread-local handling via
set_locale()andget_locale() - Clean fallback locale management
Β§Example
use fluent_i18n::{i18n, t};
i18n!("locales", fallback = "en-US");
println!("{}", t!("greeting"));
println!("{}", t!("welcome", { "name" => "Orhun" }));Place your localization files in locales/en-US/main.ftl:
greeting = Hello, world!
welcome = Welcome, { $name }!See the Fluent syntax for more details about FTL files.
Β§Usage
Β§Installation
Add fluent-i18n to your Cargo.toml:
cargo add fluent-i18nΒ§Initialization
At the entry point of your application (e.g., main.rs or lib.rs), invoke the i18n!() macro to initialize the localization system:
i18n!("locales");Or with a fallback locale:
i18n!("locales", fallback = "en-US");This will expose a static loader named LOCALES that will be used by the t!() macro for translations throughout your application.
You can also dynamically change the locale at runtime using the set_locale() function:
use fluent_i18n::{set_locale, get_locale};
set_locale(Some("tr"))?;
let current_locale = get_locale()?;Running set_locale(None) will detect the system locale automatically.
Β§Lookup
To look up a translation for a given key, use the t!() macro:
t!("greeting");With parameters:
t!("count-items", { "count" => 3 })
t!("key", { "arg1" => value1, "arg2" => value2 })The given parameters should be one of the supported types.
Β§Supported Types
The t!() macro interpolates values into the message using the ToFluentValue trait.
The following types implement the ToFluentValue trait:
String,&'static str,Cow<'static, str>- Integer and float primitives (
usize,u32,i64, etc.) Path,PathBufOption<T>whereTimplementsToFluentValue
You can extend support for your own types by implementing this trait:
use fluent_i18n::{FluentValue, ToFluentValue};
impl ToFluentValue for MyType {
fn to_fluent_value(&self) -> FluentValue<'static> {
FluentValue::from(self.to_string())
}
}Β§Locale Layout
You can organize .ftl files per locale, and shared files like core.ftl will be included in all locales.
locales/
βββ core.ftl
βββ en-US/
β βββ main.ftl
βββ fr/
β βββ main.ftl
βββ zh-CN/
β βββ main.ftl
βββ zh-TW/
βββ main.ftlThe directory names should adhere to the Unicode Language Identifier.
It also respects any .gitignore or .ignore files present.
See the Fluent syntax for more details about FTL files.
Β§Testing
In tests, you can access the translations as usual without reinitialization:
use fluent_i18n::t;
#[test]
fn test_translation() {
assert_eq!(t!("greeting"), "Hello, world!");
}Β§Debugging
When raw mode is enabled, translations will return the key itself instead of looking up the translation. This is useful for debugging purposes to see which keys are being requested.
use fluent_i18n::{t, set_raw_mode};
set_raw_mode(true);
let raw_message = t!("some-translation-key"); // "some-translation-key"You could also follow this workflow for translating missing strings:
- Run the program and navigate to the area you want to test.
- Enable raw mode with
set_raw_mode(true). - Look for untranslated output (the raw key will be shown instead of the translation).
- Copy that key.
- Search for it in the project.
- Add the missing translation.
Β§Security
Unicode directional isolate characters (U+2068, U+2069) are disabled as default to prevent potential security issues like bidirectional text attacks. This also gives clean output without unexpected characters in translations.
Also, please note that this is only applicable for mixed-script languages such as Arabic, Hebrew, and Persian.
Β§License & Contributions
This project can be used under the terms of the Apache-2.0 or MIT. Contributions to this project, unless noted otherwise, are automatically licensed under the terms of both of those licenses.
π¦ γ( ΒΊ _ ΒΊ γ) - respect crables!
Feel free to open issues or PRs for improvements, bug fixes, or ideas!
Β§Acknowledgements
This library was originally developed as part of the ALPM project and later extracted for general-purpose use.
Re-exportsΒ§
pub use locale::get_locale;pub use locale::set_locale;pub use locale::set_raw_mode;pub use fluent_templates;
ModulesΒ§
- locale
- Locale management methods and macros.
MacrosΒ§
- i18n
- Macro to initialize the i18n system with a specified directory for locale files.
- t
- Macro to lookup a translation for a given key.
EnumsΒ§
- Error
- The error that may occur while using the crate.
- Fluent
Value - Re-export the type.
The
FluentValueenum represents values which can be formatted to a String.
TraitsΒ§
- ToFluent
Value - Helper trait for converting various types to a
FluentValue.