{"id":15672689,"url":"https://github.com/virviil/libfluent","last_synced_at":"2025-05-06T21:46:56.067Z","repository":{"id":46687849,"uuid":"209051286","full_name":"Virviil/libfluent","owner":"Virviil","description":"Project Fluent native bindings for Elixir","archived":false,"fork":false,"pushed_at":"2023-11-14T18:33:31.000Z","size":74,"stargazers_count":14,"open_issues_count":1,"forks_count":2,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-04-27T18:24:40.129Z","etag":null,"topics":["elixir","ftl","gettext","translation"],"latest_commit_sha":null,"homepage":"","language":"Elixir","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Virviil.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2019-09-17T12:43:29.000Z","updated_at":"2024-12-15T11:00:35.000Z","dependencies_parsed_at":"2024-10-23T10:57:25.922Z","dependency_job_id":"bb63f7fc-8fc9-45ad-9d09-bcda96efda5a","html_url":"https://github.com/Virviil/libfluent","commit_stats":null,"previous_names":[],"tags_count":2,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Virviil%2Flibfluent","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Virviil%2Flibfluent/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Virviil%2Flibfluent/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Virviil%2Flibfluent/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Virviil","download_url":"https://codeload.github.com/Virviil/libfluent/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":252776475,"owners_count":21802461,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["elixir","ftl","gettext","translation"],"created_at":"2024-10-03T15:30:13.773Z","updated_at":"2025-05-06T21:46:55.982Z","avatar_url":"https://github.com/Virviil.png","language":"Elixir","funding_links":[],"categories":[],"sub_categories":[],"readme":"# libfluent\n[![](https://img.shields.io/hexpm/dt/libfluent.svg?style=flat-square)](https://hex.pm/packages/libfluent)[![](https://img.shields.io/hexpm/v/libfluent.svg?style=flat-square)](https://hex.pm/packages/libfluent)[![](https://img.shields.io/hexpm/l/libfluent.svg?style=flat-square)](https://hex.pm/packages/libfluent)[![](https://img.shields.io/circleci/build/gh/Virviil/libfluent?style=flat-square)](https://circleci.com/gh/Virviil/libfluent)[![](https://img.shields.io/coveralls/github/Virviil/libfluent.svg?style=flat-square)](https://coveralls.io/github/Virviil/libfluent)[![](https://img.shields.io/github/last-commit/virviil/libfluent.svg?style=flat-square)](https://github.com/Virviil/libfluent/commits)[![](https://img.shields.io/maintenance/yes/2020.svg?style=flat-square)](https://github.com/Virviil/libfluent)\n\nModule provides [**Project Fluent**](https://projectfluent.org/) bindings and API to build \ninternationalized applications. API is trying to be as simmilar as possible to \nElixir's *default* internatrionalization library - [**Gettext**](https://hex.pm/packages/gettext)\n\nAt the same time, `Fluent.Native` module - as native binding - can be used to work with **Project Fluent**\nfrom any structure of choice. One can use it to define his own API, that is opposite to **Gettext** API\nas much as he wants.\n\n## Using Fluent\n\nTo use **Fluent**, a module that calls `use Fluent.Assembly` has to be defined:\n\n```elixir\ndefmodule MyApp.Fluent do\n  use Fluent.Assembly, otp_app: :my_app\nend\n```\n\nThis automatically defines some funcitons in the `MyApp.Fluent` module, that can be used to translation:\n\n```elixir\nimport MyApp.Fluent\n\n# Simple translation\nftl(\"hello-world\")\n\n# Argument-based translation\nftl(\"hello-user\", userName: \"Alice\")\n\n# With different types\nftl(\"shared-photos\", userName: \"Alice\", userGender: \"female\", photoCount: 3)\n```\n\n## Translations\n\nTranslations are stored inside **FTL** files, with `.ftl` extension. \nSyntax overview can be found [here](https://projectfluent.org/fluent/guide/)\n\n**FTL** files, containgin translations for an application must be stored in a directory (by default it's `priv/fluent`),\nthat has the following structure:\n\n```bash\n%FLUENT_TRANSLATIONS_DIRECTORY%\n└─ %LOCALE%\n   ├─ file_1.ftl\n   ├─ file_2.ftl\n   └─ file_3.ftl\n```\n\nHere, **%LOCALE%** is the locale of the translations (for example, `en_US`),\nand file_i.ftl are FTL files containing translations. All the files from single translation\nare loaded as the single scope, so name conflicts inside the files in one folder should be avoided.\n\nA concrete example of such a directory structure could look like this:\n\n```bash\npriv/gettext\n└─ en_US\n|  ├─ default.ftl\n|  └─ errors.ftl\n└─ it\n   ├─ default.ftl\n   └─ errors.ftl\n```\n\nBy default, **Fluent** expects translations to be stored under the `fluent` directory inside `priv` directory of an application. This behaviour can be changed by specifying a `:priv` option when using `Fluent.Assembly`:\n\n```elixir\n# Look for translations in my_app/priv/translations instead of\n# my_app/priv/gettext\nuse Fluent.Assembly, otp_app: :my_app, priv: \"translations\"\n```\n\n## Locale\n\nAt runtime, all translation functions that do not explicitly take a locale as an argument read the locale from the assembly locale and then fallbacks to `libfluent`'s locale.\n\n`Fluent.put_locale/1` can be used to change the locale of all assemblies for the current Elixir process. That's the preferred mechanism for setting the locale at runtime. `Fluent.put_locale/2` can be used when you want to set the locale of one specific **Fluent** assembly without affecting other **Fluent** assemblies.\n\nSimilarly, `Fluent.get_locale/0` gets the locale for all assemblies in the current process. `Fluent.get_locale/1` gets the locale of a specific assembly for the current process. Check their documentation for more information.\n\nLocales are expressed as strings (like \"en\" or \"fr\"); they can be arbitrary strings as long as they match a directory name. As mentioned above, the locale is stored per-process (in the process dictionary): this means that the locale must be set in every new process in order to have the right locale available for that process. Pay attention to this behaviour, since not setting the locale will not result in any errors when `Fluent.get_locale/0` or `Fluent.get_locale/1` are called; the default locale will be returned instead.\n\nTo decide which locale to use, each gettext-related function in a given assembly follows these steps:\n\n* if there is a assembly-specific locale for the given assembly for this process (see `Fluent.put_locale/2`), \n  use that, *otherwise*\n* if there is a global locale for this process (see `Fluent.put_locale/1`), \n  use that, *otherwise*\n* if there is a assembly's specific default locale in the configuration for that assembly's `:otp_app`\n  (see the [**Default locale**](#default-locale) section below), use that, *otherwise*\n* use the default global **Fluent** locale (see the [**Default locale**](#default-locale) section below)\n\n\n### Default locale\n\nThe global **Fluent** default locale can be configured through the `:default_locale` key of the `:libfluent` application:\n\n```elixir\nconfig :libfluent, :default_locale, \"fr\"\n```\n\nBy default the global locale is \"en\".\n\nIf for some reason an assembly requires with a different `:default_locale` than all other assemblies, you can set the `:default_locale` inside the assembly configuration, but this approach is generally discouraged as it makes it hard to track which locale each assembly is using:\n\n```elixir\nconfig :my_app, MyApp.Fluent, default_locale: \"fr\"\n```\n\n## Installation\n\nIf [available in Hex](https://hex.pm/docs/publish), the package can be installed\nby adding `fluent` to your list of dependencies in `mix.exs`:\n\n```elixir\ndef deps do\n  [\n    {:libfluent, \"~\u003e 0.2.2\"}\n  ]\nend\n```\n\nDocumentation can be generated with [ExDoc](https://github.com/elixir-lang/ex_doc)\nand published on [HexDocs](https://hexdocs.pm). Once published, the docs can\nbe found at [https://hexdocs.pm/libfluent](https://hexdocs.pm/libfluent).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvirviil%2Flibfluent","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fvirviil%2Flibfluent","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvirviil%2Flibfluent/lists"}