cells icon indicating copy to clipboard operation
cells copied to clipboard

Question: How to I add extra wrapper in inherited cell?

Open PikachuEXE opened this issue 13 years ago • 11 comments

Suppose I have this cell for avatar:

class AvatarCell < Cell::Rails
  BASE_CLASS = "mod-avatar"

  def show(options = {})
    @user = options[:user]
    @size = options[:size] || :large

    @class = [BASE_CLASS, options[:class]].compact.join(" ")

    render
  end
end

Then I want to make a new cell for avatar, but with a link wrapped around it How can I do that?

I have this code:

class LinkedAvatarCell < AvatarCell

  def show(options = {})
    render
  end

end

But I am not sure if I should call super here, or call something inside the template like:

= link_to @user, title: full_name_of(@user), rel: "tooltip" do
  -# What to put in here

PikachuEXE avatar Nov 20 '12 09:11 PikachuEXE

Or should I use different "states" of a cell? like:

class AvatarCell < Cell::Rails
  BASE_CLASS = "mod-avatar"

  def default(options = {})
    prepare(options)

    render
  end

  def linked(options = {})
    prepare(options)

    render
  end

  protected

  def prepare(options)
    @user = options[:user]
    @size = options[:size] || :large

    @all_classes = [BASE_CLASS, options[:class]].compact.join(" ")
    @image_classes = options[:image_class]
  end

end

and make the template do this:

= link_to @user, title: full_name_of(@user), rel: "tooltip" do
  = render view: :default

PikachuEXE avatar Nov 20 '12 09:11 PikachuEXE

If you just want to have different views for show simply derive an empty cell and drop the overriding view into app/cells/linked_cell/show.haml.

class LinkedCell < AvatarCell
end

When you have different setups in your code, extract the code to a separate method and override it in the subclass, just as you did in your second example.

apotonick avatar Nov 20 '12 10:11 apotonick

Is it possible to get "parent view" and render in the subclass' view? Like

= link_to 'somewhere' do
  = #super or render blah blah

If it is possible, how should i do that?

PikachuEXE avatar Nov 20 '12 12:11 PikachuEXE

You can always render another state (method+view) using

render :state => :show

or render another view (eh, view only) with

render :view => :show

apotonick avatar Nov 20 '12 13:11 apotonick

Ah, now I understand you. You want to extend the view with the "super" view. One first step would be introducing a new state.

class LinkedCell < AvatarCell

def extended_show
  render
end

In the view, you could do

= link_to ..
= render :state => :show

Another trick would be by extending the view in your cell state.

class LinkedCell < AvatarCell
  def show
    render_state(:link) + super
  end

  def link
    render # add the link here
  end
end


It would be cool if you could call the super view in your derived view, like you proposed.

= do something

= render :super

Let me think about that!

apotonick avatar Nov 20 '12 16:11 apotonick

The first one is like my second example, but with an extra subclass which is unnecessary The second one is also the same

What I want is inherit from avatar cell but without any extra method (Avatar#show and LinkedAvatar#show)

Oh the last one should be what I want

Right now I will just stick with my second example :)

PikachuEXE avatar Nov 21 '12 01:11 PikachuEXE

I played around with this a bit, I can see some new feature in cells similar to the one I proposed above. However, no urgent need to fix this right now, right? ;-)

You could do the following.


do something

render :file => "super_cell/state"

However, it would be cool if cells provides this for you so you don't have to know the super name. Does that work?

apotonick avatar Feb 25 '13 01:02 apotonick

Also, I'd love to have a consistent API differing from Rails.

render :view => "state" # render cell's view or inherit.

render :view => "some_ascendent/state" # render inherited view up from some_ascendent's inheritance chain.

render :view => super_view_for(state) # like above but you don't have to know the ascendent names.

apotonick avatar Feb 25 '13 01:02 apotonick

I have no urgent need for this :) Now I just use different states to achieve what I need

Working on upgrading to Ruby 2.0 right now :P

PikachuEXE avatar Feb 25 '13 01:02 PikachuEXE

Try out the :file thing, it will work for you.

What do you think of the proposed API with :view?

Yeeaaah, 2.0!!!! :+1:

apotonick avatar Feb 25 '13 01:02 apotonick

Well I can do the "wrapper" thing with states, so no need to use :file

The proposed API is good for real "view inheritance". It is possible to call super in code, why not view? (as a cell's view of course)

PikachuEXE avatar Feb 25 '13 02:02 PikachuEXE