I *swear* this used to work!

3 views
Skip to first unread message

Robin Lee Powell

unread,
Oct 16, 2008, 11:38:55 PM10/16/08
to Weblocks

So I had code much like the following; the widget goes inside a
composite so do-widget works.

- -----------

(defmethod render-widget-body ((self my-widget) &rest args)
(render-link
(lambda (&rest args)
(declare (ignore args))
(let ((comp (make-instance
'composite
:widgets (list
(lambda ()
(render-link
(lambda (&rest args)
(answer self))
"Test Back"))))))
(do-widget self comp)))
"Test Button"))

- -----------

What *used* to happen (like, a few days ago) was that "Test Button"
would appear as a link. If you clicked on it, "Test Back" would
appear, and if you cilck on that "Test Button" would reppear.

Today, when you click on "Test Button", nothing whatsoever happens.

Even this simplified version doesn't work:

- ---------

(defmethod render-widget-body ((self agreement-bits) &rest args)
(render-link
(lambda (&rest args)
(declare (ignore args))
(let ((comp (make-instance
'composite
:widgets (list "Test Plain"))))
(do-widget self comp)))
"Test Button"))

- ---------

Again, nothing happens when you cilck on "Test Button".

I don't know if this is something I've changed in my own code
somewher, or something that has changed elsehwere in Weblocks (I'm
keeping up with -dev for the most part), but any pointers would be
most welcome.

-Robin

--
They say: "The first AIs will be built by the military as weapons."
And I'm thinking: "Does it even occur to you to try for something
other than the default outcome?" -- http://shorl.com/tydruhedufogre
http://www.digitalkingdom.org/~rlpowell/ *** http://www.lojban.org/

Robin Lee Powell

unread,
Oct 17, 2008, 1:31:02 AM10/17/08
to Weblocks
On Thu, Oct 16, 2008 at 08:38:55PM -0700, Robin Lee Powell wrote:
>
>
> So I had code much like the following; the widget goes inside a
> composite so do-widget works.

*sigh*

Every time I was rendering the widget containing the broken ones, it
was creating new sub-widgets, which started in the initial state.

D'oh.

Robin Lee Powell

unread,
Oct 17, 2008, 2:03:27 AM10/17/08
to Weblocks
On Thu, Oct 16, 2008 at 10:31:02PM -0700, Robin Lee Powell wrote:
>
> On Thu, Oct 16, 2008 at 08:38:55PM -0700, Robin Lee Powell wrote:
> >
> >
> > So I had code much like the following; the widget goes inside a
> > composite so do-widget works.
>
> *sigh*
>
> Every time I was rendering the widget containing the broken ones,
> it was creating new sub-widgets, which started in the initial
> state.

Erm, no, that wasn't it.

I've commented *everything* out; my entire application is now:

(make-navigation
; FIXME: used to be (class "upper-right") (id "upper-right")
'main-menu
'home (make-instance


'composite
:widgets (list
(lambda ()

(format t "recreation.~%")
"foo"))))

Every time I hit reload, "recreation." gets printed. Every time.

I'm really pretty certain that's wrong; you can't have state stored
in the widgets if they get recreated on every single user action.

Help?

Leslie P. Polzer

unread,
Oct 17, 2008, 3:46:18 AM10/17/08
to weblocks
> I've commented *everything* out; my entire application is now:
>
> (make-navigation
>     ; FIXME: used to be (class "upper-right") (id "upper-right")
>     'main-menu
>     'home (make-instance
>             'composite
>             :widgets (list
>                        (lambda ()
>                          (format t "recreation.~%")
>                          "foo"))))

You're lying, that's no entire application. ;)

Seriously: it depends on where you put that stuff.

If it's in INIT-USER-SESSION then it's working correctly.
The composite gets spawned exactly once when the session is created.

Leslie

Robin Lee Powell

unread,
Oct 17, 2008, 1:17:02 PM10/17/08
to webl...@googlegroups.com
On Fri, Oct 17, 2008 at 12:46:18AM -0700, Leslie P. Polzer wrote:
>
> > I've commented *everything* out; my entire application is now:
> >
> > (make-navigation
> >     ; FIXME: used to be (class "upper-right") (id "upper-right")
> >     'main-menu
> >     'home (make-instance
> >             'composite
> >             :widgets (list
> >                        (lambda ()
> >                          (format t "recreation.~%")
> >                          "foo"))))
>
> You're lying, that's no entire application. ;)
>
> Seriously: it depends on where you put that stuff.

Right you are; there was a single function in the way. Just to be
extra clear then:

- -------------------

(defun init-user-session (comp)
(setf (composite-widgets comp)
(make-navigation


'main-menu
'home (make-instance
'composite
:widgets

(lambda ()
(format t "recreation.~%")

(list
"foo"))))))

- -------------------

I also flipped tha lambda and the list, just to be extra clear.

> If it's in INIT-USER-SESSION then it's working correctly. The
> composite gets spawned exactly once when the session is created.

You'd think so, but that doesn't seem to actually be the case. As I
said, every time I hit reload, "recreation." gets printed out. That
*must* mean the composite widget is getting recreated every time I
hit reload. That's not OK.

Robin Lee Powell

unread,
Oct 17, 2008, 1:44:42 PM10/17/08
to webl...@googlegroups.com

It occurs to me that I can see how the examples I've given are not
scary-bad. The actual code has a widget getting recreated on every
reload that, it seems to me, *really* shoudn't be, but I can't
replicate in a simple test case. Until I do, you might as well
ignore this thread.

Robin Lee Powell

unread,
Oct 17, 2008, 1:56:37 PM10/17/08
to webl...@googlegroups.com
On Fri, Oct 17, 2008 at 10:44:42AM -0700, Robin Lee Powell wrote:
>
>
> It occurs to me that I can see how the examples I've given are not
> scary-bad. The actual code has a widget getting recreated on
> every reload that, it seems to me, *really* shoudn't be, but I
> can't replicate in a simple test case. Until I do, you might as
> well ignore this thread.

And the moral of the story is: lambdas as widgets get re-run on
every render, which means that if you want persistent widgets,

(make-instance
'composite
:widgets (list
(lambda ()

(render-list
(make-instance 'foo)))))

will not do what you want.

Sorry to waste people's time.

Time to go off and make a render-list widget. :)

Stephen Compall

unread,
Oct 17, 2008, 2:32:41 PM10/17/08
to webl...@googlegroups.com
Robin Lee Powell

<rlpowell-VkGw2YyLwTCa/A/roGhosh2...@public.gmane.org> writes:
> Time to go off and make a render-list widget. :)

* datalist
* listedit (datalist + dataedit-mixin)
* dataseq's on-query slot lets you bypass the store API

Also, some presentation code that you may like:

;;;; A stripped-down view-only single-field dataform

(defwidget singledata (weblocks:widget)
((data :initarg :data :initform nil :accessor singledata-data
:documentation "The item to render.")
(view :initarg :view :initform nil
:documentation "The view used to render the item. Defaults
to the scaffold view."))
(:documentation "Show a single view."))

(defwidget closeable-singledata (singledata)
()
(:documentation "Like `singledata', but also provide a Close
button."))

(defgeneric singledata-view (widget)
(:method ((widget singledata))
(or (slot-value widget 'view)
(weblocks:find-view
(list 'data (class-name-of (singledata-data widget)))))))

(defgeneric (setf singledata-view) (new-value widget)
(:method (new-value (widget singledata))
(setf (slot-value widget 'view) new-value)))

(defmethod weblocks:render-widget-body ((widget singledata) &key &allow-other-keys)
(weblocks:render-object-view
(singledata-data widget) (singledata-view widget) :widget widget))

(defmethod weblocks:render-widget-body :after
((self closeable-singledata) &key &allow-other-keys)
"Show said close button."
(with-html
(:div :class "operations"
(weblocks:render-form-and-button
"Close" (f_% (weblocks:answer self))))))

(defclass single-field-view (weblocks:data-view)
()
(:documentation "Render a single field and leave off all the chrome
for lists of fields."))

(defclass single-field-view-field (weblocks:inline-view-field)
()
(:documentation "Default field type for `single-field-view'.
This is just here to make the view compiler happy."))

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

Robin Lee Powell

unread,
Oct 17, 2008, 5:15:57 PM10/17/08
to webl...@googlegroups.com
On Fri, Oct 17, 2008 at 01:32:41PM -0500, Stephen Compall wrote:
>
> Robin Lee Powell
> <rlpowell-VkGw2YyLwTCa/A/roGhosh2...@public.gmane.org> writes:
> > Time to go off and make a render-list widget. :)
>
> * datalist
> * listedit (datalist + dataedit-mixin)
> * dataseq's on-query slot lets you bypass the store API

All of those are for presenting lists of data objects, whereas I
want to present a list of widgets. I suppose I could just use
composite, but I actually wanted the ul wrapping visually.

> Also, some presentation code that you may like:
>
> ;;;; A stripped-down view-only single-field dataform

Hey! Thanks! I started to write that but ended up not actually
using it, but I'm sure I will in the future.

Yarek Kowalik

unread,
Oct 18, 2008, 12:08:51 AM10/18/08
to weblocks
Well, you could have custom composite where you render items wrapped
in UL.

Is each widget different, or all are identical but showing different
data item? The datalist widget renders items in UL with each data
item rendered by reusable view - something to consider.

Yarek

On Oct 17, 2:15 pm, Robin Lee Powell <rlpow...@digitalkingdom.org>
wrote:
> On Fri, Oct 17, 2008 at 01:32:41PM -0500, Stephen Compall wrote:
>
> > Robin Lee Powell

Robin Lee Powell

unread,
Oct 18, 2008, 1:35:02 AM10/18/08
to webl...@googlegroups.com
I don't really understand views yet, so I don't know if they'd do
what I want. Each item differes only in data, but the presentation
includes things like render-link bits that call do-widget to do some
confirmation with the user.

-Robin

Stephen Compall

unread,
Oct 18, 2008, 11:32:56 AM10/18/08
to webl...@googlegroups.com
Yarek Kowalik <yarek.kowalik-Re5J...@public.gmane.org> writes:
> Well, you could have custom composite where you render items wrapped
> in UL.

This is what I would suggest, given the need to render separate widgets.
A "render-list" function cannot take advantage of all the machinery of
`composite' that is already in place, such as replacement in flow and
path finding.

(defclass list-composite (composite)
()
(:documentation "Render subwidgets in a UL."))

(defmethod render-widget-body ((obj list-composite) &rest args)
(with-html
(:ul (dolist (wij (composite-widgets obj))
(htm (:li (render-widget wij)))))))

If your reason for thinking of a `render-list' function before this was
so render-list calls could be tossed into rendering functions with other
things to be rendered, try to consider the overall widget as a composite
containing a list-composite alongside other widgets to contain the other
things.

Robin Lee Powell

unread,
Oct 18, 2008, 8:46:42 PM10/18/08
to webl...@googlegroups.com
On Sat, Oct 18, 2008 at 10:32:56AM -0500, Stephen Compall wrote:
>
> Yarek Kowalik
> <yarek.kowalik-Re5J...@public.gmane.org> writes:
> > Well, you could have custom composite where you render items
> > wrapped in UL.
>
> This is what I would suggest, given the need to render separate
> widgets.

And, in fact, what I did, although I subclassed widget rather than
composite; *shrug*.

-Robin

--
They say: "The first AIs will be built by the military as weapons."
And I'm thinking: "Does it even occur to you to try for something

Robin Lee Powell

unread,
Oct 19, 2008, 9:27:52 PM10/19/08
to webl...@googlegroups.com
On Fri, Oct 17, 2008 at 01:32:41PM -0500, Stephen Compall wrote:
>
> Robin Lee Powell
> <rlpowell-VkGw2YyLwTCa/A/roGhosh2...@public.gmane.org> writes:
> > Time to go off and make a render-list widget. :)
>
> * datalist
> * listedit (datalist + dataedit-mixin)
> * dataseq's on-query slot lets you bypass the store API
>
> Also, some presentation code that you may like:

[snip]

> (defgeneric singledata-view (widget)
> (:method ((widget singledata))
> (or (slot-value widget 'view)
> (weblocks:find-view
> (list 'data (class-name-of (singledata-data widget)))))))

Neither sbcl nor google seem to have any idea of what class-name-of
is.

Yarek Kowalik

unread,
Oct 19, 2008, 10:59:57 PM10/19/08
to weblocks
I think this was intended:

(class-name (class-of (sigledata-data widget)))

Yarek

On Oct 19, 6:27 pm, Robin Lee Powell <rlpow...@digitalkingdom.org>
wrote:
> On Fri, Oct 17, 2008 at 01:32:41PM -0500, Stephen Compall wrote:
>
> > Robin Lee Powell

Stephen Compall

unread,
Oct 20, 2008, 10:13:35 AM10/20/08
to webl...@googlegroups.com
Robin Lee Powell <rlpowell-VkGw2YyLwTCa/A/roGhosh2...@public.gmane.org> writes:
>> (list 'data (class-name-of (singledata-data widget)))))))
>
> Neither sbcl nor google seem to have any idea of what class-name-of
> is.

Oops, that's from arnesi.

Reply all
Reply to author
Forward
0 new messages