如何在没有布局的情况下呈现控制器操作?

How do I render a controller action without a layout?

我有一个特定的控制器动作,我想在没有任何布局的情况下呈现。

我尝试在控制器级别不使用插头进行渲染,但没有成功。

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

  plug :put_layout, nil

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

我该怎么做?

您只需调用 put_layout 并将 conn 和 false 传递给它。

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

plug :put_layout, nil 不起作用的原因是 the put_layout plug only considers false to mean "don't use any layout"nil 就像任何其他原子一样对待,Phoenix 尝试渲染 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

修复方法是使用 false:

plug :put_layout, false

如果想限制插件的某些动作,可以通过when:

plug :put_layout, false when action in [:index, :show]

如果您是 运行 LiveVeiw 应用程序,您的浏览器管道中可能会有 plug :put_root_layout, {MyAppWeb.LayoutView, :root}

在这种情况下 put_layout(false) 只会禁用应用程序布局,因此您必须使用 conn |> put_root_layout(false) 来禁用根布局。

您可能希望同时禁用两者,因此您需要:

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

或更短:

conn
|> put_root_layout(false)
|> render(..., layout: false)