Packages
fermo
0.3.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__, [], 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) do
translate(to_string(key), parameters, locale)
end
def translate(key, parameters, 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 t(key, locale) do
translate!(key, locale)
end
def handle_call({:put, state}, _from, _state) do
{:reply, {:ok}, state}
end
def handle_call({:translate, key, parameters, locale}, _from, {translations} = state) do
translation = substitute(translations[locale][key], 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, %{}), do: translation
defp substitute(translation, parameters) do
Regex.replace(
~r/%\{([^}]+)\}/,
translation,
fn _match, key -> parameters[String.to_atom(key)] || "" end
)
end
end