Created
November 20, 2018 23:27
-
-
Save RichMorin/071f01e6b5d08d5670c35aba5bbc3211 to your computer and use it in GitHub Desktop.
concatenating the output of the link helper, take 4
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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