EctoTranslate

EctoTranslate is a library that helps with translating Ecto data. EctoTranslate can help you with returning translated values of your Ecto data attributes. For this it uses a singe table called "translations" which will contain polymorphic entries for all of your Ecto data stucts.

You might also be interested in set_locale which will enable urls like http://www.example.com/nl-nl/foo/bar and set the correct locale.

examples

Given an ecto module like :

defmodule MyApp.Post do
...
use EctoTranslate, [:title, :body]
...
schema "posts" do
field :title, :string
field :body, :string
end
...
end

You can set translations using :

record = MyApp.Repo.get(MyApp.Post, 1)
EctoTranslate.set(record, locale: :nl, title: "Een nederlandse titel", description: "Een nederlandse beschrijving"]

Then you can ask for a translated fields explicitly using :

iex> MyApp.Post.translated_title(post, :nl)
"Een nederlandse titel"

Or you can update the model by replacing the fields with their translations using :

iex> translated_post = MyApp.Post.translate!(post, :nl)
iex> translated_post.title
"Een nederlandse titel"
iex> translated_post.description
"Een nederlandse beschrijving"

You can also pass in a collection to translate in batch preventing n+1 queries

iex> posts = MyApp.Post |> MyApp.Repo.all
iex> translated_posts = MyApp.Post.translate!(posts, :nl)

If a translation is not found, it will fall back to the original database value. If you ommit the locale in the function calls, the current gettext locale will be used.

iex> Gettext.set_locale(MyApp.Gettext, :nl)
iex> translated_post = MyApp.Post.translate!(post)
iex> translated_post.title

Docs

Docs can be found here

Installation

  1. Add ecto_translate to your list of dependencies in mix.exs:

    def deps do
    [{:ecto_translate, "~> 0.1.0"}]
    end
  2. Ensure ecto_translate is started before your application:

    def application do
    [applications: [:ecto_translate]]
    end
  3. Create a migration for the translation table :

    mix ecto.gen.migration create_translations
    vi priv/repo/migrations/<date>_create_translations.exs
    defmodule MyApp.Repo.Migrations.CreateTranslations do
    use Ecto.Migration
    def change do
    create table(:test_model) do
    add :title, :string
    add :description, :string
    end
    create table(:translations) do
    add :translatable_id, :integer
    add :translatable_type, :string
    add :locale, :string
    add :field, :string
    add :content, :text
    timestamps
    end
    create index :translations, [:translatable_id, :translatable_type]
    create index :translations, [:translatable_id, :translatable_type, :locale]
    create unique_index(:translations, [:translatable_id, :translatable_type, :locale, :field])
    end
    end
  4. Migrate

    mix ecto.migrate
  5. Update your config.exs and add these settings

    config :ecto_translate, repo: MyApp.Repo, gettext: MyApp.Gettext
  6. Add the macro to your model that you want to translate

    defmodule MyApp.Post do
    ...
    use EctoTranslate, [:title, :body]
    ...
    schema "posts" do
    field :title, :string
    field :body, :string
    end
    ...
    end
  7. Set translations for your data

    record = MyApp.Repo.get(MyApp.Post, 1)
    EctoTranslate.set(record, locale: :nl, title: "Een nederlandse titel", description: "Een nederlandse beschrijving"]
  8. Use the translations

    iex> translated_post = MyApp.Post.translate!(post, :nl)
    iex> translated_post.title
    "Een nederlandse titel"

    or

    iex> MyApp.Post.translated_title(post, :nl)
    "Een nederlandse titel"