Re: [weblocks] managing and accessing the widget tree

2 views
Skip to first unread message

Leslie P. Polzer

unread,
Nov 10, 2008, 2:10:02 PM11/10/08
to webl...@googlegroups.com

> I have a widget called `detail', which contains 3 subwidgets to do its
> work, "summary", "thumbnails", and "description". To get explicit tree
> access and avoid writing a renderer, I just subbed composite and put the
> three in composite-widgets.
>
> However, this means that to access the subs, I have to do one of 3
> unpleasant things:
>
> 1. find-if typep
> 2. first, second, third, and hope I don't subclass and tack on more
> 3. store each in a slot *and* the subwidget list

Yes, I know what you mean...


> The fourth thing, defining a method on composite-widgets to prepend the
> extras, is precluded by the setter:
>
> ;; uh oh, now there will be duplicates
> (push another-widget (composite-widgets detail))

At what time do you intend to do this?

How will there be duplicates?


> So I think the answer is to merge container's protocol into widget's,
> remove the "update-children" methods, and specify two protocols for
> accessing the widget tree:
>
> 1. widget-children: the setf-able, explicit list of always-rendered
> non-ephemeral subwidgets, where each has widget-parent => this.
>
> 2. generate-subwidgets: the most general of tree walker protocols I
> could think of. It looks like this:

Can you explain why plain widget-children layered above your
own container structure doesn't solve your problem?

This will help me understand what you're up to.


> Example: I currently use an implicit variant of walk-widgets to inform
> widgets when the authentication state changes, naturally using a `progn'
> method combination; the append-generate mc is a natural extension of
> that.

That's a bit terse, can you elaborate on it?

Leslie

Stephen Compall

unread,
Nov 10, 2008, 6:35:56 PM11/10/08
to webl...@googlegroups.com
"Leslie P. Polzer" <s...@viridian-project.de> writes:
>> (push another-widget (composite-widgets detail))
>
> At what time do you intend to do this?
>
> How will there be duplicates?

(defmethod composite-widgets ((self detail))
(append (mapcar (f_ (funcall _ self)) '(summary thumbnails description))
(call-next-method)))

Now after said expr, composite-widgets will answer (summary thumbnails
description another-widget summary thumbnails description
other-composites…)

> Can you explain why plain widget-children layered above your
> own container structure doesn't solve your problem?

Sometimes we want some elements of the set of subwidgets to be a place
that can be accessed, where other elements' presence on the widget tree
ought to be controlled privately.

>> Example: I currently use an implicit variant of walk-widgets to inform
>> widgets when the authentication state changes, naturally using a `progn'
>> method combination; the append-generate mc is a natural extension of
>> that.
>
> That's a bit terse, can you elaborate on it?

Sure, in a more primitive variant of the previously posted code:

(varying (base-type string function symbol weblocks:widget)
(defmethod walk-widgets progn (proc (wij (vary base-type)))
(funcall proc wij)))

(defmethod walk-widgets progn (proc (wij weblocks:composite))
(mapc #L(walk-widgets proc !1) (weblocks:composite-widgets wij)))

(defmethod walk-widgets progn (proc (wij weblocks:dataedit-mixin))
(case (weblocks:dataedit-ui-state wij)
((:add :drilldown) (walk-widgets proc (weblocks:dataedit-item-widget wij)))))

(defmethod walk-widgets progn (proc (wij weblocks:selector-mixin))
(mapc #L(walk-widgets proc (cdr !1)) (weblocks:selector-mixin-panes wij)))

Then I pass gf `auth-changed' to walk-widgets in my auth handler, and
have several methods that respond to that.

In this example, one would not consider the `dataedit-item-widget' to be
a member of the settable list of `widget-children', because it has
"feature on or off" semantics, not "member of an arbitrarily settable
list" semantics.

--
I write stuff at http://failex.blogspot.com/ now. But the post
formatter and themes are terrible for sharing code, the primary
content, so it might go away sooner or later.

Leslie P. Polzer

unread,
Nov 11, 2008, 11:11:42 AM11/11/08
to weblocks

> Sometimes we want some elements of the set of subwidgets to be a place
> that can be accessed, where other elements' presence on the widget tree
> ought to be controlled privately.

I slowly get it. You want to have the standard container thing
but also some private parts of the widget tree to walk on request
(together with the public ones).

Is that correct?

Stephen Compall

unread,
Nov 11, 2008, 8:35:26 PM11/11/08
to webl...@googlegroups.com
"Leslie P. Polzer" <leslie.polze...@public.gmane.org> writes:
> I slowly get it. You want to have the standard container thing
> but also some private parts of the widget tree to walk on request
> (together with the public ones).
>
> Is that correct?

Yes.

Stephen Compall

unread,
Nov 11, 2008, 8:36:09 PM11/11/08
to webl...@googlegroups.com
Anyway, with all this in mind, what do you think of my original
proposal?

Leslie P. Polzer

unread,
Nov 12, 2008, 3:03:08 AM11/12/08
to webl...@googlegroups.com

> Anyway, with all this in mind, what do you think of my original
> proposal?

It sounds very good, although I still have to wrap my head around
it -- this week's a bit busy for me.

Merge it into modern-dispatching and we'll see how well it works
with the real world.

When we got containers, mwpw, generated widgets and Yarek's stuff
together we can transfer the whole thing to -dev.

Leslie

Leslie P. Polzer

unread,
Nov 23, 2008, 3:40:27 PM11/23/08
to weblocks
On Nov 12, 9:03 am, "Leslie P. Polzer" <s...@viridian-project.de>
wrote:
Stephen,

do you need anything else to merge this in?

Leslie

Stephen Compall

unread,
Nov 24, 2008, 5:57:44 AM11/24/08
to webl...@googlegroups.com
"Leslie P. Polzer" <leslie...@gmx.net> writes:
> do you need anything else to merge this in?

I found a bug in Clozure/Cont when testing the changes I scribbled out
in earlier messages, then had to work on other stuff, so...

Go ahead and merge if you want, but my proposal changes most of the
protocols introduced in modern-dispatching. In particular it eliminates
container-update-children and container altogether. That may be too
much instability to introduce then take away, even for dev.

Stephen Compall

unread,
Dec 10, 2008, 12:06:53 AM12/10/08
to webl...@googlegroups.com
Stephen Compall <s11-IGUgQLVVQ...@public.gmane.org> writes:
> Go ahead and merge if you want, but my proposal changes most of the
> protocols introduced in modern-dispatching. In particular it eliminates
> container-update-children and container altogether. That may be too
> much instability to introduce then take away, even for dev.

Have a look at my branch, and you'll see what I mean. The key change is
here:

--- a/src/request-handler.lisp
+++ b/src/request-handler.lisp
@@ -142,7 +142,7 @@
; that wraps them in order to collect a list of script and
; stylesheet dependencies.
(hunchentoot-mp:with-lock (*dispatch/render-lock*)
- (handler-case (container-update-children (root-composite))
+ (handler-case (walk-widgets #'update-uri-tokens (root-composite) :order :pre)
(http-not-found () (return-from handle-normal-request
(page-not-found-handler app))))
(render-widget (root-composite)))

As I mentioned, I have removed CUC and CUDC entirely, preferring
extensions to hooks that use `walk-widgets' and the generate-subwidgets
protocol.

Jan Rychter

unread,
Dec 10, 2008, 11:08:11 AM12/10/08
to webl...@googlegroups.com
Stephen Compall <s...@member.fsf.org> writes:

> Stephen Compall <s11-IGUgQLVVQ...@public.gmane.org> writes:
>> Go ahead and merge if you want, but my proposal changes most of the
>> protocols introduced in modern-dispatching. In particular it eliminates
>> container-update-children and container altogether. That may be too
>> much instability to introduce then take away, even for dev.
>
> Have a look at my branch, and you'll see what I mean. The key change is
> here:

[...]

Stephen,

On a related note, I've just been looking at
http://www.bitbucket.org/S11001001/weblocks-modern-dispatching/
(interesting stuff!) and I'm puzzled -- you seem to have introduced
generators and a new method combination (append-generators). I don't
understand why? Do we need to generate lists of widgets lazily?

--J.

Stephen Compall

unread,
Dec 10, 2008, 1:28:59 PM12/10/08
to webl...@googlegroups.com
Jan Rychter <jan-JAsPCFd0e...@public.gmane.org> writes:
> On a related note, I've just been looking at
> http://www.bitbucket.org/S11001001/weblocks-modern-dispatching/
> (interesting stuff!) and I'm puzzled -- you seem to have introduced
> generators and a new method combination (append-generators). I don't
> understand why? Do we need to generate lists of widgets lazily?

To head off "let's change it to a mapping function so we don't cons up a
bunch of lists", vs "only with lists do we get to hold on to the program
flow". Generators provide the benefits of mapping and of lists, costing
only some time spent bug-hunting in CL-Cont (see 0.3.7). In fact, I
think Slava ought to consider adding the generator utilities to cl-cont
itself.

Jan Rychter

unread,
Dec 10, 2008, 2:57:07 PM12/10/08
to webl...@googlegroups.com
Stephen Compall <s...@member.fsf.org> writes:

> Jan Rychter <jan-JAsPCFd0e...@public.gmane.org> writes:
>> On a related note, I've just been looking at
>> http://www.bitbucket.org/S11001001/weblocks-modern-dispatching/
>> (interesting stuff!) and I'm puzzled -- you seem to have introduced
>> generators and a new method combination (append-generators). I don't
>> understand why? Do we need to generate lists of widgets lazily?
>
> To head off "let's change it to a mapping function so we don't cons up a
> bunch of lists", vs "only with lists do we get to hold on to the program
> flow". Generators provide the benefits of mapping and of lists, costing
> only some time spent bug-hunting in CL-Cont (see 0.3.7). In fact, I
> think Slava ought to consider adding the generator utilities to cl-cont
> itself.

Oh, I fully appreciate the benefits of generators, I was just curious
what the need in weblocks was. Our lists are rather small and rarely
need to be lazily generated, unless I'm missing something.

On the negative side, the cost is larger than what you describe -- added
complexity everywhere where they are used.

--J.

Reply all
Reply to author
Forward
0 new messages