Hello everyone
I’ve been learning Elixir for a few months now and just published my first Hex package
Any feedback is welcome.
This library might be relevant to you if you need to store translations in the database (e.g. user-generated content), and want to store these translations in a JSON data type (as opposed to storing them in separate tables).
You can manage that by just using the Ecto’s :map
field type, but the idea of this library is to provide a set of helpers to ease working with such embedded translations.
The library expects you to store a map of translations for each field. For example:
%Post{
title: %{"en" => "The title", "fr" => "Le titre"},
body: %{"en" => "The content", "fr" => "Le contenu"}
}
In brief, the library helps you translating your Ecto struct and its associations for a given locale (in one call), with a fallback locale and a handler for missing translations.
post =
Repo.all(Post)
|> Repo.preload(:category)
|> Repo.preload(:comments)
|> Translator.translate("fr", fallback_locale: "en")
assert post.translated_title == "Le titre"
assert post.category.translated_name == "La catégorie"
assert List.first(post.comments).translated_text == "Un commentaire"
As you might already understand from the example above, by “translating an Ecto struct”, it is meant extracting the texts (from the different translations’ maps) for a given locale and fallback locale, and set them in a virtual field (which is named by the field it retrieved the text from prefixed by “translated_”).
It is done recursively for the struct and all their loaded associations.
It is particularly useful if you need to use different fallback locales throughout your application as is my case, or if you need to be notified for missing translations.
This library differs from other similar libraries where:
- translations are stored in a JSON data type (in Postgres that will be
jsonb
type); - each field has its translations map (as opposed to one big translation map for all fields);
- there is no notion of “main” locale, all the texts are stored in the map (but you can specify a fallback locale);
- translations for a given locale are retrieved in one call for an Ecto struct and all its associations;
- a fallback locale and a handler for missing translations may be provided.