Closed. This may happen if there is an EEx interpolation inside a tag, which is not supported

I got error of this

def set_locale(assigns) do
    IO.inspect("====start====")
    IO.inspect(assigns.conn.query_params["locale"])
    IO.inspect("====end====")
    locale = assigns.conn.query_params["locale"]
    ~H"""
    <select name="lang" id="lang" class="lang-">
      <option value="ko" <%= if locale == "ko", do: "selected" else: "" %>>Korean</option>
      <option value="en" <%= if locale == "en", do: "selected" else: "" %>>English</option>
    </select>
    """
  end```

Compiling 1 file (.ex)

** (Phoenix.LiveView.Tokenizer.ParseError) lib/homepage_web/components/layouts.ex:13:26: expected closing `>` or `/>`

Make sure the tag is properly closed. This may happen if there
is an EEx interpolation inside a tag, which is not supported.
For instance, instead of

    <div id="<%= @id %>">Content</div>

do

    <div id={@id}>Content</div>

If @id is nil or false, then no attribute is sent at all.

Inside {...} you can place any Elixir expression. If you want
to interpolate in the middle of an attribute value, instead of

    <a class="foo bar <%= @class %>">Text</a>

you can pass an Elixir string with interpolation:

    <a class={"foo bar #{@class}"}>Text</a>

    (phoenix_live_view 0.20.3) lib/phoenix_live_view/tokenizer.ex:418: Phoenix.LiveView.Tokenizer.handle_maybe_tag_open_end/5
    (phoenix_live_view 0.20.3) lib/phoenix_live_view/tag_engine.ex:278: Phoenix.LiveView.TagEngine.handle_text/3
    (eex 1.16.0) lib/eex/compiler.ex:317: EEx.Compiler.generate_buffer/4
    (phoenix_live_view 0.20.3) expanding macro: Phoenix.Component.sigil_H/2
    (homepage 0.1.0) lib/homepage_web/components/layouts.ex:11: HomepageWeb.Layouts.set_locale/1

I don't know how to solve this

HEEx doesn’t allow the use of <%= %> eex tags to define attributes. Use attribute={expr} where expr evaluating to true or false would render as a boolean attribute.

1 Like

In this case you could also use this helper:

options_for_select(["Korean": "ko", "English": "en"], locale)
2 Likes

Thank you for the response. I ended up using the provided code. Is there a better or more optimized way to write this? Any suggestions are appreciated.

defmodule HomepageWeb.Layouts do
  use HomepageWeb, :html

  embed_templates "layouts/*"

  def set_locale(assigns) do
    locale = assigns.conn.params["locale"] || assigns.conn.cookies["locale"]
    ~H"""
    <select name="lang" id="lang" class="lang-">
      <%= if locale == "ko" do %>
        <option value="ko" selected>Korean</option>
      <% else %>
        <option value="ko">Korean</option>
      <% end %>
      <%= if locale == "en" do %>
        <option value="en" selected>English</option>
      <% else %>
        <option value="en">English</option>
      <% end %>
    </select>
    """
  end
end

I wanted to use the suggested approach, but nothing appeared. Could you please help me identify what I might have done wrong?

def set_locale(assigns) do
    locale = assigns.conn.params["locale"] || assigns.conn.cookies["locale"]
    ~H"""
    <select name="lang" id="lang" class="lang-">
      options_for_select(["Korean": "ko", "English": "en"], locale)
    </select>
    """
  end

In doing as you instructed, it seems to be working. Thank you!

defmodule HomepageWeb.Layouts do
  use HomepageWeb, :html

  embed_templates "layouts/*"

  def set_locale(assigns) do
    locale = assigns.conn.params["locale"] || assigns.conn.cookies["locale"]
    ~H"""
    <select name="lang" id="lang" class="lang-">
      <option value="ko" selected={locale == "ko"}>Korean</option>
      <option value="en" selected={locale == "en"}>English</option>
    </select>
    """
  end
end

is used to populate the options in a %Phoenix.HTML.Form{}.
You do not need that here, your solution is fine.

1 Like

The suggested function call was meant to go within <%= %> tags to execute.

1 Like