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)
(call-next-method)))

(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.)

2 comments:

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.