Cldr
Elixir implementation of CLDR/ICU
Install / Use
/learn @elixir-cldr/CldrREADME
Getting Started with Cldr
Change to :json_library configuration {: .warning}
As of
ex_cldrversion 2.37.2 the configuration parameter:json_librarydoes not attempt to read the configuration of either Phoenix or Ecto.
Automatic configuration of :json_library {: .info}
OTP 27 and Elixir 1.18 both include native JSON libraries. Therefore if running on either (or both) of these platforms, no
:json_libraryconfiguration is required or recommended.
Introduction
ex_cldr is an Elixir library for the Unicode Consortium's Common Locale Data Repository (CLDR). The intentions of CLDR, and this library, is to simplify the locale specific formatting and parsing of numbers, lists, currencies, calendars, units of measure and dates/times. As of August 16th 2024 and ex_cldr Version 2.40.1, ex_cldr is based upon CLDR version 45.0.
The first step is to define a module that will host the desired ex_cldr configuration and the functions that serve as the public API. This module is referred to in this documentation as a backend module. For example:
defmodule MyApp.Cldr do
@moduledoc """
Define a backend module that will host our
Cldr configuration and public API.
Most function calls in Cldr will be calls
to functions on this module.
"""
use Cldr,
locales: ["en", "fr", "zh", "th"],
default_locale: "en"
end
This strategy means that different configurations can be defined and it also
means that one ex_cldr implementation won't interfere with implementations in another,
potentially dependent, applications.
The functions you are mostly likely to use are:
MyApp.Cldr.default_locale/0MyApp.Cldr.put_locale/1MyApp.Cldr.get_locale/0MyApp.Cldr.known_locale_names/0MyApp.Cldr.Locale.new/1MyApp.Cldr.validate_locale/1
Use Case
Use this library if you need to:
-
Support multiple languages and locales in your application
-
Support formatting numbers, dates, times, date-times, units and lists in one language or many
-
Need to access the data maintained in the CLDR repository in a functional manner
-
Parse an Accept-Language HTTP header or a language tag
It is highly likely that you will also want to install one or more of the dependent packages that provide localization and formatting for a particular data domain. See Additional Cldr Packages below.
Elixir Version Requirements
- ex_cldr requires Elixir 1.12 or later.
Installation
Add ex_cldr and the JSON library of your choice as a dependency to your mix project. If running on OTP 27 or later, this step is not required since ex_cldr will detect and use the built-in :json module.
defp deps do
[
{:ex_cldr, "~> 2.37"},
# Poison or any other compatible json library
# that implements `encode!/1` and `decode!/1`
# :jason is recommended
{:jason, "~> 1.0"}
# {:poison, "~> 2.1 or ~> 3.0"}
]
end
then retrieve ex_cldr and the JSON library from hex:
mix deps.get
mix deps.compile
Additional Cldr Packages
ex_cldr includes only basic functions to maintain the CLDR data repository in an accessible manner and to manage locale definitions. Additional functionality is available by adding additional packages:
- Plugs for setting the locale from an HTTP request: ex_cldr_plugs
- Number formatting: ex_cldr_numbers
- List formatting: ex_cldr_lists
- Unit or measure formatting: ex_cldr_units
- Date/Time/DateTime formatting: ex_cldr_dates_times
- Route localization for Phoenix: ex_cldr_routes
- Locale name localisation: ex_cldr_locale_display
- HTML select helpers: ex_cldr_html
- Calendars: ex_cldr_calendars
- Calendar formatting: ex_cldr_calendars_format
- Printf-like formatting: ex_cldr_print
- Collation: ex_cldr_collation
- ICU Message formatting: ex_cldr_messages
- Person name formatting: ex_cldr_person_names
- Territories localization and information: ex_cldr_territories by @Schultzer
- Languages localization: ex_cldr_languages by @lostkobrakai
Each of these packages includes ex_cldr as a dependency so configuring any of these additional packages will automatically install ex_cldr.
Configuration
ex_cldr attempts to maximise runtime performance at the expense of additional compile time. Where possible ex_cldr will create functions to encapsulate data at compile time. To perform these optimizations for all 541 locales known to Cldr wouldn't be an effective use of your time or your computer's. Therefore ex_cldr requires that you configure the locales you want to use.
ex_cldr is configured in your backend module. This removes any dependency on your mix.exs and therefore simplifies deployment as a release.
Backend Module Configuration
use Cldr{: .info}When you
use Cldr, a number of functions are generated that encapsulate CLDR data. A module that invokesuse Cldris referred to as a Cldr backend module.The functions in a Cldr backend module form the primary recommended API for
ex_cldr.In addition, a number of additional modules may be generated with names that are prefixed by the name of the module in which
use Cldris invoked. The number and names of these additional modules is determined by the modules configured under the:providersoption touse Cldr.It is not recommended that a module that invokes
use Cldrdefine any other functions.
defmodule MyApp.Cldr do
use Cldr,
default_locale: "en",
locales: ["fr", "en", "bs", "si", "ak", "th"],
add_fallback_locales: false,
gettext: MyApp.Gettext,
data_dir: "./priv/cldr",
otp_app: :my_app,
precompile_number_formats: ["¤¤#,##0.##"],
precompile_transliterations: [{:latn, :arab}, {:thai, :latn}],
providers: [Cldr.Number],
generate_docs: true,
force_locale_download: false
end
Otp App Configuration
In the backend configuration example above the :otp_app key has been defined. This means that ex_cldr will look for additional configuration, defined under the key :my_app with the sub-key MyApp.Cldr. For example:
# cldr.ex
defmodule MyApp.Cldr do
use Cldr,
otp_app: :my_app,
default_locale: "en",
gettext: MyApp.Gettext,
json_library: Jason,
data_dir: "./priv/cldr",
precompile_number_formats: ["¤¤#,##0.##"],
providers: [Cldr.Number]
end
# config/config.exs
config :my_app, MyApp.Cldr,
# a single locale, for fast compilation in dev / test
locales: ["en"]
# config/production.exs
config :my_app, MyApp.Cldr,
# these will take a while to compile
locales: ["fr", "en", "bs", "si", "ak", "th"],
precompile_transliterations: [{:latn, :arab}, {:thai, :latn}]
Multiple backends can be configured under a single :otp_app if required.
Global configuration.
In config.exs a global configuration can be defined under the :ex_cldr key. Although any valid configuration keys can be used here, only the keys :json_library, :default_locale, :default_backend, :cacertfile, :data_dir, :force_locale_download are considered valid. Other configuration keys may be used to aid migration from ex_cldr version 1.x but a deprecation message will be printed during compilation. Here's an example of global configuration:
config :ex_cldr,
default_locale: "en",
default_backend: MyApp.Cldr,
json_library: Jason,
cacertfile: "path/to/cacertfile"
Note that the :json_library key can only be defined at the global level since it is required during compilation before any backend module is compiled.
Automatic configuration of :json_library {: .info}
OTP 27 and Elixir 1.18 both include native JSON libraries. Therefore if running on either (or both) of these platforms, no
:json_libraryconfiguration is required or recommended.
On most platforms other than Windows the :cacertfile will be automatically detected. Any configured :cacertfile will take precedence on all platforms.
If configuration beyond the keys :default_locale, :cacertfile or :json_library are defined a deprecation warning is printed at compile time noting that configuration should be moved to a backend module.
Configuration Priority
When building the consolidated configuration the following priority applies:
- Consider the global configuration
- Merge the otp_app configuration over the top of the global configuration
- Merge the backend module configuration over the top
