0

One gotcha with new Phoenix 1.7 for me has been the dynamic parts of the layouts, i.e. meta tags for descriptions, preloading, canonical and whatnot. Open graph tags. Also optional JS scripts for things like AdSense or some captcha. And many more.

And it seems like the best way to approach this is through assigns. But building all those assigns in a controller seems strange to me, especially when it's about meta tags or JS. So my approach includes using presenter modules, something like that (pseudo code):

def show(conn, _) do
  conn
  |> assign(:adsense_script, AdsensePresenter.script_tag())
  |> assign(:open_graph, OpenGraphPresenter.tags())
  |> render(:show)
end

And while it's okay, it still feels like it doesn't belong in the controller, so I wonder if anyone has come up with more elegant solution to this?

UPDATE #1

Another idea that I have is to have a layout function that checks how the layout was rendered and calls a function from that module:

# layouts.ex

defp page_description(assings) do
  module_function(assigns, :page_description)
end

defp module_function(assigns, name) do
  module = assigns[:live_module] || view_module(assigns[:conn])

  if function_exported?(module, name, 1) do
    apply(module, name, [assigns])
  end
end

And then in HTML or Live modules add a function:

# main_page_html.ex or main_page_live.ex

def page_description(_) do
  "My main page description here"
end
NoDisplayName
  • 15,246
  • 12
  • 62
  • 98
  • 1
    Tbh I like the first approach the most. One thing I learned with phx is to not be too clever about implementing something. The second one has the cleaner approach and puts the things where they should belong.. but those already have some magic going one which for a new person on your codebase could be tricky. They have to know that there needs to be a `page_description/1` somewhere. Have you though about a plug which preassigns all required adsense/opengraph/js things? `plug MyApp.Plug.Analytics` on top of the controller. – Denny Mueller Jul 23 '23 at 13:23

0 Answers0