Packages
fermo
0.14.0
0.20.1
0.20.0
0.19.2
0.19.1
0.19.0
0.18.1
0.18.0
0.17.1
0.17.0
0.16.7
0.16.6
0.16.5
0.16.4
0.16.3
0.16.2
0.16.1
0.16.0
0.15.0
0.14.9
0.14.8
0.14.7
0.14.6
0.14.5
0.14.4
0.14.3
0.14.2
0.14.1
0.14.0
0.13.9
0.13.8
0.13.7
0.13.6
0.13.5
0.13.4
0.13.2
0.13.1
0.13.0
0.12.1
0.12.0
0.11.1
0.11.0
0.10.0
0.9.1
0.9.0
0.8.4
0.8.3
0.8.2
0.8.1
0.8.0
0.7.1
0.7.0
0.6.4
0.6.3
0.6.2
0.6.1
0.6.0
0.5.1
0.5.0
0.4.0
0.3.0
0.2.4
0.2.2
0.2.1
0.2.0
0.1.8
0.1.7
0.1.6
0.1.5
0.1.4
0.1.3
0.1.2
0.1.1
0.1.0
A static site generator
Current section
Files
Jump to
Current section
Files
lib/i18n.ex
defmodule I18n do
use GenServer
def init(args) do
{:ok, args}
end
def start_link() do
GenServer.start_link(__MODULE__, nil, name: :i18n)
end
def put(translation_tree) do
{:ok, collapsed} = collapse(translation_tree)
{:ok} = GenServer.call(:i18n, {:put, {collapsed}})
end
def translate(key, parameters \\ %{}, locale)
def translate(key, parameters, locale) when is_list(key) and is_atom(locale) do
translate(to_string(key), parameters, locale)
end
def translate(key, parameters, locale) when is_atom(locale) do
GenServer.call(:i18n, {:translate, key, parameters, locale})
end
def translate!(key, parameters \\ %{}, locale) do
{:ok, translation} = translate(key, parameters, locale)
translation
end
def handle_call({:put, state}, _from, _state) do
{:reply, {:ok}, state}
end
def handle_call({:translate, key, parameters, locale}, _from, {translations} = state) do
translated = translations[locale][key]
translation = substitute(translated, parameters)
{:reply, {:ok, translation}, state}
end
# We want to turn the nested structure into a simple Map
# with keys like "a.b.c"
defp collapse(translation_tree) do
collapsed = Enum.reduce(translation_tree, %{}, fn ({locale, tree}, acc) ->
nested = do_collapse(tree, [])
twoples = List.flatten(nested)
flat_map = Enum.into(twoples, %{})
put_in(acc, [locale], flat_map)
end)
{:ok, collapsed}
end
defp do_collapse(tree, parents) when is_map(tree) do
Enum.map(tree, fn ({k, v}) -> do_collapse({k, v}, parents) end)
end
defp do_collapse({key, map}, parents) when is_map(map) do
do_collapse(map, parents ++ [key])
end
defp do_collapse({key, value}, parents) do
keys = Enum.join(parents ++ [key], ".")
{keys, value}
end
defp substitute(translation, parameters) when parameters == %{} do
translation
end
defp substitute(translation, parameters) do
Regex.replace(
~r/%\{([^}]+)\}/,
translation,
fn _match, key -> parameters[String.to_atom(key)] || "" end
)
end
end