我需要为Phoenix / Elixir应用程序创建一个简单的布局层次结构,并从不同的布局继承我的模板。我知道如何为单个布局和多个模板做到这一点。但是我怎样才能从另一个布局继承一个布局呢?
说,层次结构是layout1 - > layout2 - > layout3和template2(layout2),template3(layout3)。
在文档中没有提到这一点。
更新:
基本布局是基本布局 - 类似于OOP中的基类,它不知道它的子布局 - 有多少,如果有的话。因此,从基础中调用“render children1”是没有意义的。
答案 0 :(得分:2)
可以通过在调用render时在layout
中传递assigns
键来嵌套布局:
<%= render @view_module, @view_template, Map.put(assigns, :layout, {MyApp.LayoutView, "nested.html"}) %>
文档中的相关部分
分配
分配意味着将是用户数据 可在模板中使用。然而,有分配的钥匙 由凤凰专门处理,他们是:
:layout
- 告诉Phoenix将渲染结果包装成 给定布局。见下一节。以下分配是保留的,不能直接设置:
@view_module
- 正在呈现的视图模块@view_template
- 正在呈现的@view_module
模板## Layouts模板可以使用:layout
选项在其他模板中呈现。:layout
接受形式为元组的元组{LayoutModule, "template.extension"}
。渲染模板 在布局中,只需使用
render/3
拨打@view_module
即可 并@view_template
指定:<%= render @view_module, @view_template, assigns %>
对于3种布局,您可以执行以下操作:
# Controller
render(conn, "index.html", nested_1: "nested_1.html", nested_2: "nested_2.html")
# app.html.eex
<%= render @view_module, @view_template, Map.put(assigns, :layout, {MyApp.LayoutView, assigns.nested_1}) %>
# nested_1.html.eex
<%= render @view_module, @view_template, Map.put(assigns, :layout, {MyApp.LayoutView, assigns.nested_2}) %>
# nested_2.html.eex
<%= render @view_module, @view_template, assigns %>
答案 1 :(得分:2)
我解决这个问题的方法是在View中添加一个帮助器来渲染父布局:
defmodule MyApp.LayoutView do
use MyApp.Web, :view
def base_layout(conn, opts, do: contents) when is_list(opts) do
render "base.html", [conn: conn, contents: contents] ++ opts
end
end
&#34;内容&#34;帮助器中的参数将是您放在do / end块中的任何内容,因此您可以在HTML中使用它来进行&#34;子布局&#34;像:
<%= base_layout @conn, [foo: "bar"] do %>
<div class="sublayout-wrapper">
<%= render @view_module, @view_template, assigns %>
</div>
<!-- specific footer for sub-layout goes here etc -->
<% end %>
在base.html布局中,我输出@contents
变量,我需要在其中呈现内容,例如:
<html>
<head>
<title>My App</title>
</head>
<body>
<div class="header"></div>
<%= @contents %>
</body>
这有点像黑客,但到目前为止,这是我发现问题的最佳解决方案。
请注意,我还添加了opts
参数,以便能够在特定情况下覆盖某些分配(我主要使用此参数来定义要附加在<html>
或<body>
上的html css类取决于正在渲染的子布局。