Re: Feedback on proposed Groovy DSL syntax for Wicket

2008-03-07 Thread Dmitry Kandalov
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 

Feedback on proposed Groovy DSL syntax for Wicket

2008-03-06 Thread graemer

So as some of you may know I've been updating the Grails Wicket plug-in.
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=IntroducingApacheWicket

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:

class BasePage extends BuildablePage {
public build() {
stylesheet main
panel searchPanel {
form searchForm {
def model = [:]
bookmarkablePageLink addContact, EditContact
textField searchString, model:model
onSubmit {
redirect page:ListContacts, [searchString:
model.searchString]
}
}
}
}
}
class ListContacts extends BasePage {

public build() {
super.build();

def contactsModel = {
Contact.findByNameLike(%${params.searchString}%) }  as
LoadableDetachableModel

listView contacts, contactsModel { item -
def view = link( view, item.model ) {
onClick {
 redirect page:new ViewContact(item.model.id)
}
}
view  label(firstName, new PropertyModel(item.model,
firstName))
view  label(lastName, new PropertyModel(item.model,
lastName))

item  view

item  link(edit, item.model) {
onClick {
redirect page:new EditContact(model.id)
}
}
item  link(delete, item.model) {
onClick {
item.model.delete()
redirect page:ListContacts  
}
}

}

}

}
-- 
View this message in context: 
http://www.nabble.com/Feedback-on-proposed-Groovy-DSL-syntax-for-Wicket-tp15873183p15873183.html
Sent from the Wicket - User mailing list archive at Nabble.com.


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



Re: Feedback on proposed Groovy DSL syntax for Wicket

2008-03-06 Thread Ryan Sonnek
I think this looks really great.  I'm pretty sure the current wicket
builder project has been abandoned, so this would be a welcome
replacement.

I've been dying to dive into grails now that it supports a *real* view
layer!  =)

On Thu, Mar 6, 2008 at 8:59 AM, graemer [EMAIL PROTECTED] wrote:

  So as some of you may know I've been updating the Grails Wicket plug-in.
  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=IntroducingApacheWicket

  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:

  class BasePage extends BuildablePage {
 public build() {
 stylesheet main
 panel searchPanel {
 form searchForm {
 def model = [:]
 bookmarkablePageLink addContact, EditContact
 textField searchString, model:model
 onSubmit {
 redirect page:ListContacts, [searchString:
  model.searchString]
 }
 }
 }
 }
  }
  class ListContacts extends BasePage {

 public build() {
 super.build();

 def contactsModel = {
  Contact.findByNameLike(%${params.searchString}%) }  as
  LoadableDetachableModel

 listView contacts, contactsModel { item -
 def view = link( view, item.model ) {
 onClick {
  redirect page:new ViewContact(item.model.id)
 }
 }
 view  label(firstName, new PropertyModel(item.model,
  firstName))
 view  label(lastName, new PropertyModel(item.model,
  lastName))

 item  view

 item  link(edit, item.model) {
 onClick {
 redirect page:new EditContact(model.id)
 }
 }
 item  link(delete, item.model) {
 onClick {
 item.model.delete()
 redirect page:ListContacts
 }
 }

 }

 }

  }
  --
  View this message in context: 
 http://www.nabble.com/Feedback-on-proposed-Groovy-DSL-syntax-for-Wicket-tp15873183p15873183.html
  Sent from the Wicket - User mailing list archive at Nabble.com.


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



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