/fluent-lua

Lua implementation of Project Fluent https://projectfluent.org

Primary LanguageLuaMIT LicenseMIT

Fluent Lua¹

Luacheck Busted Coverage Status GitHub tag (latest SemVer) LuaRocks Join the chat at https://gitter.im/fluent-lua/community

A Lua implementation of Project Fluent, a localization paradigm designed to unleash the entire expressive power of natural language translations. Fluent is a family of localization specifications, implementations and good practices developed by Mozilla who extracted parts of their 'l20n' solution (used in Firefox and other apps) into a re-usable specification. For more information also see the Fluent Syntax Guide, the Discourse channel, documentation wiki, and playground.

Other implementations already exist in Rust, Javascript, Python, c#, elm, and perl. See also other implementations.

¹ Fluent the localization paradigm, not to be confused with Fluent the API interface concept!

Status

It is possible to use this for simple string localization with basic parameter substitution but it is not feature complete nor is the API stable (see Lua alternatives). If you have ideas about how the Lua API should work or wish to contribute, please join the project chat and/or open issues for points of discussion.

  • Parse FTL input strings
  • Format Basic messages
  • Format String and Number literals
  • Substitute VariableReferences
  • Handle Attributes
  • Handle Variants using SelectExpressions
  • Handle TermsReferences
  • Handle MessageReferences
  • Setup Locale fallbacks in Bundle
  • Localize number formatting
  • Functions

Changelog

Please see CHANGELOG.md.

Usage

Lua code demo.lua:

-- Import and start a new instance
local FluentBundle = require("fluent")
local bundle = FluentBundle()

-- Load some messages (can be a string or table of strings)
bundle:add_messages([[
hello = Hello { $name }!
foo = bar
    .attr = baz
]])

-- Access methods like other Fluent implementations
print(bundle:format("foo"))
print(bundle:format("foo.attr"))
print(bundle:format("hello", { name = "World" }))

-- Alternate idomatic Lua access methods
print(bundle["foo"]) -- access property, implicit cast to string, cannot pass parammeters
print("Attr: " .. bundle.foo.attr) -- access attributes as property, allow contatenation
print(bundle.hello({ name = "World" })) -- access as property is callable, parameters passed to format()

Output of lua demo.lua:

bar
baz
Hello World!
bar
Attr: baz
Hello World!

Alternative(s)

Fluent-lua is usage for many basic use-cases but it is not 100% feature complete. If you need something more mature (and don’t have the energy to contribute here), have a look at the i18n.lua project (Github / LuaRocks). It implements many of the same features this project will, just without the interoperability with other Fluent based tools. The Lua API it provides is quite nice, but your localization data needs to be provided in Lua tables instead of FTL files. While Fluent has quite a few more tricks up its sleeve the i18n module already has working interpolation, pluralization, locale fallbacks, and more. And it works now, today.

Another even simpler solution is the Lua say module (Github / LuaRocks) from the makers of Busted. This is much closer to a flat one-to-one key value map, but with namespacing in such a way that it is useful for localization.

Design Goals

This project's end goal is to provide an idiomatic Lua API implementing the Fluent spec that is fully compatible with other FTL based tooling. This will allow Lua projects to easily implement localized interfaces with natural sounding translations and take advantage of tools such as Pontoon.