【问题标题】:Partial with multiple yields in rails在轨道中具有多个收益率的部分
【发布时间】:2013-06-18 10:36:15
【问题描述】:

我正在寻找具有多个yields 的部分解决方案。

在实际示例中,我有这样的视图结构:

基本 application.erb (/views/layouts/application.erb):

<!DOCTYPE html>
<head>
    <title>Some title</title>
</head>
<body>
<div class="page">
    <%= yield %>
</div>
</body>
</html> 

有些部分要干掉我的代码(/views/shared/content.erb):

<div class="content">
    <div class="sidebar">
        <%= yield :sidebar %>
    </div>
    <div class="main">
        <%= yield %>
    </div>
</div>

和控制器视图(/views/home/index.erb):

<%= render :partial => 'layouts/header' %>    
<%= render :partial => 'shared/navigation' %>

<% # It is close to what I want to do %>
<%= render :layout => 'shared/content' do %>
    <% content_for :sidebar do %>
        <%# This is will go to application.erb, not in content.erb %>
        <%= render :partial => 'shared/menu' %>
    <% end %>

    <%= yield %>
<% end %>

<%= render :partial => 'layouts/footer' %>

所以这里的主要问题是要有一个具有多个屈服区域的模板块,并且能够传递自定义 html 或呈现另一个部分。

【问题讨论】:

    标签: ruby-on-rails templates model-view-controller view


    【解决方案1】:

    这个问题很老,但是,当我在 Google 上搜索答案时,它仍然很重要。

    我想出了一个解决方案,虽然还不够漂亮,但效果很好。这个想法使用了 Rails 的capture 方法,它接受一个块并将其内容存储到一个变量中:

    controller.html.erb

    <%= render 'shared/partial', body: capture { %>
      My body content
    <% }, footer: capture { %>
      My footer content
    <% } %>
    

    shared/_partial.html.erb

    <div id="body"><%= body %></div>
    <div id="footer"><%= footer %></div>
    

    希望这对某人有所帮助!

    【讨论】:

      【解决方案2】:

      就我而言,我找到了这样的解决方案。

      在我的控制器视图上 (/views/home/index.erb):

      <% sidebar_content = render :partial => 'shared/slider' %>
      <%= render :layout => 'shared/content', :locals => {:sidebar => sidebar_content} do %>
          <%= yield %>
      <% end %>
      

      具有多个区域的部分(/views/shared/content.erb):

      <div class="content">
          <div class="sidebar">
              <%= sidebar %>
          </div>
          <div class="main">
              <%= yield %>
          </div>
      </div>
      

      这个解决方案看起来并不漂亮,但它确实有效。我希望在不久的将来能找到更好的东西。

      【讨论】:

      • 不。我用模板改变了我的工作流程。我只使用部分,并试图避免将另一个部分作为参数传递。特别是在提到的示例中,我将创建一个内部带有“菜单”的“内容”部分。 /shared/content/default.erb, /shared/content/with_menu.erb
      【解决方案3】:

      这是我的解决方案:

      /views/shared/_content.erb

      <div class="content">
          <div class="sidebar">
              <%= yield :sidebar %>
          </div>
          <div class="main">
              <%= yield %>
          </div>
      </div>
      

      views/home/index.erb

      
      <%= my_content_tag do %>
          <% content_for :sidebar do %>
              <%= render :partial => 'shared/menu' %>
          <% end %>
      
          <%= yield %>
      <% end %>
      

      app/helpers/my_tags_helper.rb

      module MyTagsHelper
        def my_content_tag(&block)
          sidebar_backup = @view_flow.content.delete(:sidebar)
          x = capture(&block)
          html = render('shared/content') { x }
          @view_flow.content[:sidebar] = sidebar_backup if sidebar_backup
          html
        end
      end
      

      关键是使用capture提取content_for块并将其传递给@view_flow

      【讨论】:

        猜你喜欢
        • 2011-01-28
        • 2014-08-22
        • 2012-11-26
        • 1970-01-01
        • 2011-10-07
        • 2011-04-20
        • 1970-01-01
        • 2019-04-14
        • 1970-01-01
        相关资源
        最近更新 更多