Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Phoenix Framework - page titles per route

In the Phoenix Framework is there a common technique for setting a page title based on a route/path. Or is this just a matter of calling assign(:page_title, "fred") at the right point inside my routed function?

Update

I ended up implementing a variation of @michalmuskala's solution. I pass up the action name instead of @view_template:

<title><%= @view_module.title(action_name(@conn), assigns) %></title>

Then in the view module the code looks like this:

def title(:show, assigns), do: assigns.user.name <> " (@" <> assigns.user.user_name <> ")"
def title(:edit, _assigns), do: "Edit Profile"
def title(_action, _assigns), do: "User related page"

The last statement in the above code is an optional "catch all" for the module (and is something I'll probably only do while transitioning)

like image 297
Mitkins Avatar asked Feb 21 '17 08:02

Mitkins


1 Answers

A nice approach to handling titles is to realise that view is a module like every other one. This means you can define additional functions on it. On the other hand, in the layout you have access to the current view module - this means we can call the function we defined earlier.

Let's see how that would work in practice:

# The layout template
<title><%= @view_module.title(@view_template, assigns) %></title>

# In some view module
def title("show.html", _assigns) do
  "My awesome page!"
end

Thanks to passing both template name and assigns to the title function it works exactly like render/2 - we can pattern match on the template name and have access to all the assigns. We're calling the function unconditionally on all the views, so it has to be defined on all the views - we could add some additional check with function_exported?/3 and some default fallback title, but I think being explicit and defining it in every view isn't that much work and makes for a simpler code.

like image 55
michalmuskala Avatar answered Oct 08 '22 17:10

michalmuskala