Рендеринг части / макета с несколькими блоками

У меня очень простое требование - у меня есть макет, состоящий из заголовка и тела. Это подмакет страницы, а не сама страница.

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

Моя первая попытка состояла в том, чтобы использовать частичный рендеринг в качестве макета, который использовал именованные выходы для рендеринга заголовка и тела:

<header class="Resource-header">
  <%= yield :resource_header %>
</header>
<div class="Resource-body">
  <%= yield :resource_body %>
</div>

Затем визуализируйте его из моих шаблонов следующим образом:

<%= render layout: 'admin/resource' do %>

  <% content_for :resource_header do %>
  <% end %>

  <% content_for :resource_body do %>
  <% end %>

<% end %>

Однако это ничего не дает.

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

<% content_for :resource_header do %>
<% end %>

<% content_for :resource_body do %>
<% end %>

<%= render layout: 'admin/resource' do %><% end %>

Однако это кажется невероятно хакерским. Кажется, что content_for имеет глобальную область видимости, и нет никакой связи между блоком content_for и частичным рендерингом.

Так каков правильный способ для меня достичь этого?


person Undistraction    schedule 23.11.2014    source источник


Ответы (3)


Просто у меня была точно такая же проблема.

Решение: в вашем частичном файле макета 'admin/resource' body:

<header class="Resource-header">
  <%= yield resource, :resource_header %>
</header>
<div class="Resource-body">
  <%= yield resource, :resource_body %>
</div>

в ваших шаблонах сделайте:

<%= render layout: 'admin/resource' do |resource, section| %>
  <% case section %>
    <% when :resource_header %>
      Resource header shows here.
    <% when :resource_body %>
      Resource body shows here.
  <% end %>

<% end %>
person user2954224    schedule 11.09.2018
comment
это формальный способ? - person iownthegame; 12.05.2020

Взгляните на презентеры rails https://www.ruby-toolbox.com/categories/rails_presenters Возможно, ваше решение — гем клеток.

person sashaegorov    schedule 27.11.2014

Несмотря на то, что вопрос уже довольно старый, сегодня у меня была аналогичная проблема. Я придумал что-л. нравится. Не требуется драгоценный камень или пользовательский класс, просто использование необычного блока;)

<!-- app/views/layouts/fancy-blocks.html.erb -->
<%
  body, footer = nil
  yield(
    proc {|&blk| body = capture(&blk) },
    proc {|&blk| footer = capture(&blk) }
  )
%>
<section class="body"><%= body %></section>
<footer><%= footer %></footer>
<!-- app/views/some-other/view.html.erb -->
<%= render 'layout/fancy-blocks' do |body, footer| %>
  <% body.call do %>
    BODY
  <% end %>

  <% footer.call do %>
    FOOTER
  <% end %>
<% end %>
person Alex    schedule 12.03.2021