Подтвердить что ты не робот

Многоуровневая вложенная компоновка в Rails 3

У меня есть приложение с файлом макета глобального приложения application.html.haml. Затем у меня есть несколько "стеков контроллера": для нашего основного сайта, нашего портала-администратора и нашего бизнес-сайта. Для каждого из них контроллеры находятся внутри модуля и все наследуются от одного и того же BaseController. Каждый стек имеет собственный файл макета. Внутри стека некоторые контроллеры также имеют файлы макета.

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

Например, для действия Site::BlogController#show я бы хотел, чтобы рельсы отображались:

/site/blog/show.html.haml внутри /layouts/site/blog.html.haml внутри /layouts/site.html.haml внутри /layouts/application.html.haml

Мне трудно понять, как вставить /layouts/site.html.haml в стек. Кажется, что автоматически, рельсы будут отображать действие внутри макета контроллера внутри макета приложения, однако я не вижу, как "вставлять" макеты в стек рендеринга.

Любая помощь очень приветствуется, однако, я прочитал все руководства по направляющим, но ничего не получилось, поэтому ссылка на http://guides.rubyonrails.org/layouts_and_rendering.html#using-nested-layouts не будет действительно будет полезно.

4b9b3361

Ответ 1

Я перечитал ссылку, которую я опубликовал (http://guides.rubyonrails.org/layouts_and_rendering.html#using-nested-layouts), и понял, что я пропустил ключевую деталь.

<%= render :file => 'layouts/application' %>

поэтому в Site::BaseController у меня есть вызов layout 'site', а в /layouts/site.html.haml у меня есть

= content_for :footer do
   -#Content for footer
= render :file => 'layouts/application'

Тогда в Site::BlogController, который продолжается Site::BaseController, я layout 'site/blog' и в /layouts/site/blog.html.haml имеет

=content_for :header do
  %h1 HELLO WORLD!

= render :file => 'layouts/site'

Затем это делает макеты вложенными, как описано в вопросе. Извините за отсутствие этого в моем вопросе. Я должен был читать ближе.

Ответ 2

если вы создаете вспомогательный помощник:

# renders a given haml block inside a layout
def inside_layout(layout = 'application', &block)
  render :inline => capture_haml(&block), :layout => "layouts/#{layout}"
end

то вы можете определить sublayout следующим образом:

= inside_layout do
  # nested layout html here
  = yield

эти макеты могут использоваться как обычные макеты.

подробнее: http://www.requests.ch/blog/2013/10/30/combine-restful-rails-with-nested-layouts/

Ответ 3

Я сделал аналогичный, но использовал только 1 уровень подуровней. Можно легко настроить, чтобы разрешить несколько уровней.

В контроллерах /application _controller.rb:

def sub_layout
  nil
end

В контроллере (например, blog_controller.rb):

def sub_layout
  "blog"
end

В layouts/application.html.erb вместо <%=yield%>:

<%= controller.sub_layout ? (render :partial => "/layouts/#{controller.sub_layout}") : yield %>

Сделайте частичный layouts/_blog.html.erb:

...code
  <%=yield%>
...code

Повторите это для других макетов контроллера и подкомпоновки.

EDIT: Если вам нужно сделать это на основе действия:

def sub_layout
  {
    'index' => 'blog',
    'new' => 'other_sub_layout',
    'edit' => 'asdf'
  }[action_name]
end

Ответ 4

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

((render "layouts/#{controller_name}" rescue nil)|| yield )

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

note: убедитесь, что ваш вложенный макет назван _layoutname.whatever и что ваш вложенный макет имеет yield внутри

Ответ 5

Вы можете создать частичный с уроком в нем.

_my_sub_layout.html.erb:

<h3>I'm a sub layout and here my content:</h3>
<%= yield %>

В каком-то другом представлении или даже в вашем основном макете application.html.erb отображает частичное как макет:

<%= render layout: 'my_sub_layout' do %>
  <p>I'm the sub layout content</p>
<% end %>