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
Add
ecto_translateto your list of dependencies inmix.exs:def deps do[{:ecto_translate, "~> 0.1.0"}]endEnsure
ecto_translateis started before your application:def application do[applications: [:ecto_translate]]endCreate a migration for the translation table :
mix ecto.gen.migration create_translationsvi priv/repo/migrations/<date>_create_translations.exsdefmodule MyApp.Repo.Migrations.CreateTranslations douse Ecto.Migrationdef change docreate table(:test_model) doadd :title, :stringadd :description, :stringendcreate table(:translations) doadd :translatable_id, :integeradd :translatable_type, :stringadd :locale, :stringadd :field, :stringadd :content, :texttimestampsendcreate index :translations, [:translatable_id, :translatable_type]create index :translations, [:translatable_id, :translatable_type, :locale]create unique_index(:translations, [:translatable_id, :translatable_type, :locale, :field])endendMigrate
mix ecto.migrateUpdate your config.exs and add these settings
config :ecto_translate, repo: MyApp.Repo, gettext: MyApp.GettextAdd the macro to your model that you want to translate
defmodule MyApp.Post do...use EctoTranslate, [:title, :body]...schema "posts" dofield :title, :stringfield :body, :stringend...endSet translations for your data
record = MyApp.Repo.get(MyApp.Post, 1)EctoTranslate.set(record, locale: :nl, title: "Een nederlandse titel", description: "Een nederlandse beschrijving"]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"