Concatenating the output of the link helper into HTML?

I’d like to concatenate the output of the link() helper into some HTML, but its output isn’t a string. Help?


I suppose link() returns an iolist? And what’s the type of your HTML? If it’s an iolist as well, you can just take the iolist out of phoenix’s {:safe, iolist} and put it somewhere in your HTML iolist. Or maybe there is a function in phoenix that does just that.

The important thing here is that the HTML you work with in phoenix does not use strings as it’s datatype. This is for performance reasons and for distinguishing between sanitized html and content, which would need to be html escaped. If you want to concatinate what phoenix helpers produce and some strings, just put those in a list like ["prefix", link(…), "suffix"].

Following the kindly proffered hints, I modified my code and got it running.
However, it still seems a bit awkward. Suggestions welcome…


1 Like

It can look like this. That is, you don’t need to interpolate an iolist into a binary, you can just put it as an element of some other list.

  defmodule PhxHttpWeb.ResourcesView do
    use PhxHttpWeb, :view
    import RefData.Common

    def display(type, address), do: display_h(type, address[type])

    defp display_h(_, nil), do: ""

    defp display_h(:web_site, submap) do
      link_f  = fn key ->
        {:safe, iolist} = link(key, to: submap[key])
        ["<li>", iolist, "</li>"]

      links = submap
      |> keyss()
      ["<h3>Web Site</h3><ul>", links, "</ul>"]

    # ...

But, sure, further improvements are possible. For example, you can move this functionality to an .eex template.

# website_resource.html.eex
<h3>Web Site</h3>
<%=, fn key -> %>
  # note that `@hrefs[key]` might return nil
  <li><%= link(key, to: @hrefs[key]) %></li>
<% end) %>

You almost never need to build the list by hand, since you can use Phoenix.HTML’s sigile_E macro and stay in eex, for example:

def my_function(title) do
  <h1><%= title %></h1>

Combining some clues from idiot and chrismccord, I got something that works and seems fairly tidy:

However, I’m still not too happy with the link_f definition.


FWIW, here is a fairly complete module: