On Thursday 06 March 2008 18:59:59 graemer wrote:
> So as some of you may know I've been updating the Grails Wicket plug-in.

I didn't know but I tried the plug-in a couple of weeks ago (with help of your 
blog) and it worked fine expect that I couldn't make wicket classes reload. I 
should look at the updated version ;)

> There is quite a few users on the Grails list who have shown interest in it
> and the ability to use a component framework backed onto the rest of the
> Grails stack (GORM, transactional services, plugin system etc.)
>
> However, the plugin provides a very basic level of integration and I was
> thinking it would be nice to create a Groovy DSL for Wicket. I looked into
> the WicketBuilder, but really I think we can take this further. So based on
> the example here:
> http://www.theserverside.com/tt/articles/article.tss?l=IntroducingApacheWic
>ket
>
> I came up with the below syntax to represent this application (note i
> havent actually implemented anything yet this is just a syntax proposal).
> Thoughts/feedback/suggestions welcome:

I also looked a while ago at the WicketBuilder, Kevin Galligan blog and 
discussion at wicket and groovy mailing lists.

As I understand there are two major problems with using groovy and wicket:
 - groovy doesn't have anonymous classes but they are used a lot in wicket;
 - if you somehow substitute anonymous classes with closures (what seems to be 
the most sane way), groovy's closures are not serializable but components in 
wicket must be serializable.

So IMHO the main purpose of creating a builder (actually it doesn't have to be 
a builder) would be in the first place to solve the above problems.

From what I remember from the WicketBuilder sources to solve the problems 
WicketBuilder:
 - generates groovy class (as text) which implements/overrides methods, then 
builder add closures calls to this methods.
 - stores the class of the closure (class is serializable :)) and when the 
closure needs to be called, builder creates new instance of the class and 
execute it. The consequence is that closures cannot reference local 
variables.

Some time ago I myself created a small builder to try groovy out and see how 
useful nice syntax can be. To solve the above problems I:
 - manually created subclasses for some basic wicket classes, added closures 
calls in implemented methods and added setters for these closures. (I know 
manual subclassing is lame, but it was the simplest thing I could 
do.)
 - created closure wrapper which is serializable and can serialize closure 
casting all its properties to Serializable. This way closures can reference 
page's local variables. It works fine for my simple use cases, though it 
might be not a very good solution.

>
> [skipped]
>
> Contact.findByNameLike("%${params.searchString}%") }  as
> LoadableDetachableModel
>
> [skipped]
>
>             view << label("lastName", new PropertyModel(item.model,
> "lastName"))
>             item << view
>             item << link("edit", item.model) {
>                 onClick {
>                     redirect page:new EditContact(model.id)
>                 }
>             }
>
> [skipped]

If I got it right, the main difference compared to WicketBuilder is that you 
put event handlers like onClick in a closure where child components are 
added. I like the idea, it seems to be more readable than adding closures as 
attributes to the builder method. I also like the idea of using "<<", IMHO 
it's a bit easier to notice in the code than "add".


What I did in my humble builder is more weird, because I added component id to 
the builder methods names. It looks like this (it's "working" code from 
test):

builder.build {
    myLabel()
    myLink(onClick: this.&callback) {
        my2Label()
    }
    myForm(onSubmit: this.&callback) {
        anotherLabel()
        myButton(onSubmit: this.&callback)
        myList([1,2,3], onItem: {})
    }
}

I used here link to instance method ("this.&callback") because I didn't like 
putting callback code in the builder hierarchy.


The next idea was that it would be ugly to put all the configuration into 
builder, so after calling the builder it's possible to access components 
without declaring local variables (it only works on a groovy specific page):

builder.build {...}
myLabel.visible = false
myLabel.markupId = "myLabelMarkupId"


Another idea is that there should _not_ be any builders since components 
hierarchy is already declared in markup files. In this case components could 
be created like that (it's also "working" code from test):

public PageWithImplicitLabel() {
    // creating label by calling non-existent method
    myLabel("label text")
    // accessing label by name
    myLabel.markupId = "myLabelMarkupId"
}

Component hierarchy could be built at the end of the constructor with static 
call like that:

public PageWithImplicitLabel() {
    ...
    HierarchyBuilder.build(this); // reads markup, rearranges components
}

I've also created very basic HierarchyBuilder. I wonder if someone really use 
something like that.

Hierarchy builder is not very original idea, there was at least one thread 
about it before 
(http://www.nabble.com/hierarchical-redundancy-in-markup-tt12409985.html). As 
Igor Vaynberg said there it won't work for Repeaters. Though probably it 
could work for some kind of enhanced-for-that-purpose ListView.


Dima

---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to