2013-12-09 220 views
8

我無法找到一種方法,做到以下幾點:軌道4嵌套佈局

讓我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> 

可能嗎?謝謝。

回答

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中添加新的右側菜單。

+0

但是如何獲得被調用的佈局的名稱?我期望'layout =='application'?產量:渲染布局「 –

8

我迄今爲止發現的乾淨的解決方案來自這個回購: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 %> 

就像一個魅力!我仍然在微笑着,終於找到了一個乾淨的解決方案

+0

今天發現您的評論,並立即使用它。這非常有用,謝謝! – dimitarvp

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,因爲執行中列出的嵌套佈局方法不必從子佈局轉到主佈局,然後返回到子佈局。相反,它更自然地流動,從主佈局開始,進入子佈局,然後在視圖結束。

0

如果你正在尋找一個乾淨的解決方案,它不夫婦application.html.erb其繼承元素,寶石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年(根據鏈接的博客文章的日期)。