Skip to content

Commit

Permalink
feat: configurable repository with init function
Browse files Browse the repository at this point in the history
  • Loading branch information
bamorim committed Apr 25, 2022
1 parent c3f9d31 commit fd9024b
Show file tree
Hide file tree
Showing 3 changed files with 64 additions and 25 deletions.
19 changes: 13 additions & 6 deletions lib/gettext/compiler.ex
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,13 @@ defmodule Gettext.Compiler do
default_domain = opts[:default_domain] || @default_domain

interpolation = opts[:interpolation] || Gettext.Interpolation.Default
repo = opts[:repo]

{repo, repo_opts} =
case opts[:repo] do
nil -> {nil, nil}
mod when is_atom(mod) -> {mod, mod.init([])}
{mod, opts} when is_atom(mod) -> {mod, mod.init(opts)}
end

plural_mod =
Keyword.get(opts, :plural_forms) ||
Expand Down Expand Up @@ -57,7 +63,7 @@ defmodule Gettext.Compiler do

unquote(macros())

unquote(public_functions(repo, interpolation, plural_mod))
unquote(public_functions(repo, repo_opts, interpolation, plural_mod))

unquote(compile_po_files(env, known_po_files, plural_mod, opts))

Expand Down Expand Up @@ -296,7 +302,7 @@ defmodule Gettext.Compiler do
end
end

defp public_functions(nil, _interpolation, _plural_mod) do
defp public_functions(nil, _repo_opts, _interpolation, _plural_mod) do
quote do
def lgettext(locale, domain, msgctxt \\ nil, msgid, bindings) do
lgettext_compiled(locale, domain, msgctxt, msgid, bindings)
Expand All @@ -308,10 +314,10 @@ defmodule Gettext.Compiler do
end
end

defp public_functions(repo, interpolation, plural_mod) do
defp public_functions(repo, repo_opts, interpolation, plural_mod) do
quote do
def lgettext(locale, domain, msgctxt, msgid, bindings) do
case unquote(repo).get_translation(locale, domain, msgctxt, msgid) do
case unquote(repo).get_translation(locale, domain, msgctxt, msgid, unquote(repo_opts)) do
{:ok, msgstr} ->
unquote(interpolation).runtime_interpolate(msgstr, bindings)

Expand All @@ -328,7 +334,8 @@ defmodule Gettext.Compiler do
domain,
msgctxt,
msgid,
plural_form
plural_form,
unquote(repo_opts)
) do
{:ok, msgstr} ->
bindings = Map.put(bindings, :count, n)
Expand Down
10 changes: 8 additions & 2 deletions lib/gettext/repo.ex
Original file line number Diff line number Diff line change
Expand Up @@ -11,16 +11,22 @@ defmodule Gettext.Repo do
@type msgid() :: binary()
@type plural_form() :: integer()
@type msgstr() :: binary()
@type opts() :: term()

@doc """
Called at compile time to configure the repository.
"""
@callback init(opts()) :: opts()

@doc """
Should return a singular translation string.
"""
@callback get_translation(locale(), domain(), msgctxt(), msgid()) ::
@callback get_translation(locale(), domain(), msgctxt(), msgid(), opts()) ::
{:ok, msgstr()} | :not_found

@doc """
Should return a plural translation string.
"""
@callback get_plural_translation(locale(), domain(), msgctxt(), msgid(), plural_form()) ::
@callback get_plural_translation(locale(), domain(), msgctxt(), msgid(), plural_form(), opts()) ::
{:ok, msgstr()} | :not_found
end
60 changes: 43 additions & 17 deletions test/gettext_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -903,47 +903,61 @@ defmodule GettextTest do
assert "quack foo %{} quack" = gettext("foo")
end

defmodule GettextTest.TranslatorWithRuntimeRepo do
use Gettext,
otp_app: :test_application,
repo: GettextTest.PersistentTermRepo
end

defmodule GettextTest.PersistentTermRepo do
@behaviour Gettext.Repo

use Agent

def start_link(_opts) do
Agent.start_link(fn -> nil end, name: __MODULE__)
def start_link(opts) do
name = Keyword.get(opts, :name, __MODULE__)
Agent.start_link(fn -> nil end, name: name)
end

def set_msgstr(msgstr) do
Agent.update(__MODULE__, fn _ -> msgstr end)
def set_msgstr(msgstr, name \\ __MODULE__) do
Agent.update(name, fn _ -> msgstr end)
end

def get_msgstr do
case Agent.get(__MODULE__, & &1) do
def get_msgstr(name \\ __MODULE__) do
case Agent.get(name, & &1) do
nil -> :not_found
msgstr -> {:ok, msgstr}
end
end

@impl Gettext.Repo
def get_translation(_locale, _domain, _msgctxt, _msgid) do
get_msgstr()
def init(name) when is_atom(name) do
name
end

def init(_), do: __MODULE__

@impl Gettext.Repo
def get_plural_translation(_locale, _domain, _msgctxt, _msgid, _plural_form) do
get_msgstr()
def get_translation(_locale, _domain, _msgctxt, _msgid, name) do
get_msgstr(name)
end

@impl Gettext.Repo
def get_plural_translation(_locale, _domain, _msgctxt, _msgid, _plural_form, name) do
get_msgstr(name)
end
end

defmodule GettextTest.TranslatorWithRuntimeRepo do
use Gettext,
otp_app: :test_application,
repo: GettextTest.PersistentTermRepo
end

defmodule GettextTest.TranslatorWithConfigurableRuntimeRepo do
use Gettext,
otp_app: :test_application,
repo: {GettextTest.PersistentTermRepo, :gettext_test_repo_name}
end

test "uses runtime repo" do
import GettextTest.TranslatorWithRuntimeRepo, only: [lgettext: 5, lngettext: 7]

{:ok, repo} = GettextTest.PersistentTermRepo.start_link([])
{:ok, _repo} = GettextTest.PersistentTermRepo.start_link([])

get_singular = fn -> lgettext("it", "default", nil, "Hello world", %{}) end

Expand All @@ -967,4 +981,16 @@ defmodule GettextTest do
assert get_singular.() == {:ok, "Runtime"}
assert get_plural.() == {:ok, "Runtime"}
end

test "runtime repo can be initialized with config value" do
import GettextTest.TranslatorWithConfigurableRuntimeRepo, only: [lgettext: 5]

{:ok, _repo1} = GettextTest.PersistentTermRepo.start_link([])
{:ok, _repo2} = GettextTest.PersistentTermRepo.start_link(name: :gettext_test_repo_name)

GettextTest.PersistentTermRepo.set_msgstr("Not this one")
GettextTest.PersistentTermRepo.set_msgstr("This one", :gettext_test_repo_name)

assert lgettext("it", "default", nil, "Hello world", %{}) == {:ok, "This one"}
end
end

0 comments on commit fd9024b

Please sign in to comment.