Search documentation of Localize

# Localize.Locale.Provider behaviour (Localize v0.39.0)

Copy Markdown View Source

Defines the behaviour for locale data providers.

A locale data provider is responsible for loading, storing, and retrieving CLDR locale data. Implementations may store data in any backing store such as `:persistent_term`, ETS, or the filesystem.

## Callbacks

Implementing modules must define four callbacks:

- `load/1` — finds and retrieves locale data for a given locale.

- `store/2` — persists locale data to the provider's backing store.

- `loaded?/1` — checks whether a locale's data has been loaded and is available for use.

- `get/3` — retrieves a specific value from locale data by following a list of access keys, with optional fallback to parent locales.

## Summary

### Types

locale()

A locale reference: either a locale identifier atom or a language tag struct.

locale_id()

A locale identifier as an atom.

### Callbacks

allow_download?()

Returns whether this provider is permitted to download locale data from a remote source at runtime.

get(locale, list, t)

Retrieves a value from locale data by following a list of access keys.

load(locale)

Loads locale data for the given locale.

loaded?(locale)

Returns whether locale data has been loaded and is available.

store(locale_id, map)

Stores locale data in the provider's backing store.

### Functions

allow_download?(provider_module \\ configured_provider())

Returns whether runtime locale downloads are permitted for the given provider module.

base_url()

Returns the base URL from which locale data files are downloaded.

default_locale_cache_dir()

Returns the default directory in which downloaded locale data is cached.

download_locale(locale_id)

Downloads locale data for the given locale from `locale_url/1`.

load_with_fallback(provider, locale)

Loads locale data with fallback through the CLDR parent chain.

locale_cache_dir()

Returns the directory in which downloaded locale data is cached.

locale_file_name(locale_id)

Returns the file name for a locale's cached data file.

locale_url(locale_id)

Returns the download URL for a given locale.

version_segment()

Returns the version segment used in cache paths and download URLs.

## Types

# locale()

    @type locale() :: locale_id() | Localize.LanguageTag.t()

A locale reference: either a locale identifier atom or a language tag struct.

# locale_id()

    @type locale_id() :: atom()

A locale identifier as an atom.

## Callbacks

# allow_download?()

(optional)

    @callback allow_download?() :: boolean()

Returns whether this provider is permitted to download locale data from a remote source at runtime.

Providers that never download (e.g. a database-backed provider) should return `false`. Providers that always have data locally available can simply not implement this callback — the default implementation reads `Application.get_env(:localize, :allow_runtime_locale_download, false)`.

# get(locale, list, t)

    @callback get(locale(), list(), Keyword.t()) :: {:ok, term()} | {:error, term()}

Retrieves a value from locale data by following a list of access keys.

Navigates the locale data map using the provided list of keys, returning the value found at the end of the key path.

### Arguments

- `locale` is a locale identifier atom or a `Localize.LanguageTag.t/0`.

- `keys` is a list of keys to traverse in the locale data map.

- `options` is a keyword list of options. The default is `[]`.

### Options

- `:fallback` is a boolean. When `true`, if the requested key path is not found in the given locale, the provider will attempt to find it in parent locales according to the CLDR locale inheritance chain. The default is `false`.

### Returns

- `{:ok, value}` if the key path resolves to a value.

- `{:error, reason}` if the key path cannot be resolved.

# load(locale)

    @callback load(locale()) :: {:ok, map()} | {:error, Exception.t()}

Loads locale data for the given locale.

Finds the locale data for the given locale identifier or language tag, retrieves it from the data source, and returns the data as a map.

### Arguments

- `locale` is a locale identifier atom or a `Localize.LanguageTag.t/0`.

### Returns

- `{:ok, locale_data}` where `locale_data` is a map of the locale's CLDR data.

- `{:error, Localize.UnknownLocaleError.t()}` if the locale is not recognized.

# loaded?(locale)

    @callback loaded?(locale()) :: boolean()

Returns whether locale data has been loaded and is available.

### Arguments

- `locale` is a locale identifier atom or a `Localize.LanguageTag.t/0`.

### Returns

- `true` if the locale data has been loaded and stored.

- `false` otherwise.

# store(locale_id, map)

    @callback store(locale_id(), map()) :: :ok | {:error, term()}

Stores locale data in the provider's backing store.

### Arguments

- `locale` is a locale identifier atom.

- `locale_data` is a map of locale data to store.

### Returns

- `:ok` on success.

- `{:error, reason}` on failure.

## Functions

# allow_download?(provider_module \\ configured_provider())

    @spec allow_download?(module()) :: boolean()

Returns whether runtime locale downloads are permitted for the given provider module.

If the provider module implements the optional `allow_download?/0` callback, that implementation is called. Otherwise falls back to the `:allow_runtime_locale_download` application environment key (default `false`).

### Arguments

- `provider_module` is a module that implements the `Localize.Locale.Provider` behaviour. The default is the currently configured provider.

### Returns

- `true` if runtime downloads are permitted.

- `false` otherwise.

# base_url()

    @spec base_url() :: String.t()

Returns the base URL from which locale data files are downloaded.

### Returns

- A string URL.

### Examples

    iex> Localize.Locale.Provider.base_url()
    "https://elixir-localize.com/locales"

# default_locale_cache_dir()

    @spec default_locale_cache_dir() :: String.t()

Returns the default directory in which downloaded locale data is cached.

The default directory is located under the `:localize` application's `priv` directory at `localize/locales`.

### Returns

- A string path to the default locale cache directory.

### Examples

    iex> String.ends_with?(Localize.Locale.Provider.default_locale_cache_dir(), "localize/locales")
    true

# download_locale(locale_id)

    @spec download_locale(locale_id()) :: {:ok, binary()} | {:error, Exception.t()}

Downloads locale data for the given locale from `locale_url/1`.

Uses Erlang's built-in `:httpc` to fetch the file. The downloaded content is returned as a binary and is not written to disk or decoded by this function.

### Arguments

- `locale_id` is a locale identifier atom.

### Returns

- `{:ok, binary}` with the raw downloaded file contents on success.

- `{:error, exception}` if the locale could not be downloaded.

# load_with_fallback(provider, locale)

    @spec load_with_fallback(module(), locale()) ::
      {:ok, map(), locale_id()} | {:error, Exception.t()}

Loads locale data with fallback through the CLDR parent chain.

Attempts to load the requested locale via `provider.load/1`. If the load fails, walks up the CLDR locale inheritance chain (e.g. `en-AU` → `en` → `und`) trying each parent in turn. If the entire chain is exhausted without success, falls back to `:en` which is guaranteed to be present.

Returns `{:ok, locale_data, resolved_locale_id}` so the caller knows which locale was actually loaded.

### Arguments

- `provider` is the module implementing `Localize.Locale.Provider`.

- `locale` is a locale identifier atom or a `Localize.LanguageTag.t/0`.

### Returns

- `{:ok, locale_data, resolved_locale_id}` on success.

- `{:error, exception}` if even the `:en` fallback fails (should not happen in normal operation).

# locale_cache_dir()

    @spec locale_cache_dir() :: String.t()

Returns the directory in which downloaded locale data is cached.

The directory is resolved from the `:locale_cache_dir` application environment key for `:localize`, falling back to `default_locale_cache_dir/0` when unset.

### Returns

- A string path to the locale cache directory.

### Examples

    iex> is_binary(Localize.Locale.Provider.locale_cache_dir())
    true

# locale_file_name(locale_id)

    @spec locale_file_name(locale_id()) :: String.t()

Returns the file name for a locale's cached data file.

### Arguments

- `locale_id` is a locale identifier atom.

### Returns

- A string file name of the form `"{locale_id}.etf"`.

### Examples

    iex> Localize.Locale.Provider.locale_file_name(:en)
    "en.etf"

# locale_url(locale_id)

    @spec locale_url(locale_id()) :: String.t()

Returns the download URL for a given locale.

The URL is versioned by the current `Localize.version/0` so that each Localize release downloads from its own path.

### Arguments

- `locale_id` is a locale identifier atom.

### Returns

- A string URL from which the locale's data file can be downloaded.

### Examples

    iex> url = Localize.Locale.Provider.locale_url(:en)
    iex> String.starts_with?(url, "https://elixir-localize.com/locales/")
    true
    iex> String.ends_with?(url, "/en.etf")
    true

# version_segment()

    @spec version_segment() :: String.t()

Returns the version segment used in cache paths and download URLs.

### Returns

- A string of the form `"v{major}.{minor}.{patch}"` matching `Localize.version/0` with a `v` prefix.