maennchen

maennchen

This works with a slight change (needs a quote / unquote cycle, not sure why):

defmodule DummyGettext do
  defmacro dummy_macro(input, _lang \\ "en") do
    # gettext macros require literals at this point (not within quote do … end block)
    IO.inspect(input)
    is_binary(input) == false && raise "gettext fail here"
  end

  def get_locales, do: ["en"]
end

defmodule MyLib.DSL do
  defmacro __using__(_opts \\ []) do
    quote do
      import MyLib.DSL

      require DummyGettext

      def translated_input(input, locale \\ "en")
    end
  end

  defmacro some_dsl(input) do
    quote do
      def translated_input(unquote(input), locale) do
        DummyGettext.dummy_macro(unquote(input), locale)
      end
    end
  end
end

defmodule MyApp.Example do
  use MyLib.DSL

  # this one obviously works
  some_dsl "text to translate"

  # my macros are fine with that, but gettext requires literal at compile time
  # so below code fails
  for data <- ["first", "second", "third"] do
    some_dsl unquote(data)
  end
end

There’s no need to create a function implementation per message / locale since gettext will already do that for you.

1
Post #11
Eiji

Eiji OP

Thanks, but this is not best for 2 reasons:

  1. data is better than unquote(data) - my DSL designed to be simply, so everyone can use it without …
  2. not sure why ): :smiley:

My main issue was about extracting message and private APIs. Generating a .pot file is best in my case.

That’s why it’s a small example. It’s part of a bigger DSL designed for fast runtime execution i.e. the gettext calls would happen only in compile time and yes in my case it makes sense, a very bad … I mean good … very good one! :smiling_imp:

0
Post #12
maennchen

maennchen

True, it’s a bit ugly. I wonder if that variable could be expanded somehow since unquote clearly also seems to be able to.

Sure, that works as well. Just make sure to either use a different domain from normal gettext or to not add the elixir-autogen flag. Otherwise you will get conflicts.

Gettext is already defining a function body for each message / locale:

https://github.com/elixir-gettext/gettext/blob/3a6e81ce64ae580af300c2abf825fef310314b2c/lib/gettext/compiler.ex#L605-L615

Doing it again will not make it faster :slight_smile:

1
Post #13
Eiji

Eiji OP

No need to worry about that. I’m using a custom domain every time. :slight_smile:

Also I’m not using any flag, because I generate a .pot file every time the module is re-compiled, so any new change will regenerate the template (pot file). Then I let gettext handle .po files.

Good point, I did not know that … It looks very complicated, so let’s summarise it if anyone is interested:

  1. Function in Gettext module calls a generated backend function
  2. When compiling backend (use Gettext.Backend, …) @before_compile Gettext.Compiler is generated
  3. So before backend module compiles a compiler module is then generating a function from .po files

I understand that, but I still use it as I’m not returning just translated text, so I can simply translate a text at compile time or work with quoted gettext call when dealing with AST from DSL. :thinking:

1
Post #14
— All posts loaded —