在同一页面上渲染具有不同内容块的部分:我需要一个接受内容块的部分帮助器

时间:2013-11-08 14:35:58

标签: ruby haml erb padrino middleman

我真的很喜欢Sass mixins让你用可自定义的包装器包装一段代码:

=container($class)
  .#{$class}.container
    .container-inner
      @content

+container(header)
  foo: bar

+container(main)
  baz: quux

产生的CSS:

.header.container .container-inner {
  foo: bar;
}

.main.container .container-inner {
  baz: quux;
}

我正在尝试对Padrino / Middleman部分做同样的事情。问题是部分不接受内容块(为什么?)。 :(

我尝试通过将内容块传递到content_for来解决这个问题,但content_for的后续使用会附加到内容而不是替换它:

部分partials/container.haml

.container
  = yield_content :container

Page index.html.haml

- content_for :container do
  Foo

= partial('partials/container')


- content_for :container do
  Bar

= partial('partials/container')

结果HTML:

<div class="container">
  Foo
</div>
<div class="container">
  Foo
  Bar
</div>

正如您所看到的,它复制了我的内容,这是绝对不可接受的。此外,这种方式不允许提供用于自定义包装器HTML的参数。

所以我想创建一个帮手。它将启用以下使用方式,方式更优雅而不是content_for,并且支持将变量传递到内容块

= partial_with_content_block('partials/container', class: 'header') do
  Foo

= partial_with_content_block('partials/container', class: 'main') do
  Bar

我如何实施这样的帮助?

2 个答案:

答案 0 :(得分:1)

这样的事情应该有效,但我把局部分开了:

def container(options={}, &block)
  raise ArgumentError, "Missing block" unless block_given?
  content = capture_html(&block)
  content_tag(:div, content, options)
end

请致电:

= container(class: 'main') do
  p More content here

但是现在我想如果它,这可以用默认的Padrino方法处理:

= content_tag :div, class: 'main' do
  p More content

答案 1 :(得分:1)

Middleman部分确实接受内容块,但语法略有不同。 ERB如下所示,但您也应该能够在HAML中执行此操作。

<% partial 'my_partial' do %>
    My Content
<% end %>

my_partial.html.erb

<p>
    <%= yield %>
</p>

结果

<p>
    My Content
</p>