应用程序布局中的嵌套布局

时间:2014-02-14 17:56:56

标签: html ruby-on-rails ruby-on-rails-4 nestedlayout

我对嵌套布局几乎没有任何问题。在我的网站上,我只需要为管理员创建一个独立的网站部分。

我在application.html.erb文件中有这个:

<body>
    <%= render 'layouts/header' %>
    <div class="container">
        <%= yield %>
        <%= render 'layouts/footer' %>
    </div>
</body>

我想知道如何才能在<%= yield %>内插入另一个这样的模板,因为对于管理员部分我再次需要网站的固定部分,例如headerfooter布局。而不是headerfooter我会有两个菜单。我希望<%= yield %>填充新模板,其中包含顶部菜单和新<%= yield %>,其中将填充来自管理员控制器的操作。因此,菜单将始终保持最佳状态。

我已经将菜单部分views/admins/_menu.html.erb

<div>  
    <div>  
        <div class="container">  
            <ul>
                <li><%= link_to "Action1", '#' %></li>
                <li><%= link_to "Action2", '#' %></li>
                <li><%= link_to "Action3", '#' %></li>
            </ul>
        </div>  
    </div>  
</div> 

我的新布局是layouts/sublayouts/admin.html.erb

<%= render 'admins/menu' %>
<%= yield %>

目前替代方案是在每个视图中呈现views/admins/_menu.html.erb,但这对我来说不是一个好的解决方案。

常规网站将具有以下结构:

Header/Menu
   |
Container
   |Content
Footer

管理员网站将具有以下结构:

Header/Menu
   |
Container
   |Content
     |Admin Menu
     |Admin Content
   |
Footer

实现这一目标的最佳方法是什么?

2 个答案:

答案 0 :(得分:1)

更新:根据评论,我更新了答案并更好地理解了问题

最好的方法是将其合并到application.html.erb布局中。

当用户点击Admin Panel链接或管理菜单上的任何链接时,所需的行为是显示管理员菜单。

我建议这样做的方法是你有一个管理控制器来处理所有管理员视图的路由,所以点击Admin Panel按钮和管理菜单中的所有链接都将由你的管理员处理控制器。像这样在管理员控制器中添加一个before_filter:

# app/controller/admin_controller.rb
class AdminController < ActionController::Base
  before_filter: set_admin_status

  private
  def set_admin_status
   @admin = true
  end
end

在您的应用程序模板中,执行以下操作:

# application.html.erb
<body>
    <%= render 'layouts/header' %>
    <div class="container">
        <% if @admin %>
          <%= render 'admins/menu' %>
        <% end %>
        <%= yield %>
        <%= render 'layouts/footer' %>
    </div>
</body>

这应该做的是,每当您导航到与Admin Panel或管理菜单中的任何链接相对应的页面时,它都会将@admin_status标志设置为true,并且您的布局将呈现管理员菜单,我认为这是理想的行为。

答案 1 :(得分:1)

通常我会按照以下方法来完成同样的问题,我会根据父类创建单独的布局:

<强> application_controller.rb

class ApplicationController < ActionController::Base    
  protect_from_forgery
  layout :layout

  private
  def layout
    if self.class.parent == Admin
      'application_admin'
    else
      'application'
    end
  end
end

应用/视图/布局/ application.html.haml

Header/Menu
   |
Container
   |Content
Footer

应用/视图/布局/ application_admin.html.haml

Header/Menu
   |
Container
   |Content
     |Admin Menu
     |Admin Content
   |
Footer

更新1


<强>配置/ routes.rb中

namespace :admin do
  root to: 'home#index'
  resources :admins
end

应用/控制器/管理/ admins_controller.rb

class Admin::AdminsController < ApplicationController
  def index
    // code
  end
end