I've been pulling my hair out all day, silently cursing the blank walls around my office but I can't seem to find an elegant solution to manage the rendering cycle with this new logic any other way.
The basic problem is that for JSON or Ajax responses I'm going to need a different MarkupWriter implementation. If it was Ajax only then there wouldn't be as much of a problem, I could extend IMarkupWriter a little bit and call it a day, not worrying about changing method signatures and such....The JSONWriter is an entirely different animal though, so is the logic that handles rendering ajax requests. The method signatures of all these render calls would have to be duplicated in order to handle the JSON responses...And we all know duplicating logic will only lead to more bugs and headaches later on. So...To kill a few birds with one stone I'd like to introduce an interim solution somewhat based on what Howard has already mentioned. I don't know what to call the object yet but it would "contain" the right kind of MarkupWriter depending on the request type. It would also contain all of the logic that handles determining whether a component should actually render a response, and if so, what type of response. So...The old method signature of renderComponent(IMarkupWriter, IRequestCycle) would more or less go away. I don't mean to actually make it go away right now, but will instead duplicate logic just this once to allow backwards compatiblity. The new interface would be something along the lines of renderPipeline(<Myseterious Object Name Here>, IRequestCycle); The render implementation would then do the normal sort of housework that it always does, for instance the For component would setup it's collection and iteration loop, the actual rendering wouldn't happen directly in this method though, instead the <MONH> (short for mysterious object name here) would be called with a signature somewhat like: <MONH>.renderComponent(IComponent component, IRequestCycle cycle); The logic for determining JSON vs normal vs Ajax writers and which methods to call on the component would be encapsulated by this new object. This also brings us closer to providing a more centralized/seperate sort of logic area for transitioning the state and rendering of these objects out of the hands of the objects themselves and into something a little bit more managable. I'm sure Howard's ideas will ultimately create a much better solution for this, but without completely duplicating and hacking up the current design internals of tapestry I don't know a better solution. Stop me now before I get too far I guess... -- Jesse Kuhnert Tacos/Tapestry, team member/developer Open source based consulting work centered around dojo/tapestry/tacos/hivemind. http://opennotion.com