View Source Trans (Trans v3.0.1)
Manage translations embedded into structs.
Although it can be used with any struct Trans
shines when paired with an Ecto.Schema
. It
allows you to keep the translations into a field of the schema and avoids requiring extra tables
for translation storage and complex joins when retrieving translations from the database.
Trans
is split into two main components:
Trans.Translator
- provides easy access to struct translations.Trans.QueryBuilder
- provides helpers for querying translations usingEcto.Query
(requiresEcto.SQL
).
When used, Trans
accepts the following options:
:translates
(required) - list of the fields that will be translated.:container
(optional) - name of the field that contains the embedded translations. Defaults to:translations
.:default_locale
(optional) - declares the locale of the base untranslated column.
storing-translations
Storing translations
To store translations in a schema you must use the translations
macro:
defmodule MyApp.Article do
use Ecto.Schema
use Trans, translates: [:title, :body], default_locale: :en
schema "articles" do
field :title, :string
field :body, :string
translations [:es, :fr]
end
end
This is equivalent to:
defmodule MyApp.Article do
use Ecto.Schema
use Trans, translates: [:title, :body], default_locale: :en
schema "articles" do
field :title, :string
field :body, :string
embeds_many :translations, Translations, primary_key: :false do
embeds_one :es, Fields
embeds_one :fr, Fields
end
end
end
defmodule MyApp.Article.Translations.Fields do
use Ecto.Schema
embedded_schema do
field :title, :string
field :body, :string
end
end
If you want to customize the translation fields (for example how they are casted) you may define them yourself manually. In such cases you may tell Trans not to generate the fields automatically for you:
defmodule MyApp.Article do
use Ecto.Schema
use Trans, translates: [:title, :body], default_locale: :en
schema "articles" do
field :title, :string
field :body, :string
# Define MyApp.Article.Translations.Fields yourself
translations [:es, :fr], build_field_schema: false
end
end
the-translation-container
The translation container
As we have seen in the previous examples, Trans
automatically stores and looks for translations
in a field called :translations
. This is known as the translations container.
In certain cases you may want to use a different field for storing the translations, this can
be specified when using Trans
in your module.
# Use the field `:locales` as translation container instead of the default `:translations`
use Trans, translates: [...], container: :locales
reflection
Reflection
Any module that uses Trans
will have an autogenerated __trans__
function that can be used for
runtime introspection of the translation metadata.
__trans__(:fields)
- Returns the list of translatable fields.__trans__(:container)
- Returns the name of the translation container.__trans__(:default_locale)
- Returns the name of default locale.
Link to this section Summary
Types
A locale that may be a string or an atom
When translating or querying either a single locale or a list of locales can be provided
A translatable struct that uses Trans
Functions
Checks whether the given field is translatable or not.
Create the translation container and fields.
Link to this section Types
Link to this section Functions
@spec translatable?(module() | translatable(), locale()) :: boolean()
Checks whether the given field is translatable or not.
Returns true if the given field is translatable. Raises if the given module or struct does not use
Trans
.
examples
Examples
Assuming the Article schema defined before.
If we want to know whether a certain field is translatable or not we can use this function as follows:
iex> Trans.translatable?(Article, :title)
true
iex> Trans.translatable?(%Article{}, :not_existing)
false
Raises if the given module or struct does not use Trans
:
iex> Trans.translatable?(Date, :day)
** (RuntimeError) Elixir.Date must use `Trans` in order to be translated
Create the translation container and fields.
This macro creates a field named like the module's translation container to store the
translations. By default YourModule.Translations
and YourModule.Translations.Fields
schemas will be created.
This macro creates an embedded field named after your "translation container" of type
YourModule.Translations
. This field in turn has an embedded field for each locale
of type YourModule.Translations.Fields
.
Calling:
translations [:en, :es]
Is equivalent to:
embeds_one :translations, Translations do
embeds_one :en, Fields
embeds_one :es, Fields
end
options
Options
- build_field_schema (boolean / default: false) wether to automatically generate the module for
locales or not. Set this to false if you want to customize how the field translations
are stored and keep in mind that you must create a
YourModule.Translations.Fields
schema.