I really like how Sass mixins let you wrap a block of code with a customizable wrapper:
=container($class)
.#{$class}.container
.container-inner
@content
+container(header)
foo: bar
+container(main)
baz: quux
Resulting CSS:
.header.container .container-inner {
foo: bar;
}
.main.container .container-inner {
baz: quux;
}
I'm trying to do the same with Padrino/Middleman partials. The problem is that partials not accept content blocks (whyyy?). :(
I tried to work it around by passing content blocks into content_for
, but subsequent uses of content_for
would append to content rather than replace it:
Partial 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')
Resulting HTML:
<div class="container">
Foo
</div>
<div class="container">
Foo
Bar
</div>
As you can see, it duplicates my content which is absolutely unacceptable. Also, this way does not allow to provide arguments that would be used to customize wrapper HTML.
So i thought of creating a helper. It would enable the following usage style which is way more elegant than content_for
and also supports passing variables into content block:
= partial_with_content_block('partials/container', class: 'header') do
Foo
= partial_with_content_block('partials/container', class: 'main') do
Bar
How do i implement such a helper?
Something like this should work, but I left the partial out:
def container(options={}, &block)
raise ArgumentError, "Missing block" unless block_given?
content = capture_html(&block)
content_tag(:div, content, options)
end
Call as:
= container(class: 'main') do
p More content here
But now that I think if it, this could be all handled with default Padrino methods:
= content_tag :div, class: 'main' do
p More content