How to write correct view helper

defmodule Promo.OrderView do
  use Promo.Web, :view
 alias Promo.Page

 def page_title(page = %Page{}) do
    for {tag, class} <- [h5: "hide-on-small-only", h6: "hide-on-med-and-up"] do
      content_tag tag, class: class do
        page.title <> page_sub_title(page.sub_title)
      end
    end
  end

   def page_sub_title(nil), do: ""
   def page_sub_title(sub_title) do
     "<br><small>" <> sub_title <> "</small>"
  end
end    

In view i see escaped html string with small and etc.
How to write helper function “page_title” what return to me:
h2 title + br + small sub_title /small /h2, but
only h2 title /h2 if sub_title do not exists??

1 Like

For any view helpers, first I have these at the top of my module:

  import Phoenix.HTML
  import Phoenix.HTML.Form
  import Phoenix.HTML.Link
  import Phoenix.HTML.Tag

Just for convenience sakes.

However, to do what you want:

  def page_sub_title(nil), do: ""
  def page_sub_title(sub_title) do
    ~e"""
    <br><small><%= sub_title %></small>
    """
  end

The ~e sigil when you import the Phoenix view stuff gives you inline ‘eex’ templating, just like eex files. This is the best way to work with it.

However, you can always wrap your output in a {:safe, content} tuple, but that is not recommended unless you are sure it is entirely safe, and considering I do not see where sub_title is coming from (possibly user input through database or so), I’d use eex to make sure everything gets properly escaped or bad bad bad things can happen.

5 Likes

Thanks for reply!
But now i have an error “argument error” in view.
This code does not work

defmodule Promo.OrderView do
  use Promo.Web, :view
  alias Promo.Page

  def page_title(page = %Page{}) do
    for {tag, class} <- [h5: "hide-on-small-only", h6: "hide-on-med-and-up"] do
      content_tag tag, class: class do
        page.title <> page_sub_title(page.sub_title)
      end
    end
  end

  def page_sub_title(nil), do: ""
  def page_sub_title(sub_title) do
    ~e{<br><small><%= sub_title %></small>}
  end
end

I find correct answer. Thanks for help

def page_title(page = %Page{}) do
    for {tag, class} <- [h5: "hide-on-small-only", h6: "hide-on-med-and-up"] do
      content_tag tag, class: class do
        do_page_title(page.title, page.sub_title)
      end
    end
  end

  defp do_page_title(title, nil), do: title
  defp do_page_title(title, sub_title) do
    ~e{<%= title %><br><small><%= sub_title %></small>}
  end