Eiji
Extract gettext translations inside macro
Hi, I’m working on DSL and the last thing that I don’t like is how I’m extracting translations.
I have 2 version of code:
-
My current implementation is based on
Gettext.Extractorprivate API - it’s working without any issues -
An alternative is to use
Gettext.Macros.dpgettext_noop_with_backend/4. It’s also a solution which works very well, but unfortunately it does not allow function generators (other macros,forloops etc.) asGettextmacros requires binary literals.
defmodule MyApp.Example do
use MyLib.DSL, gettext_backend: MyApp.GettextBackend
for data <- ~w[first second third] do
some_dsl data
end
end
I understand that private API is unstable and can be changed at any time, but I have simply no idea about other possible solutions. From now on I can see only 2 ways to fix it:
-
Propose to make
Gettext.Extractora public API - that’s the simplest thing that could be done as it’s only about documenting code i.e. no change in code. -
Propose to support non-literals, so internal
Gettext.Extractorcalls are done withinquote do … endblock instead of directly inside macros.
Both solutions are rather something you consider at the very end. Support for gettext is only optional, so I don’t want to resign from function generators. The whole logic is done only in compile-time, so the generated code is as fast as possible in runtime.
With all above in mind I’m not satisfied in both implementations and I have no idea what to do with that. Did you had a similar problems with gettext when working on DSL? What do you think about making Gettext.Extractor public? Is there any other way to extract translations without above problems?
Marked As Solved
Eiji
Generating a .pot file using expo is definitely the best solution. I have a full control over code, I don’t need to worry about private APIs and it’s also a very simple thing to do.
Also Liked
LostKobrakai
I’d love if Gettext.Extractor could become public api. I had asked for that a few months back on a more esoteric usecase and given the usecase the response was negative. This sounds more in line with the libraries goals. But I wonder why you cannot provide binary literals if you’re in a macro context.
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.
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:
Doing it again will not make it faster ![]()
Popular in Questions
Other popular topics
Categories:
Sub Categories:
Forums
Popular Tags
- #ecto
- #liveview
- #troubleshooting
- #learning-elixir
- #deployment
- #library
- #erlang
- #testing
- #genserver
- #mix
- #absinthe
- #remote-other
- #otp
- #plug
- #how-to-question
- #macros
- #postgres
- #channels
- #elixirconf
- #exunit
- #discussion
- #code-sync
- #javascript
- #podcasts
- #onsite
- #dialyzer
- #docker
- #authentication
- #umbrella
- #full-time-contract
- #podcasts-by-brainlid
- #ecto-query
- #elixir-ls
- #phoenix_html
- #iex
- #blog-post
- #graphql
- #genstage
- #ai
- #websockets
- #supervisor
- #advent-of-code
- #elixirconf-us
- #distillery
- #processes
- #forms
- #api
- #metaprogramming
- #security
- #performance








