I’d like to concatenate the output of the link() helper into some HTML, but its output isn’t a string. Help?
-r
I’d like to concatenate the output of the link() helper into some HTML, but its output isn’t a string. Help?
-r
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…
-r
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>"]
end
links = submap
|> keyss()
|> Enum.map(link_f)
["<h3>Web Site</h3><ul>", links, "</ul>"]
end
# ...
end
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>
<ul>
<%= Enum.map(@sorted_keys, fn key -> %>
# note that `@hrefs[key]` might return nil
<li><%= link(key, to: @hrefs[key]) %></li>
<% end) %>
</ul>
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
~E"""
<h1><%= title %></h1>
"""
end
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.
-r
FWIW, here is a fairly complete module:
-r