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]
