Question: How to I add extra wrapper in inherited cell?
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
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
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.
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?
You can always render another state (method+view) using
render :state => :show
or render another view (eh, view only) with
render :view => :show
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!
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 :)
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?
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.
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
Try out the :file thing, it will work for you.
What do you think of the proposed API with :view?
Yeeaaah, 2.0!!!! :+1:
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)