This one took awhile to figure out. In Tapestry, if a component is passed to another component (such as your main page layout component), you need to pass it as a Block parameter. The problem with blocks, there is no quick way to render them. You can use the @AfterRenderBody rendering stage annotation, but this gives you very limited flexibility in where the object will end up (or you make kludgy hacks to put this together). This quick little component can solve all those problems. I present you Render.java. This incredible class is appearing in IRM 2. Update: You can also use the builtin Tapestry component named Delegate. <t:delegate to=“block:foo”/> But if you still prefer, you can use this Component:
package net.stackworks.irm.web.components;
import org.apache.tapestry.annotations.Parameter;
/**
* Simple component which will render a Block in a page.
* To use: - Make sure your Block has a defined getter method (getSidebar()) which returns the Block
* - Do a <t:render value="sidebar"/> <!-- this calls getSidebar() -->
* - Enjoy your rendered Block
* @author Yann Ramin
*
*/
public class Render {
@Parameter(required = true)
private Object _value;
/**
* Returns the Object, which allows another object (presumably, a block) to render
* first.
*
* @return Object to render
*/
Object beginRender() {
return _value;
}
}