In a Phoenix template we are trying to check if a Phoenix.HTML.Safe
contains iodata that represents an HTML link. Based on whether it’s a link, we want to add a certain class to an element.
We want to check / pattern match on the given input and return true
when all the following conditions are met:
- The input is an “a” tag.
- The input is only one node / tag.
- The input can have surrounding whitespace.
Now, to check if the given input is a link, we had the following code:
defp link?({:safe, [60, "a" | _]}), do: true
defp link?({:safe, [" " <> _, [60, "a" | _] | _]}), do: true
defp link?(_), do: false
Example what it should do:
{:safe,
[
" ",
[60, "a", [[32, "href", 61, 34, "/", 34]], 62, "this is a link", 60, 47, "a", 62],
" "
]
}
|> link?()
true
That seemed dirty so we figured it might be better to convert the input by using safe_to_string/1
, escape it, and then pattern match or regex on the result.
That still feels tricky, so we now decided to use Floki to do the job, as it looks like a good way to go. However, we are curious as to the alternatives. So, are there any other (maybe simpler) options to achieve this?