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?
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
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)
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]
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With