Set the <head> and <body> from the same eex file

Viewed 41

In a particular new website using Elixir and Phoenix, there is lots of boilerplate in order to make the pages have a consistent style. Hence there is a "layout" template whose inner_content delegation is inside the html <body> tag (and a couple <div>s for styling). However, some parts of the <head> actually do change page-to-page, and these aren't just a few trivial values like the <title/>, there's a bunch of SEO metadata too.

Worse yet, there's probably enough visible boilerplate in each page, that significant nontrivial parts of the <body> probably ought to be factored out of the individual templates and into the layout, yet those parts might also contain title-like values.

How do I specify arbitrary extra content for the <head>, or for other places outside the one place where the vast majority of page-to-page-variable content goes, without getting an unmaintainable anti-DRY mess? (Where I come from, a child template could divide itself up into multiple named blocks that a layout template could substitute by-name at multiple different places within itself.)

1 Answers

I believe the correct thing to do is to use assigns field on the [Plug.Conn][1]

In my Pheonix (v 1.6.10) there's pre-decided page_title assigns, so just do this:

conn
|> assign(:page_title), "My Special title")

and it just works, because my root.html.heex has this:

<%= live_title_tag assigns[:page_title] || "Rumbl", suffix: " · Phoenix Framework" %>

And I suppose this is the right thing to do with any other custom stuff, like SEO medatada:

conn
|> assign(:my_seo_metadata), "Whatever")

and add in your template

<whatever>
<%= assigns[:my_seo_metadata] %>
</whatever>
Related