Hexa's Blog

Phoenix and using multiple layouts

26/01/2016 Phoenix

1. How to specify the layout when render() in controllers

There is an option in render/3 method, source In the below example, I did specify the layout, the layout will be located at @conn.assigns[:layout], so as :id

defmodule ImageQuickShare.ImageController do
  use ImageQuickShare.Web, :controller
  def show(conn, %{"id" => id}) do
    render(conn, "show.html", id: id,
           layout: {ImageQuickShare.ImageView, "empty_layout.html"})
  end
end

The directory which locate layout look like:

templates
├── image
│   ├── empty_layout.html.eex
│   └── show.html.eex
├── layout
│   └── app.html.eex
└── page
    └── index.html.eex

2. Setup a default layout for all method within a controller

We have to use plug :put_layout.

defmodule ImageQuickShare.ImageController do
  use ImageQuickShare.Web, :controller
  plug :put_layout, {ImageQuickShare.ImageView, "empty_layout.html"}  #<--- HERE

  def show(conn, %{"id" => id}) do
    render(conn, "show.html", id: id)
  end
end

3. Get advanced from PLUG.

Because of using plug, we can also specify the defaul layout in router. In route.ex we can define an extra pipeline.

pipeline :empty_layout do
  plug :put_layout, {ImageQuickShare.ImageView, "empty_layout.html"}
end

And then, within scope, add the pipeline via pipe_through. Here is an example.

scope "/", ImageQuickShare do
  pipe_through [:browser, :empty_layout] # Use the default browser stack
  get "/", PageController, :index
  get "/image", ImageController, :show
end

REFERENCE