Saturday, October 11, 2008

A practical use for change-class!

Previously only thought useful for metaprogramming, the amazing change-class finds a use in the hallowed realm of application programming.

(defwidget maybe-pagination (weblocks:pagination)
((show-pred :initarg :show-predicate :accessor show-paginator-predicate
:initform (constantly t)
:documentation "One-arg proc accepting self answering
whether to show the widget contents."))
(:documentation "Hide the paginator sometimes."))

(defmethod weblocks:render-widget-body
((self maybe-pagination) &key &allow-other-keys)
"Iff `show-paginator-predicate''s value answers NIL on myself, don't
send to super."
(when (funcall (show-paginator-predicate self) self)

(defmethod initialize-instance :after
((self my-listedit-subclass) &key &allow-other-keys)
(change-class (weblocks:dataseq-pagination-widget self) 'maybe-pagination
:show-predicate (f_% (typep (weblocks:authenticatedp) 'admin-account))))

Wow, huh?

(The above makes it so that only admins can see the subwidget that
shows the current page with links for paging through the results.)


Leslie P. Polzer said...

I've been thinking about killing off Weblocks dispatcher's ON-SELECT slot, forcing the user to derive his own selector classes and then using CHANGE-CLASS at runtime to get the desired behaviour.

But I suppose it's more clean and more flexible if we just provide a DYNAMIC-DISPATCHER subclass for this that has an ON-DISPATCH slot.

So that was just a MAYBE-USE-CHANGE-CLASS case. :)

Slobodan Blazeski said...

It would be even more to work with ContextL based approach. Different slots for different types of users.