如何在父窗体内渲染子布局?

时间:2016-09-17 04:24:21

标签: elixir phoenix-framework

我有一个基本的应用程序布局:

#layouts/base.html.eex
<body>
  <div id="base_layout.html">
  <!-- some content -->
    <%= render(@view_module, @view_template, assigns) %>
  <!-- some content -->
  </div>
</body>

我有20个其他不同的布局。我希望从base.html.eex继承所有这些内容。我怎样才能做到这一点?我试过这个:

#layouts/child_layout5.html.eex
<div id="child_layout5.html">
  <!-- some content -->
  <%= render(@view_module, @view_template, Map.put(assigns, :layout, {MyApp.LayoutView, "base.html"})) %>
</div>

但这只是将基本布局呈现为<div id="child_layout5.html">

而我希望反之亦然:从child_layoutXX.html.eex

呈现base.htmlchild_layoutXX.html.eex的内容

请注意,base.html不知道其子child_layoutXX.html.eex,有多少,如果有的话,他们的名字是什么,即base.html无法显式呈现任何一个孩子的名字。

迄今为止,函数https://hexdocs.pm/phoenix/Phoenix.View.html#render/3对我没有帮助。

1 个答案:

答案 0 :(得分:1)

这是您传递子布局以在render的分配地图中使用并让base布局处理使用它的一种方式。您可以为每个操作传递child_layout的不同值。这样base布局就没有任何硬编码的子布局。

# controllers/page_controller.ex
defmodule MyApp.PageController do
  use MyApp.Web, :controller

  def index(conn, _params) do
    conn
    |> put_layout("base.html")
    |> render("index.html", child_layout: "child_layout5.html")
  end
end
# templates/layout/base.html.eex
<body>
  <div id="base_layout.html">
    <%= render(@view_module, @view_template, Map.put(assigns, :layout, {MyApp.LayoutView, @child_layout})) %>
  </div>
</body>
# templates/layout/child_layout5.html.eex
<div id="child_layout5.html">
  <%= render(@view_module, @view_template, assigns) %>
</div>
# templates/page/index.html.eex
<!-- index.html -->

输出:

<body>
  <div id="base_layout.html">
<div id="child_layout5.html">
<!-- index.html -->
</div>
  </div>
</body>

修改:要使base模板在child_layout未通过时也可以使用,您可以执行以下操作:

<body>
  <div id="base_layout.html">
    <%= render(@view_module, @view_template, if(assigns[:child_layout], do: Map.put(assigns, :layout, {MyApp.LayoutView, @child_layout}), else: assigns)) %>
  </div>
</body>