Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
PikachuEXE opened this issue Nov 20, 2012 · 11 comments
Open

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

PikachuEXE opened this issue Nov 20, 2012 · 11 comments

Comments

@PikachuEXE
Copy link
Contributor

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
Copy link
Contributor Author

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

@apotonick
Copy link
Member

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.

@PikachuEXE
Copy link
Contributor Author

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?

@apotonick
Copy link
Member

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

render :state => :show

or render another view (eh, view only) with

render :view => :show

@apotonick
Copy link
Member

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!

@PikachuEXE
Copy link
Contributor Author

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 :)

@apotonick
Copy link
Member

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
Copy link
Member

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.

@PikachuEXE
Copy link
Contributor Author

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

@apotonick
Copy link
Member

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

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

Yeeaaah, 2.0!!!! 👍

@PikachuEXE
Copy link
Contributor Author

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)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants