There's lots and lots going on with Tapestry right now. We're gearing up to bring Tapestry 5.2 into a beta phase ... hopefully a short one before a final GA release.
We've been busy adding new committers to the team. Not every vote has been successful, but that just shows that the system works.
Lots of people are working on a terrific refresh of the Tapestry home page and documentation. Not just new text, but a new more timely approach (based on Confluence) and a terrific new layout. Just lots of energy going on there. I can't wait for it to be ready ... it really makes Tapestry looks like the first-class citizen it is.
Meanwhile, I've been busy for my clients, writing some useful code.
I've managed to get the nightly builds of the TapX working again ... just in time. I've created an exciting new component: Dynamic.
Dynamic is targeted for use in skinning applications. Tapestry's structure makes skinning an application a little tricky, especially if you want to take a standard application and customize it for different customers. Tapestry templates are expected to be uniform across all instances of a component (in the same way that a classes's methods and fields are fixed across all instances). This makes it tricky to create a component that renders differently for different users, which is the essence of skinning. Often, you end up either simulating a JSP include and injecting a blob of raw markup content into the Tapestry DOM ... or you end up with an evil nest of conditionals and indirection.
The Tapx Dynamic component exists to mix a dynamic template file with live Tapestry components; The dynamic template is any well-formed XML document that can be represented as a Resource; mostly, it is output as-is ... until Tapestry hits an element, such as a <div>, with a special
id. When the id is of the form
param:block-name, the Dynamic component replaces the dynamic template element with the content of the Block parameter passed to the Dynamic component. We're really weaving Tapestry and the external template together here.
I'm working on a good, simple example here ... but anyone who has struggled with this issue will appreciate what Dynamic accomplishes. It's not unlike running SiteMesh at the Tapestry component level.