【问题标题】:Nested layout inside application layout应用程序布局内的嵌套布局
【发布时间】:2014-02-14 17:56:56
【问题描述】:

我对嵌套布局没有什么问题。在我的网站上,我需要为网站制作一个单独的部分,仅供管理员使用。

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

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

我想知道现在如何制作另一个这样的模板以插入到 &lt;%= yield %&gt; 中,因为对于管理员部分,我再次需要在主布局中固定站点的部分,例如 headerfooter。我将有两个菜单,而不是 headerfooter。我希望&lt;%= yield %&gt; 填充新模板,该模板顶部有菜单,新的&lt;%= yield %&gt; 将填充来自管理控制器的操作。因此,菜单将始终位于顶部。

我做了一个部分菜单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

最好的方法是什么?

【问题讨论】:

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


    【解决方案1】:

    更新:根据 cmets,我更新了答案,以便更好地理解问题

    最好的方法是将其合并到您的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,并且您的布局将呈现管理菜单,我认为这是期望的行为。

    【讨论】:

    • 看起来不错,但是只有当我单击打开视图的按钮时,我才能完成该菜单才能显示管理菜单?目前它将与所有内容一起立即显示在首页。
    • 您能否澄清一下:您是否希望管理员导航到管理页面(因此只有一个视图可以呈现部分管理员/菜单),或者您是否拥有一个完整的管理员部分是一系列页面(因此您可以在多个视图中加载此部分)?
    • Ok :) 在标题内部我有带有链接的菜单(管理面板、Link2 等)。用户点击 Link2 后,链接内容显示在yield 处。但是在用户点击管理面板后,带有链接的新菜单(AdminMenuLink1 等)会显示在yield 中。现在我有两个菜单!管理员点击 AdminMenuLink1 后,内容显示在下方,但第二个菜单仍然存在。如果用户仅在该 menu2 内的链接(AdminMenuLink1 等)上导航,则菜单应始终存在。如果管理员从第一个菜单中单击 Link2,他将退出管理菜单并再次看到正常内容,而没有第二个菜单。
    • 好的,我想我明白你在说什么。让我更新我的答案。
    • 是的,这行得通!谢谢你。现在我唯一需要弄清楚的是,如果我需要一些由其他控制器处理的视图,如何离开该菜单。与set_admin_status 相同的技巧将不再起作用。
    【解决方案2】:

    通常我会执行以下操作来完成相同的问题,我会根据父类创建单独的布局:

    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
    

    app/views/layouts/application.html.haml

    Header/Menu
       |
    Container
       |Content
    Footer
    

    app/views/layouts/application_admin.html.haml

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

    更新 1


    config/routes.rb

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

    app/controllers/admin/admins_controller.rb

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

    【讨论】:

    • 这段代码我没有成功。这行if self.class.parent == Admin 比较的是当前控制器的名称“Admin”吗?就我而言,我设置了if self.class.parent == AdminsController
    • @user3304086 我已经更新了帖子,很快你应该将你的admins_controller.rb 移动到app/controllers/admin 命名空间
    • 嗯,现在我收到以下错误:Could not render layout: uninitialized constant ApplicationController::Admin
    • 和你的一样。它说这是我控制所有静态页面的主控制器中的 NameError。不在 AdminsController..
    猜你喜欢
    • 2013-08-22
    • 2013-06-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多