Phoenix link tag generated twice

Dear Elixir forum,

I truly hope that I’m not missing something very obvious here, for this would waste some people their time… But I’m facing the following situation:

Simply trying to generate an arrow up, arrow down, that can be click to order an item higher or lower in a list. This is the following code that I’m trying to achieve this: (using following icons)

              <%= link(tag(:i, class: "fa fa-angle-up"), to: "/link/moveup", method: :post) %>
              <%= link(tag(:i, class: "fa fa-angle-down"), to: "/link/movedown", method: :post) %>
              <%= link "Delete",
              to: Routes.link_path(@conn, :delete, link),
              method: "delete" %></td>

Which results in the following html code and how it looks like:


When I change the lines of code so that it’s first the Delete link, then an arrow, it doesn’t get generated twice. Am I doing something wrong or could this be a potential bug?

Thank you in advance,

Can you post the raw HTML that this generates? The DOM inspector can sometimes display odd things as it tries to “fix” broken markup.


Thank you for your quick answer.

<a data-csrf="fw0wEg4GNXkbHj9HAFpAKywgABRjJgAAHTjSLWy3ugZvfnscFQgG1w==" data-method="post" data-to="/link/moveup" href="/link/moveup" rel="nofollow"><i class="fa fa-angle-up"></i></a><i class="fa fa-angle-up">              
<a data-csrf="fw0wEg4GNXkbHj9HAFpAKywgABRjJgAAHTjSLWy3ugZvfnscFQgG1w==" data-method="post" data-to="/link/movedown" href="/link/movedown" rel="nofollow"><i class="fa fa-angle-down"></i></a><i class="fa fa-angle-down">
<a data-csrf="fw0wEg4GNXkbHj9HAFpAKywgABRjJgAAHTjSLWy3ugZvfnscFQgG1w==" data-method="delete" data-to="/link/1" href="/link/1" rel="nofollow">Delete</a></i></i>

This should be the relevant part (quickly dumped it all in a td element).

Thanks again in advance!

The link function accepts the string contents as the first arg. I actually wouldn’t have expected the above to work, but I need to check the source. Try this:

<%= link to: "/link/moveup", method: :post do %> 
  <%= tag(:i, class: "fa fa-angle-up") %>
<% end %>

Thank you for responding.
I’ve tried the following code: (as per your suggestion)

              <%= link to: "/link/moveup", method: :post do %> 
                <%= tag(:i, class: "fa fa-angle-up") %>
              <% end %>
              <%= link to: "/link/movedown", method: :post do %> 
                <%= tag(:i, class: "fa fa-angle-down") %>
              <% end %>

Which resulted in:

With the following raw html:

<a data-csrf="Qx0cETNnJwsLLCZUB1FnP10YM2cmEAAAtDFPq6kAeUCeaeTw7iT4tA==" data-method="post" data-to="/link/moveup" href="/link/moveup" rel="nofollow">                <i class="fa fa-angle-up">
</i></a><i class="fa fa-angle-up">              
<a data-csrf="Qx0cETNnJwsLLCZUB1FnP10YM2cmEAAAtDFPq6kAeUCeaeTw7iT4tA==" data-method="post" data-to="/link/movedown" href="/link/movedown" rel="nofollow"> 
<i class="fa fa-angle-down">              </i></a><i class="fa fa-angle-down">
<a data-csrf="Qx0cETNnJwsLLCZUB1FnP10YM2cmEAAAtDFPq6kAeUCeaeTw7iT4tA==" data-method="delete" data-to="/link/22" href="/link/22" rel="nofollow">Delete</a></i></i></td>

The problem remains I’m afraid. (right now solved it with images, that works. Not sure if patch is the correct action for this though…)

<%= img_tag("images/icons8-sort-down-24.png") |> link(to: Routes.link_path(@conn, :movedown, link), method: :patch)%>

How did you check the generated HTML? Did you use curl or a similar tool or did you use some view of your browser, the later might still be subject of DOM manipulation via scripts.

1 Like

Checked it with firefox, I’ll check it with curl as well. Editing this post soon!

<a data-csrf="KBhHPXYcNQc7DhhZbi8caUoQJXkhNgAAJ/uIOIP7Qf+0Azu/rjnATg==" data-method="post" data-to="/link/moveup" href="/link/moveup" rel="nofollow">                <i class="fa fa-angle-up"></a>              
<a data-csrf="KBhHPXYcNQc7DhhZbi8caUoQJXkhNgAAJ/uIOIP7Qf+0Azu/rjnATg==" data-method="post" data-to="/link/movedown" href="/link/movedown" rel="nofollow"> <i class="fa fa-angle-down"></a>
<a data-csrf="KBhHPXYcNQc7DhhZbi8caUoQJXkhNgAAJ/uIOIP7Qf+0Azu/rjnATg==" data-method="delete" data-to="/link/28" href="/link/28" rel="nofollow">Delete</a></td>

It is as you suggested @NobbZ! Though do you have any idea as to how this can help with finding a solution?

Check the output without having loaded any scripts, then add java script module by module, then you’ll see which one breaks your site, then debug that module.

Just using a default generated Phoenix project. The only js files that are getting compiled from webpack are socket.js (default) and app.js (default) which imports phoenix_html, does this mean that the “bug” is most likely in the phoenix_html package?

Can you try content_tag(:i, …)? This to me seems like a browser trying to fix improper html.


Im Not sure, perhaps the issue is in the font awesome provided scripts or styles? Disabling them will probably brake more :wink:

Have you tried with other symbols, or some content that is not font awesome? Perhaps an image?

1 Like

Oh, you are right, as I see now, the i tags don’t get closed.

1 Like

The output is: (tested with curl)

<i class="fa fa-angle-down"></i>              
              <a data-csrf="US9sIjgJOn1jDRsPCjcyJlhSKAhIJgAA9YUxHDMN6HxjCtUMkciqgA==" data-method="delete" data-to="/link/28" href="/link/28" rel="nofollow">Delete</a></td>

Adjusted the code to the following, ant this works:

<%= link(content_tag(:i, "", class: "fa fa-angle-up"), to: "/link/moveup", method: :post) %>
              <%= link(content_tag(:i, "", class: "fa fa-angle-down"), to: "/link/movedown", method: :post) %>

So… apparently “tag” is not usable for tags? is this normal behaviour?

tag/2 is a low level function which does only create a “tag”, aka <name {attrs}>. It doesn’t concern itself with the notion of opening/closing tag.


Thank you everyone! Going to mark @LostKobrakai his answer as the solution.

@NobbZ, thank you a lot as well! :smiley:

1 Like