我无法找到办法执行以下操作:
让我们在我的application.html.erb中说我有以下
<div id="one" >
<%= yield %>
</div>
然后我想要另一个布局文件asdf.html.erb
<div id="two">
<%= yield %>
</div>
我希望最终输出为
<div id="one>
<div id="two">
<%= yield %>
</div>
</div>
有可能吗?感谢。
答案 0 :(得分:14)
我发现到目前为止最干净的解决方案来自此代表:https://github.com/rwz/nestive
我不想要整个宝石。如果你像我一样,这就是我实现我想要的方式:
# application_helper.rb
# From https://github.com/rwz/nestive/blob/master/lib/nestive/layout_helper.rb
def extends(layout, &block)
# Make sure it's a string
layout = layout.to_s
# If there's no directory component, presume a plain layout name
layout = "layouts/#{layout}" unless layout.include?('/')
# Capture the content to be placed inside the extended layout
@view_flow.get(:layout).replace capture(&block)
render file: layout
end
然后你保持/layouts/application.html.erb
不变!
您可以创建其他布局。就我而言/layouts/public.html.erb
和/layouts/devise.html.erb
:
# public.html.erb
<%= extends :application do %>
<%= render 'partials/navbar' %>
<div class="container margin-top">
<%= yield %>
</div>
<% end %>
# devise.html.erb
<%= extends :public do %>
<div class="col-sm-6 col-sm-offset-3">
<%= yield %>
</div>
<% end %>
像魅力一样!我还在微笑,我终于找到了一个干净的解决方案。
答案 1 :(得分:7)
默认情况下,application.html.erb
是您的布局。您可以通过从应用程序布局中将其调用为部分来呈现默认子布局:
# app/views/layouts/application.html.erb
<div id="one" >
<%= render "layouts/asdf" %>
</div>
# app/views/layouts/_asdf.html.erb
<div id="two">
<%= yield %>
</div>
这将输出以下内容:
<div id="one>
<div id="two">
<%= yield %>
</div>
</div>
或者,如果您希望逐个控制地有条件地渲染布局,则应考虑使用nested layouts。来自文档:
在NewsController生成的页面上,您想隐藏顶层菜单并添加右侧菜单:
# app/views/layouts/news.html.erb
<% content_for :stylesheets do %>
#top_menu {display: none}
#right_menu {float: right; background-color: yellow; color: black}
<% end %>
<% content_for :content do %>
<div id="right_menu">Right menu items here</div>
<%= content_for?(:news_content) ? yield(:news_content) : yield %>
<% end %>
<%= render template: "layouts/application" %>
新闻视图将使用新布局,隐藏顶部菜单并在“内容”div中添加新的右侧菜单。
答案 2 :(得分:4)
将asdf.html.erb
重命名为_asdf.html.erb
并将application.html.erb
重写为:
<div id="one">
<%= render 'asdf' %>
</div>
有关此处部分内容的更多信息:http://guides.rubyonrails.org/layouts_and_rendering.html#using-partials
答案 3 :(得分:1)
您还可以执行以下操作以有条件地呈现子布局:
# app/views/layouts/application.html.erb
<%= controller.controller_name.include?("foo") ? render("layouts/foo") : yield %>
# app/views/layouts/_foo.html.erb
<div class="bar">
<%= yield %>
</div>
对于只有一个子布局的场景,我发现这比Rails guide中概述的嵌套布局方法更可取,因为执行不必从子布局转到主布局,然后回到子布局。相反,它更自然地流动,从主布局开始,继续到子布局,然后在视图结束。
答案 4 :(得分:0)
如果你正在寻找一个干净的解决方案,它不会将application.html.erb与其继承元素耦合,那么gem nestive(正如另一个所指出的那样,但它似乎不适用于Rails 5.但这是另一种方法:https://mattbrictson.com/easier-nested-layouts-in-rails
# Place this in app/helpers/layouts_helper.rb
module LayoutsHelper
def parent_layout(layout)
@view_flow.set(:layout, output_buffer)
output = render(:file => "layouts/#{layout}")
self.output_buffer = ActionView::OutputBuffer.new(output)
end
end
然后asdf.html.erb
变为
<div id="two">
<%= yield %>
</div>
<% parent_layout 'application' %>
请注意,这依赖于Rails内部,并且可能会在将来的版本中停止工作。这不太可能很快发生,因为它至少已经工作了3年(根据链接博客文章的日期)。
答案 5 :(得分:0)
我多年来一直使用这种方法:
# app/helpers/layout_helper.rb
module LayoutHelper
def inside_layout(layout = 'application', &block)
render inline: capture(&block), layout: "layouts/#{layout}"
end
end
那么你的 asdf 布局将是:
# app/views/layouts/asdf.html.erb
<%= inside_layout do %>
<div id="two">
<%= yield %>
</div>
<% end %>