trailblazer / cells

View components for Ruby and Rails.
https://trailblazer.to/2.1/docs/cells.html
3.06k stars 235 forks source link

Wrapping a Cell around content #129

Open the8472 opened 12 years ago

the8472 commented 12 years ago

With helpers I can do the following:

# my_helper.rb

def my_helper(&block)
  content_tag(:div,&block)
end
-# my_view.haml

=my_helper do
   %h1=myObj.title
   some content here

To my knowledge something equivalent currently isn't possible with cells since they take a block for configuration, not for content-capturing

If we could pass blocks of content to a cell's state and then either call the block/capture its content or even yield inside a cell's view to wrap it this would get us closer to doing away with helpers.

the8472 commented 12 years ago

Or a more advanced what one can do with custom helpers (+ some builder objects generated by the helper in the background) right now:


=sortable_table_builder @objects do |t|
  - t.define_column do |col|   
     -col.header :default_index => 15 do
       =@objects.first.class.human_attribute_name :title
     -col.item do |obj|
       =link_to obj, obj.title
  %caption=@objects.first.class.human_name
  %thead
    %tr
      %td{:colspan=>t.column_count} My Additional Header
  =t.flush
  %tfoot
    %tr
      %td{:colspan=>t.column_count} My Additional Footer

The table builder would keep a lot of state in the background, and i think cells would be the better choice, but the inability to pass blocks really hampers that.

the8472 commented 12 years ago

I have been toying with a few helpers that capture the block and pass it on to the cell and got it somewhat working so far, but i noticed that cell.render_state is not reentrant. I.e. if i trigger another state while a state is currently being rendered it change the @_action_name variable inside the cell and thus the views that get rendered.

I guess that's actually a limitation of the AbstractController being used. That means i can only use normal method calls inside a block or have to delegate to another (sub-)cell if i want to keep things clean.

ivanyv commented 9 years ago

I tried (Slim):

= cell :cell, nil, content: -> do
  h1 Blah

Then on the cell view:

= @options[:content].call

But that outputs the content twice, once before the cell's HTML. If I do - instead of = then just the content on the wrong place is rendered.

ivanyv commented 9 years ago

Found a not so neat workaround:

= cell :cell, nil, content: -> do
  - capture do
    h1 Blah