Heex: Macro support in custom components?

Is there a plan to support macros in custom components in heex (or are they somehow already supported)? Currently, macro functions are called without any relevant information:

defmacro example(arg) do
  arg |> IO.inspect
  quote, do: ""
end

# in heex:
<%= example foo: 42 %>
<.example foo={42}/>

The first call an AST including :foo and 42, but the second call using a component does not (I get {:x1, [], :elixir_fn}).

Usecase: I’d like to use gettext to generate labels, titles, etc., but at compile time so the usual tasks to find them still work.

Do you mind throwing together a minimal example repro? I might be able to poke around in it if so.

Sure. Here’s a repo; this last commit gives an example. If you need to try it, clone it, then cd basic_phoenix/my_app && mix deps.get && mix.compile.
It will print:

"This will print, at compile time, a string containing 42"
[foo: 42]
"The goal is to also print here, at compile time, a string containing 42"
{:x1, [], :elixir_fn}

Why not use just <%= gettext("title") %>. This would also make it much easier for mix gettext.extract to find that string.

That means all the places supplying text need to call gettext(text) instead of just providing text as an assign and the component would make sure they’re wrapped in gettext(…) calls.

Exactly. The whole point is so that I can write <.text_field field={:first_name}/> instead of having to use <.text_field field={:first_name label={gettext(:labels, "first_name")}> but with mix gettext.extract still working.

José Valim confirmed that there is no solution currently. Either I use a macro and <%= %> form, or I manage to convince my team to use surface.

1 Like