haml, blocks and partials

2019-08-03 09:26发布

问题:

To clean and factor ugly views, I'd like to do the following:

1) In the view:

= document_left_container do
 = document_information

2) In my helper:

  def document_left_container(&block)
    render partial: "/document_left_container", locals: { custom_block: block }
  end

   def document_information
    render partial: "document_information"
  end

3) Partials:

For document_left_container:

.foo
  = custom_block.call

For document_information:

.bar

4) The expected result:

<div class='foo'>
  <div class='bar'>
  </div> 
</div>

5) The actual result:

<div class='foo'>
</div>
<div class='bar'>
</div>

Does anyone know how I could do to get my stuff working?

Thanks in advance,

Ben

回答1:

Here's how I'd keep it DRY:

=content_for(:document_information) do
  .bar

.foo
  =yield(:document_information)

This will produce

<div class='foo'>
  <div class='bar'>
  </div> 
</div>


回答2:

My current solution is:

Helper:

def document_left_container(&block)
  content_for :document_left_container do
    block.call
  end
  render partial: "/document_left_container"
end

Partial:

.foo
  = yield :document_left_container

Rest remains unchanged, I really wanted to keep the same structure.

Still curious to understand why my original code failed.



回答3:

I think your original code failed because you were essentially calling render and then calling render again. So you pushed something onto the stack and then pushed something else onto it. If you did this I think it would work. (Although I haven't tested it.)

def document_left_container(&block)
  capture_haml do 
    render partial: "/document_left_container", locals: { custom_block: block }
  end
end

 def document_information
  render partial: "document_information"
end