# `Cldr.Trans`
[🔗](https://github.com/elixir-cldr/cldr_trans/blob/v1.1.3/lib/cldr_trans.ex#L1)

Manage translations embedded into translation structs.

Although it can be used with any struct **`Cldr.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.

`Cldr.Trans` is split into two main components:

* `Cldr.Trans.Translator` - provides easy access to struct translations.
* `Cldr.Trans.QueryBuilder` - provides helpers for querying translations using `Ecto.Query`
  (requires `Ecto.SQL`).

When used, `Cldr.Trans` accepts the following options:

* `:translates` (required) - list of the fields that will be translated.
* `:default_locale` (optional) - declares the locale of the base untranslated column.
  Defaults to the `default_locale` configured for the Cldr backend.

### Structured translations

Structured translations are the preferred and recommended way of using `Trans`. To use structured
translations, use the `translations/1` macro when defining a schema. The `translations/1` macro
will define an embedded schema with the name being the parameter passed to the `translations/1`
macro. Within the `:translations` field that is generated, an `embeds_one/2` call is added for
locale configured in the `MyApp.Cldr` backend module. Here's an example schema configuraiton:

    defmodule MyApp.Article do
      use Ecto.Schema
      use MyApp.Cldr.Trans, translates: [:title, :body]

      schema "articles" do
        field :title, :string
        field :body, :string
        translations :translations
      end
    end

When expanded by the Elxir compiler, the example above will look like the following code
(assuming the `MyApp.Cldr` is configured with three locales: `:en`, `:es` and `:fr`). It is
provided here only as an example to show what the `translations/1` macro compiles to.

    defmodule MyApp.Article do
      use Ecto.Schema
      use MyApp.Cldr.Trans, translates: [:title, :body]

      schema "articles" do
        field :title, :string
        field :body, :string

        embeds_one :translations, Translations, on_replace: :update, primary_key: false do
          embeds_one :es, MyApp.Article.Translations.Fields
          embeds_one :fr, MyApp.Article.Translations.Fields
        end
      end
    end

    defmodule MyApp.Article.Translations.Fields do
      use Ecto.Schema

      @primary_key false
      embedded_schema do
        field :title, :string
        field :body, :string
      end
    end

### 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. The locale of the fields
  in the main schema are considered to be in the language of the default locale.

# `field`

```elixir
@type field() :: atom()
```

A struct field as an atom.

# `locale_list`

```elixir
@type locale_list() ::
  Cldr.Locale.locale_reference() | [Cldr.Locale.locale_name(), ...]
```

When translating or querying either a single
locale or a list of locales can be provided.

# `translatable`

```elixir
@type translatable() :: struct()
```

A translatable struct that uses `Trans`.

# `translatable?`

```elixir
@spec translatable?(module() | translatable(), String.t() | atom()) :: 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

Assuming the Article schema defined in [Structured translations](#module-structued-translations).

If we want to know whether a certain field is translatable or not we can use
this function as follows (we can also pass a struct instead of the module
name itself):

    iex> Trans.translatable?(Article, :title)
    true

May be also used with translatable structs:

    iex> article = %Article{}
    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

# `translations`
*macro* 

# `translations`
*macro* 

---

*Consult [api-reference.md](api-reference.md) for complete listing*
