Skip to content

Instantly share code, notes, and snippets.

@RichMorin
Created November 20, 2018 23:27
Show Gist options
  • Save RichMorin/071f01e6b5d08d5670c35aba5bbc3211 to your computer and use it in GitHub Desktop.
Save RichMorin/071f01e6b5d08d5670c35aba5bbc3211 to your computer and use it in GitHub Desktop.
concatenating the output of the link helper, take 4
I'm using a view function to create a heading and a list of links.
By way of context, here is the use case:
<%
import PhxHttpWeb.LayoutView
import RefData.Common
address = @item_data.address
types = ~w[ document email phone postal related web_site ]a
%>
<%= for type <- types do %>
<%= display(type, address) %>
<% end %>
Here is the (running, but fugly) code. FYI, keyss/1 returns a sorted list of keys
defmodule PhxHttpWeb.ResourcesView do
use PhxHttpWeb, :view
import RefData.Common
def display(type, address), do: dh1(type, address[type])
# display helper functions: dh[123]
#
# dh1 - add heading, generalize type
# dh2 - define formatting function
# dh3 - format heading and list
defp dh1(_, nil), do: ""
defp dh1(:document, map), do: dh2(:site, "Documents", map)
defp dh1(:email, map), do: dh2(:text, "Email Addresses", map)
defp dh1(:phone, map), do: dh2(:text, "Phone Numbers", map)
defp dh1(:postal, map), do: dh2(:post, "Postal Addresses", map)
defp dh1(:related, map), do: dh2(:site, "Related Pages", map)
defp dh1(:web_site, map), do: dh2(:site, "Web Pages", map)
defp dh2(:post, heading, map) do
item_f = fn key ->
lines = String.replace(map[key], "\n", "<br>\n")
[ "<li><b>#{ key }:</b><br> #{ lines }</li>" ]
end
dh3(heading, map, item_f)
end
defp dh2(:site, heading, inp_map) do
#
# Performs one level of symbol substitution (eg, "main|...")
# and removes entries with anonymous keys (eg, "_1").
reduce_f = fn ({key, inp_val}, acc) ->
fields = String.split(inp_val, "|")
out_val = if Enum.count(fields) == 2 do
[ pre_str, body] = fields
pre_atom = String.to_atom(pre_str)
prefix = inp_map[pre_atom]
"#{ prefix }#{ body }"
else
inp_val
end
Map.put(acc, key, out_val)
end
reject_f = fn {key, _val} ->
key
|> Atom.to_string()
|> String.starts_with?("_")
end
out_map = inp_map
|> Enum.reject(reject_f)
|> Enum.reduce(%{}, reduce_f)
# Pre-processing is over; format the item.
item_f = fn key ->
{:safe, iolist} = link(key, to: out_map[key])
[ "<li>", iolist, "</li>" ]
end
dh3(heading, out_map, item_f)
end
defp dh2(:text, heading, map) do
item_f = fn key ->
[ "<li><b>#{ key }:</b> #{ map[key] }</li>" ]
end
dh3(heading, map, item_f)
end
defp dh3(heading, map, item_f) do
items = map
|> keyss()
|> Enum.map(item_f)
|> raw()
~E"""
<h4><%= heading %></h4>
<ul><%= items %></ul>
"""
end
end
Any suggestions on making the code a bit cleaner?
-r
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment