Несколько content_for на одной странице
У меня в приложении большой блок 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 ответов
Вы должны определить свой 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
Обратите внимание, что если ваш блок даст ноль, то старый контент будет сохранен. Однако сама идея звучит не очень хорошо, так как вы, очевидно, делаете рендеринг (или, по крайней мере, создание объекта) дважды.
В Rails 4 вы можете передать параметр:flush для переопределения содержимого.
<%= content_for :block_head, 'hello world', :flush => true %>
или, если вы хотите передать блок,
<%= content_for :block_head, :flush => true do %>
hello world
<% end %>
ср исходный код этого помощника для более подробной информации
Вы всегда можете просто передать контент напрямую и не полагаться на блок:
<% content_for :replaced_not_appended %>
Я не уверен, что я действительно понимаю ваш вопрос - вот один подход в коде, который работает:
Посмотреть:
<% 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 %>
Railsguides: http://guides.rubyonrails.org/layouts_and_rendering.html
Вы можете использовать по имени 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