Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I render a controller action without a layout?

I have a particular controller action that I want to render without any layout.

I tried to render without a plug at the controller level, but it didn't work.

defmodule Hello.PageController do
  use Hello.Web, :controller

  plug :put_layout, nil

  def landing(conn, _params) do
    render conn, "landing.html"
  end
end

How can I do this?

like image 987
Sergio Tapia Avatar asked Sep 15 '16 04:09

Sergio Tapia


3 Answers

You just need to invoke put_layout and pass it the conn and false.

def landing(conn, _params) do
  conn = put_layout conn, false
  render conn, "landing.html"
end
like image 60
Sergio Tapia Avatar answered Nov 09 '22 01:11

Sergio Tapia


If you are running a LiveVeiw app, you'll likely have a plug :put_root_layout, {MyAppWeb.LayoutView, :root} in your browser pipeline.

In which case put_layout(false) will only disable the app layout, so you'll have to use conn |> put_root_layout(false) to disable root layout.

You are probably looking to disable both, so you'll need:

conn
|> put_layout(false) # disable app.html.eex layout
|> put_root_layout(false) # disable root.html.eex layout
|> render(...)

or shorter:

conn
|> put_root_layout(false)
|> render(..., layout: false)
like image 44
Sbbs Avatar answered Nov 08 '22 23:11

Sbbs


The reason plug :put_layout, nil does not work is because the put_layout plug only considers false to mean "don't use any layout". nil is treated just like any other atom and Phoenix tries to render nil.html:

Could not render "nil.html" for MyApp.LayoutView, please define a matching clause for render/2 or define a template at "web/templates/layout". The following templates were compiled:

  • app.html

The fix is to use false:

plug :put_layout, false

If you want to restrict the plug to certain actions, you can pass when:

plug :put_layout, false when action in [:index, :show]
like image 13
Dogbert Avatar answered Nov 09 '22 01:11

Dogbert