There is a lot of gems in Ruby to do what I would like in Elixir: globalize, multilang-hstore, hstore_translate
How to automate e.g. using Gettext.get_locale
retrieving translation according to current locale from hstore field? For example if I get it by related Post by post.tags
, tags will contain a list of strings in case of locale is :en: "tags: ["climbing", "ski"]"
instead of "tags":[{"name":{"pl":"narty","en":"ski"}},{"name":{"pl":"wspinaczka","en":"climbing"}}]
? How to handle fallbacks with Gettext?
defmodule Myapp.Tag do
use Myapp.Web, :model
schema "tags" do
field :name, :map
belongs_to :post, Myapp.Post
timestamps
end
def match(query, q) do
from tag in query,
where: fragment("?->>? ILIKE ?", tag.name, "en", ^(String.downcase(q) <> "%"))
end
end
defmodule Myapp.TagController do
use Myapp.Web, :controller
alias Myapp.Tag
def search(conn, %{"q" => q}) do
tags = Tag |> Tag.match(q) |> Repo.all
render(conn, "options.json", tags: tags)
end
end
defmodule Myapp.TagView do
use Myapp.Web, :view
def render("options.json", %{tags: tags}) do
%{options: render_many(tags, Myapp.TagView, "option.json")}
end
def render("option.json", %{tag: tag}) do
%{id: tag.id,
value: tag.name["en"],
label: tag.name["en"]}
end
end
defmodule Myapp.PostView do
use Myapp.Web, :view
def render("posts.json", %{posts: posts}) do
%{data: render_many(posts, Myapp.PostView, "post.json")}
end
def render("post.json", %{post: post}) do
%{id: post.id,
title: post.title,
tags: post.tags} # <= how to get translated keys
end
end
Gettext.get_locale Myapp.Gettext
should return according locale. When getting value from map, you can set the default value. For example:
Map.get(map, key, default)
So you can define function like:
defp translated_tag_name(tag, default_lang) do
current_lang = Gettext.get_locale Myapp.Gettext
Map.get(tag.name, current_lang, Map.get(tag.name[default_lang])
end
You do the fallback manually, but it is easy to make it work with any map.