.. role:: html(code) :language: html .. role:: js(code) :language: JavaScript ============================= Fluent for Firefox Developers ============================= This tutorial is intended for Firefox engineers already familiar with the previous localization systems offered by Gecko - DTD and StringBundle - and assumes prior experience with those systems. For a more hands-on tutorial of understanding Fluent from the ground up, try following the `Fluent DOMLocalization Tutorial`__, which provides some background on how Fluent works and walks you through creating a basic web project from scratch that uses Fluent for localization. __ https://projectfluent.org/dom-l10n-documentation/ Using Fluent in Gecko ===================== `Fluent`_ is a modern localization system introduced into the Gecko platform with a focus on quality, performance, maintenance and completeness. The legacy DTD system is deprecated, and Fluent should be used where possible. Getting a Review ---------------- If you work on any patch that touches FTL files, you'll need to get a review from `fluent-reviewers`__. There's a Herald hook that automatically sets that group as a blocking reviewer. __ https://phabricator.services.mozilla.com/tag/fluent-reviewers/ Guidelines for the review process are available `here`__. __ ./fluent_review.html To lighten the burden on reviewers, please take a moment to review some best practices before submitting your patch for review. - `ProjectFluent Good Practices for Developers`_ - `Mozilla Localization Best Practices For Developers`_ .. _ProjectFluent Good Practices for Developers: https://github.com/projectfluent/fluent/wiki/Good-Practices-for-Developers .. _Mozilla Localization Best Practices For Developers: https://mozilla-l10n.github.io/documentation/localization/dev_best_practices.html Major Benefits ============== Fluent `ties tightly`__ into the domain of internationalization through `Unicode`_, `CLDR`_ and `ICU`_. __ https://github.com/projectfluent/fluent/wiki/Fluent-and-Standards More specifically, the most observable benefits for each group of consumers are Developers ---------- - Support for XUL, XHTML, HTML, Web Components, React, JS, Python and Rust - Strings are available in a single, unified localization context available for both DOM and runtime code - Full internationalization (i18n) support: date and time formatting, number formatting, plurals, genders etc. - Strong focus on `declarative API via DOM attributes`__ - Extensible with custom formatters, Mozilla-specific APIs etc. - `Separation of concerns`__: localization details, and the added complexity of some languages, don't leak onto the source code and are no concern for developers - Compound messages link a single translation unit to a single UI element - `DOM Overlays`__ allow for localization of DOM fragments - Simplified build system model - No need for pre-processing instructions - Support for pseudolocalization __ https://github.com/projectfluent/fluent/wiki/Get-Started __ https://github.com/projectfluent/fluent/wiki/Design-Principles __ https://github.com/projectfluent/fluent.js/wiki/DOM-Overlays Product Quality ------------------ - A robust, multilevel, `error fallback system`__ prevents XML errors and runtime errors - Simplified l10n API reduces the amount of l10n specific code and resulting bugs - Runtime localization allows for dynamic language changes and updates over-the-air - DOM Overlays increase localization security __ https://github.com/projectfluent/fluent/wiki/Error-Handling Fluent Translation List - FTL ============================= Fluent introduces a file format designed specifically for easy readability and the localization features offered by the system. At first glance the format is a simple key-value store. It may look like this: .. code-block:: fluent home-page-header = Home Page # The label of a button opening a new tab new-tab-open = Open New Tab But the FTL file format is significantly more powerful and the additional features quickly add up. In order to familiarize yourself with the basic features, consider reading through the `Fluent Syntax Guide`_ to understand a more complex example like: .. code-block:: fluent ### These messages correspond to security and privacy user interface. ### ### Please choose simple and non-threatening language when localizing ### to help user feel in control when interacting with the UI. ## General Section -brand-short-name = Firefox .gender = masculine pref-pane = .title = { PLATFORM() -> [windows] Options *[other] Preferences } .accesskey = C # Variables: # $tabCount (Number) - number of container tabs to be closed containers-disable-alert-ok-button = { $tabCount -> [one] Close { $tabCount } Container Tab *[other] Close { $tabCount } Container Tabs } update-application-info = You are using { -brand-short-name } Version: { $version }. Please read the privacy policy. The above, of course, is a particular selection of complex strings intended to exemplify the new features and concepts introduced by Fluent. .. important:: While in Fluent it’s possible to use both lowercase and uppercase characters in message identifiers, the naming convention in Gecko is to use lowercase and hyphens, avoiding CamelCase and underscores. For example, `allow-button` should be preferred to `allow_button` or `allowButton`, unless there are technically constraints – like identifiers generated at run-time from external sources – that make this impractical. In order to ensure the quality of the output, a lot of checks and tooling is part of the build system. `Pontoon`_, the main localization tool used to translate Firefox, also supports Fluent and its features to help localizers in their work. .. _fluent-tutorial-social-contract: Social Contract =============== Fluent uses the concept of a `social contract` between developer and localizers. This contract is established by the selection of a unique identifier, called :js:`l10n-id`, which carries a promise of being used in a particular place to carry a particular meaning. The use of unique identifiers is shared with legacy localization systems in Firefox. .. important:: An important part of the contract is that the developer commits to treat the localization output as `opaque`. That means that no concatenations, replacements or splitting should happen after the translation is completed to generate the desired output. In return, localizers enter the social contract by promising to provide an accurate and clean translation of the messages that match the request. In Fluent, the developer is not to be bothered with inner logic and complexity that the localization will use to construct the response. Whether `declensions`__ or other variant selection techniques are used is up to a localizer and their particular translation. From the developer perspective, Fluent returns a final string to be presented to the user, with no l10n logic required in the running code. __ https://en.wikipedia.org/wiki/Declension Markup Localization =================== To localize an element in Fluent, the developer adds a new message to an FTL file and then has to associate an :js:`l10n-id` with the element by defining a :js:`data-l10n-id` attribute: .. code-block:: html