Tapestry Training -- From The Source

Let me help you get your team up to speed in Tapestry ... fast. Visit howardlewisship.com for details on training, mentoring and support!

Saturday, February 10, 2007

More Tapestry 5: Grid Component, Case Insensitivity

I've been busy building a Grid component to replace T4's contrib:Table component. It's coming out great, I can't wait to put up a screen cast of it soon (once I get sorting working). It has a clean UI (more default CSS), uses a Digg-style pager, at the bottom, and it's scary fast.

Better yet, its pretty automatic. If you pass the Grid a list of components, it builds its model from the first component (it expects them to be uniform). The model even understands the order of properties, based on the order of the getter methods within the bean class. It uses similar concepts to the BeanEditor to create default labels and so forth. Basically, it's zero configuration ... push a list of objects at it, and it will build the entire UI, column labels, column order ... the whole enchilada.

Meanwhile, I've been working under the covers to further extend the bounds of case insensitivity. It's now a hard-wired concept inside Tapestry IOC, which provides a CaseInsensitiveMap (a full java.util.Map where the keys are case insensitive) to properly support it. I'll be able to strip out a whole lot of string.toLowerCase() calls inside tapestry-core (I'm just taking a little break now). Back to the point ... now when you are injecting, contributing, or doing anything else with Tapestry IOC the case of the ids just don't matter anymore. One less thing to worry about while developing (no more "is that 'Checkbox' or 'CheckBox'?").

I showed off some Tapestry 5 to my friends at Formos and they loved every bit of it. Here's a company that develops exclusively in Tapestry, and has concurrent projects in Tapestry 3 and Tapestry 4 and they loved every bit of it. Many of my "innovations" were similar to things they extended Tapestry to do for their applications, but they appreciated the idea that it is baked into Tapestry itself. And there's a few other ideas I've had that haven't occured to anyone else yet.

It was very gratifying to see how excited they got by Tapestry IOC. "It's HiveMind -- without the XML, come check it out!". So it's nice to get a little confirmation that things are on the right track.

11 comments:

Anonymous said...

I'm already using Tapestry 5 for production use, and I absolutely love it! Keep up the good work!
My productivity has more than doubled from Tapestry 4 already.
Now I'd just like to see, in the tapestry test pages, f.ex. in the todo list, examples of select component inside a loop.

Anonymous said...

hi howard,

i have to agree, reading and writing tapestry ioc configurations is great!! ... its so easy to use because of the annotations .... and you have design time support by the java IDE...

g,
kris

Dustin said...

Hey Howard

Sorry I missed you when you were at Formos. I think I was out to lunch. We will have to meet next time you stop by or you give a presentation.

Massimo said...

Yep, Tapestry IoC it's amazing, and i really like that definition... HiveMind without XML.

And it's incredibly easy to work with.

Howard said...

Thanks, I'm very proud of tapestry-ioc, it's fast, it's easy, it doesn't skimp on power. I have thought about trying to extend the class reloading concept into it, but I don't think the value add is sufficient to warrant all the likely ClassCastException problems that would cause.

Anonymous said...

learning tapestry by converting a struts app. going pretty well thanks to the all the sample code from your testing. once I figure out how to do something, the doing of it is really easy. alot less coding then in struts. current fight is with message text having html in it that is meant for browser, tapestry is converting it so browser does not processes. second fight is with component that under struts either displays its own page or pass control on to another page. haven't figure out how to do that without moving flow control to calling component rather then called component.

Robert J. Walker said...

If you create the model based off the first item in the list, how would one handle the case where your list of items is heterogeneous? For example, in my current Tap 4.1 app, I have a page that shows a list of reports. The Report class is an abstract base class from which several different types of reports descend. I'd end up with ClassCastExceptions with what you're proposing. It think it's great for the default behavior, but perhaps you could provide an optional parameter to the Grid component where you could tell it to recreate the model every time to get around this issue.

Howard said...

You can also inject the BeanEditorSource service into your component and generate the model explicitly. The joy of it is that most of the time, you just don't have to. In your example, you would generate a model for the abstract base class that your various report implementations extend.

Robert J. Walker said...

Ah, that works out well. Tap5 is sounding pretty killer.

Howard said...

"Tap5 is sounding pretty killer" -- yes, that's the intent. I've done a LOT of Tapestry training over the last couple of years, and it has been a two way street. I've learned a lot about neophytes' expectations of Tapestry (and development in general) and I'm trying to roll all of that, and more, into Tapestry 5 while not handicaping the power users who will go under the covers. The use of an IOC container is pretty critical to enabling both groups.

Anonymous said...

although you can get around fact that ${message:...} can not take a attribute name as input by writing your own component, it would seem a simpler solution would be to add a another similar command that did expect parameter to be an attribute name. another small improvement would be a command that displays a message and does pass thru straight html (sort of like this blog entry page does). we have small amounts of html in custom announcements and FAQ answers which are stored in a database. We could right a component to parse the the text string and execute multiple write statements, but this seems to be adding extra complexity. would rather have developer have choice to let html thru and live with consequences, which in our case would show up during the qa of the text that is entered.