How to replace deprecated ~E sigil with ~H in Phoenix render funciton

Background

In my quest to learn Phoenix LiveView I found myself using a render function that uses a deprecated sigil:

  def render(_assigns) do
    ~E"""
    <menubar>
      <menu label="<%= gettext "File" %>">
          <hr/>
          <item onclick="quit"><%= gettext "Quit" %></item>
      </menu>
      <menu label="<%= gettext "Extra" %>">
          <item onclick="browser"><%= gettext "Open Browser" %></item>
      </menu>
    </menubar>
    """
  end

Now, I understand this is a safe for to use eex code inside of Elixir. However the compiler says I should replace it with ~H. So my firs try is the following:

  def render(assigns) do
    ~H"""
    <menubar>
      <menu label="{@gettext('File')}">
          <hr/>
          <item onclick="quit"><%= gettext "Quit" %></item>
      </menu>
      <menu label="{@gettext 'Extra'}">
          <item onclick="browser"><%= gettext "Open Browser" %></item>
      </menu>
    </menubar>
    """
  end

Which does not work and does not show the text properly in the menu:

Capture

Quesion

What am I doing wrong?

You should remove the extra double-quotes around braces.

<menu label={@gettext('File')}>

1 Like

If I try that I get a compilation error:

Compiling 12 files (.ex)

== Compilation error in file lib/web_interface/menubar.ex ==
** (ArgumentError) cannot set attribute @gettext inside function/macro
    (elixir 1.13.1) lib/kernel.ex:3460: Kernel.do_at/5
    (elixir 1.13.1) expanding macro: Kernel.@/1
    lib/web_interface/menubar.ex:14: WebInterface.MenuBar.render/1
    (phoenix_live_view 0.17.5) expanding macro: Phoenix.LiveView.Helpers.sigil_H/2
    lib/web_interface/menubar.ex:12: WebInterface.MenuBar.render/1

Code:

  def render(assigns) do
    ~H"""
    <menubar>
      <menu label={@gettext("File")}>
          <hr/>
          <item onclick="quit"><%= gettext "Quit" %></item>
      </menu>
      <menu label="{@gettext 'Extra'}">
          <item onclick="browser"><%= gettext "Open Browser" %></item>
      </menu>
    </menubar>
    """
  end

I’m not sure why gettext has the @ infront of it. Did you try label={gettext("Extra")}?

2 Likes

I was adding the @ symbol in front because of the warning messages I was getting:

Replace: 
  < <%= symbol %> >
with: < {@symbol} >

Maybe I miss interpreted the message. But now it works ! Thanks !

  def render(assigns) do
    ~H"""
    <menubar>
      <menu label={gettext("File")}>
          <hr/>
          <item onclick="quit"><%= gettext "Quit" %></item>
      </menu>
      <menu label={gettext("Extra")}>
          <item onclick="browser"><%= gettext "Open Browser" %></item>
      </menu>
    </menubar>
    """
  end

I don’t quite understand why the compiler does not complain about the:

 <item onclick="browser"><%= gettext "Open Browser" %></item>

part however, since in theory, it is also using the deprecated form.

The <% %> is not deprecated, it just can’t be used in tag attributes. It’s perfectly fine (and the only way) to use these to interpolate Elixir values into the HTML.

4 Likes