ProductPromotion
Logo

Elixir

made by https://0x3d.site

GitHub - crbelaus/trans: Embedded translations for Elixir
Embedded translations for Elixir. Contribute to crbelaus/trans development by creating an account on GitHub.
Visit Site

GitHub - crbelaus/trans: Embedded translations for Elixir

GitHub - crbelaus/trans: Embedded translations for Elixir

Trans

Tests Hex.pm

Trans provides a way to manage and query translations embedded into schemas and removes the necessity of maintaining extra tables only for translation storage. It is inspired by the great hstore translate gem for Ruby.

Trans is published on hex.pm and the documentation is also available online. Source code is available in this same repository under the Apache2 License.

On April 17th, 2017, Trans was featured in HackerNoon

Optional Requirements

Having Ecto SQL and Postgrex in your application will allow you to use the Trans.QueryBuilder component to generate database queries based on translated data. You can still use the Trans.Translator component without those dependencies though.

  • Ecto SQL 3.0 or higher
  • PostgreSQL 9.4 or higher (since Trans leverages the JSONB datatype)

Why Trans?

The traditional approach to content internationalization consists on using an additional table for each translatable schema. This table works only as a storage for the original schema translations. For example, we may have a posts and a posts_translations tables.

This approach has a few disadvantages:

  • It complicates the database schema because it creates extra tables that are coupled to the "main" ones.
  • It makes migrations and schemas more complicated, since we always have to keep the two tables in sync.
  • It requires constant JOINs in order to filter or fetch records along with their translations.

The approach used by Trans is based on modern RDBMSs support for unstructured datatypes. Instead of storing the translations in a different table, each translatable schema has an extra column that contains all of its translations. This approach drastically reduces the number of required JOINs when filtering or fetching records.

Trans is lightweight and modularized. The Trans module provides metadata that is used by the Trans.Translator and Trans.QueryBuilder modules, which implement the main functionality of this library.

Setup and Quickstart

Let's say that we have an Article schema that contains texts in English and we want to translate it to other languages.

defmodule MyApp.Article do
  use Ecto.Schema

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

The first step would be to add a new JSONB column to the table so we can store the translations in it.

defmodule MyApp.Repo.Migrations.AddTranslationsToArticles do
  use Ecto.Migration

  def change do
    alter table(:articles) do
      add :translations, :map
    end
  end
end

Once we have the new database column, we can update the Article schema to include the translations.

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

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

    # This generates a MyApp.Article.Translations schema with a
    # MyApp.Article.Translations.Fields for :es and :fr
    translations [:es, :fr]
  end
end

After doing this we can leverage the Trans.Translator and Trans.QueryBuilder modules to fetch and query translations from the database.

The translation storage can be done using normal Ecto.Changeset functions just like it would be done for any other fields or associations.

defmodule MyApp.Article do
  def changeset(article, attrs \\ %{}) do
    article
    |> cast(attrs, [:title, :body])
    |> validate_required([:title, :body])
    |> cast_embed(:translations, with: &cast_translations/2)
  end

  defp cast_translations(translations, attrs \\ %{}) do
    translations
    |> cast(attrs, [])
    |> cast_embed(:es)
    |> cast_embed(:fr)
  end
end

# Then, anywhere in your code:
changeset = MyApp.Article.changeset(article, %{
  translations: %{
    es: %{title: "title ES", body: "body ES"},
    fr: %{title: "title FR", body: "body FR"}
  }
})

Customizing the translation container

By default Trans looks for a translations field that contains the translations. This is known as the "translation container".

You can override the default translation container passing the container option to Trans. In the following example the translations will be stored in the transcriptions field.

defmodule MyApp.Article do
  use Ecto.Schema
  use Trans, translates: [:title, :body], default_locale: :en, container: :transcriptions

  schema "articles" do
    field :title, :string
    field :body, :strings
    translations [:es, :fr]
  end
end

Customizing the translation schemas

If you want to use your own translation module you can simply pass the build_field_schema: false option when using the translations macro.

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

  defmodule Translations.Fields do
    use Ecto.Schema

    embedded_schema do
      field :title, :string
      field :body, :string
    end
  end

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

    translations [:es, :fr], build_field_schema: false
  end
end

Is Trans dead?

Trans has a slow release cadence, but that does not mean that it is dead. Trans can be considered as "done" in the sense that it does one thing and does it well.

New releases will happen when there are bugs or new changes. If the last release is from a long time ago you should take this as a sign of stability and maturity, not as a sign of abandonment.

Articles
to learn more about the elixir concepts.

Resources
which are currently available to browse on.

mail [email protected] to add your project or resources here 🔥.

FAQ's
to know more about the topic.

mail [email protected] to add your project or resources here 🔥.

Queries
or most google FAQ's about Elixir.

mail [email protected] to add more queries here 🔍.

More Sites
to check out once you're finished browsing here.

0x3d
https://www.0x3d.site/
0x3d is designed for aggregating information.
NodeJS
https://nodejs.0x3d.site/
NodeJS Online Directory
Cross Platform
https://cross-platform.0x3d.site/
Cross Platform Online Directory
Open Source
https://open-source.0x3d.site/
Open Source Online Directory
Analytics
https://analytics.0x3d.site/
Analytics Online Directory
JavaScript
https://javascript.0x3d.site/
JavaScript Online Directory
GoLang
https://golang.0x3d.site/
GoLang Online Directory
Python
https://python.0x3d.site/
Python Online Directory
Swift
https://swift.0x3d.site/
Swift Online Directory
Rust
https://rust.0x3d.site/
Rust Online Directory
Scala
https://scala.0x3d.site/
Scala Online Directory
Ruby
https://ruby.0x3d.site/
Ruby Online Directory
Clojure
https://clojure.0x3d.site/
Clojure Online Directory
Elixir
https://elixir.0x3d.site/
Elixir Online Directory
Elm
https://elm.0x3d.site/
Elm Online Directory
Lua
https://lua.0x3d.site/
Lua Online Directory
C Programming
https://c-programming.0x3d.site/
C Programming Online Directory
C++ Programming
https://cpp-programming.0x3d.site/
C++ Programming Online Directory
R Programming
https://r-programming.0x3d.site/
R Programming Online Directory
Perl
https://perl.0x3d.site/
Perl Online Directory
Java
https://java.0x3d.site/
Java Online Directory
Kotlin
https://kotlin.0x3d.site/
Kotlin Online Directory
PHP
https://php.0x3d.site/
PHP Online Directory
React JS
https://react.0x3d.site/
React JS Online Directory
Angular
https://angular.0x3d.site/
Angular JS Online Directory