AshGettext (AshGettext v0.1.0)

Copy Markdown View Source

Translate the text an Ash app shows: strings, plurals, enum labels and attribute labels.

Enum values translate themselves: see AshGettext.Enum.

AshGettext.translate(MyApp.Gettext, "default", "Order shipped", [], "ru")
#=> "Заказ отправлен"

Every input is an argument, including the language, and nothing is read from global state. So a translation works the same from any process, and a test of one is a single assertion with no setup.

The text you write is the msgid. In the source language (the backend's configured :default_locale, else the global :gettext one, else "en") it is also the translation, so that language needs no catalog.

Missing translations are observable

translate_or_missing/5 reports {:missing, fallback} rather than silently handing back the msgid, so a test can assert that a string really is covered in a locale:

assert {:ok, _} = AshGettext.translate_or_missing(MyApp.Gettext, "default", "Order shipped", [], "ru")

The detection is gettext's own signal: a lookup that misses returns the msgid unchanged. In the source locale translate_or_missing/5 always reports :ok. In a translated locale, an identity translation (a catalog mapping a msgid to itself) is indistinguishable from a miss and is reported as :missing. Use translate/5 when you only want the string.

To translate Ash's error messages as well, see AshGettext.Domain.

Summary

Functions

The translated label of a resource attribute, in Gettext's current language.

The label of a resource attribute, reporting whether the catalog covered it.

The locales backend ships catalogs for.

The backend's source locale: the language its msgids are written in, which needs no catalog.

Translate msgid and return the string, falling back to the msgid on a miss.

Translate msgid, reporting whether the catalog actually covered it.

Translate a pluralised msgid, reporting whether the catalog covered it.

Types

backend()

@type backend() :: module()

bindings()

@type bindings() :: Keyword.t() | map()

locale()

@type locale() :: String.t()

msgid()

@type msgid() :: String.t() | atom()

text_domain()

@type text_domain() :: String.t()

Functions

attribute_label(resource, attribute)

@spec attribute_label(module(), atom()) :: String.t()

The translated label of a resource attribute, in Gettext's current language.

The text is the one you wrote in the resource's gettext block (label :delivery_date, "Delivery date"). It is never made from the attribute's code name. The backend and text domain come from the resource's domain (AshGettext.Domain). Misses fall back to the written text and are reported through telemetry. Raises ArgumentError for an unknown attribute, an attribute with no written label, or a resource whose domain has no gettext block.

attribute_label_or_missing(resource, attribute)

@spec attribute_label_or_missing(module(), atom()) ::
  {:ok, String.t()} | {:missing, String.t()}

The label of a resource attribute, reporting whether the catalog covered it.

known_locales(backend)

@spec known_locales(backend()) :: [locale()]

The locales backend ships catalogs for.

Derived from the backend rather than re-declared in config, so the supported list can never drift from the catalogs on disk.

source_locale(backend)

@spec source_locale(backend()) :: locale()

The backend's source locale: the language its msgids are written in, which needs no catalog.

translate(backend, text_domain, msgid, bindings, locale)

@spec translate(backend(), text_domain(), msgid(), bindings(), locale()) :: String.t()

Translate msgid and return the string, falling back to the msgid on a miss.

translate_or_missing(backend, text_domain, msgid, bindings, locale)

@spec translate_or_missing(backend(), text_domain(), msgid(), bindings(), locale()) ::
  {:ok, String.t()} | {:missing, String.t()}

Translate msgid, reporting whether the catalog actually covered it.

translate_plural(backend, text_domain, msgid, msgid_plural, count, bindings, locale)

@spec translate_plural(
  backend(),
  text_domain(),
  msgid(),
  msgid(),
  non_neg_integer(),
  bindings(),
  locale()
) :: String.t()

Translate a pluralised msgid, returning the string.

count is always available to the catalog as the %{count} binding, and it wins over a :count the caller happens to pass in bindings — the number that selected the plural form is the number the sentence shows.

translate_plural_or_missing(backend, text_domain, msgid, msgid_plural, count, bindings, locale)

@spec translate_plural_or_missing(
  backend(),
  text_domain(),
  msgid(),
  msgid(),
  non_neg_integer(),
  bindings(),
  locale()
) :: {:ok, String.t()} | {:missing, String.t()}

Translate a pluralised msgid, reporting whether the catalog covered it.