Несколько content_for на одной странице - PullRequest
8 голосов
/ 12 апреля 2011

У меня в приложении большой блок HTML, который я хотел бы переместить в общий шаблон, а затем использовать content_for с выходами для вставки необходимого контента.Однако, если я использую его более одного раза в одном и том же файле макета, content_for просто добавляется к предыдущему, что делает эту идею неэффективной.Есть ли решение для этого?

<div class="block side">
    <div class="block_head">
        <div class="bheadl"></div>
        <div class="bheadr"></div>
        <h2><%= yield :block_head %></h2>
    </div>
    <div class="block_content">
        <%= yield :block_content %>
    </div>
    <div class="bendl"></div>
    <div class="bendr"></div>
</div>

, и я использую следующий код для установки содержимого для блока

    <%= overwrite_content_for :block_head do -%>
        My Block
    <% end -%>
    <%= overwrite_content_for :block_content do -%>
        <p>My Block Content</p>
    <% end -%>
    <%= render :file => "shared/_blockside" %>

Проблема заключается в том, если я использую это несколько раз на одном и том жемакет содержимого из исходного блока добавляется к дополнительному блоку

Я попытался создать собственный вспомогательный метод, чтобы обойти его, однако он не возвращает никакого содержимого

  def overwrite_content_for(name, content = nil, &block)
    @_content_for[name] = ""
    content_for(name, content &block)
  end

Я могуЯ также хотел бы знать, что, если это не так, то, если есть какие-то более эффективные способы заставить контент работать так, как я.Спасибо.

Ответы [ 5 ]

14 голосов
/ 19 декабря 2013

В Rails 4 вы можете передать параметр: flush для переопределения содержимого.

<%= content_for :block_head, 'hello world', :flush => true %>

или, если вы хотите передать блок,

<%= content_for :block_head, :flush => true do %>
  hello world
<% end %>

cf. исходный код этого помощника для более подробной информации

2 голосов
/ 30 октября 2012

Вы всегда можете просто передать контент напрямую и не полагаться на блок:

<% content_for :replaced_not_appended %>
2 голосов
/ 17 апреля 2011

Вы должны определить свой overwrite_content_for следующим образом (если я правильно понимаю ваш вопрос):

  def overwrite_content_for(name, content = nil, &block)
    content = capture(&block) if block_given?
    @_content_for[name] = content if content
    @_content_for[name] unless content
  end

Обратите внимание, что если ваш блок даст ноль, то старое содержимое будет сохранено. Однако сама идея звучит не очень хорошо, так как вы, очевидно, дважды выполняете рендеринг (или, по крайней мере, создание объекта).

0 голосов
/ 12 апреля 2011

Я не уверен, что я действительно понимаю ваш вопрос - вот один подход в коде, который работает:

view:

<% content_for :one do %>
  Test one
<% end %>

<% content_for :two do %>
  Test two
<% end %>

<p>Hi</p>

application.html.erb

<%= yield :one %>
<%= yield %>
<%= yield :two %>

Рельсовые направляющие: http://guides.rubyonrails.org/layouts_and_rendering.html#using-content_for

0 голосов
/ 12 апреля 2011

Вы можете использовать именованные блоки content_for и yield, например:

Вид:

<% content_for :heading do %>
  <h1>Title of post</h1>
<% end %>

<p>Body text</p>

<% content_for :footer do %>
  <cite>By Author Name</cite>
<% end %>

Тогда в макете:

<%= yield :heading %>
<%= yield %>
<%= yield :footer %>

Конечно, вы можете определить их в любом порядке.

Документы: http://api.rubyonrails.org/classes/ActionView/Helpers/CaptureHelper.html

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...