You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tapestry.apache.org by Stephen Clout <st...@al.com.au> on 2004/08/23 02:52:02 UTC
Tapestry Comment
Hello
I would like to be able to dynamically choose which components to load
at render time without resorting to a
@contrib:Choose <http://jakarta.apache.org/tapestry/doc/ComponentReference/contrib.Choose.html> statement listing every possibility.
To do this, I Dynamically load Pages at runtime, and use them as Components within other pages.
To achieve this, I have overridden BasePage to move the call to cycle.commitPageChanges() until after the call to render(writer, cycle)
/**
* @see org.apache.tapestry.AbstractPage#renderPage(
* org.apache.tapestry.IMarkupWriter,
* org.apache.tapestry.IRequestCycle)
*/
public void renderPage(IMarkupWriter writer, IRequestCycle cycle) {
try
{
// Move call to render() before commitPageChanges()
firePageBeginRender();
render(writer, cycle);
if (!cycle.isRewinding()) cycle.commitPageChanges();
}
finally
{
firePageEndRender();
}
}
I have also created a custom component which can be used as follows:
<span jwcid="@PageImporter" pageName="ognl:content">
and whose implementation is as follows:
public abstract class PageImporter extends BaseComponent {
/**
*
* @return The Name of the DynamicPage instance to render
*/
public abstract String getPageName();
/**
* @see org.apache.tapestry.BaseComponent#renderComponent(
* org.apache.tapestry.IMarkupWriter,
* org.apache.tapestry.IRequestCycle)
*/
protected final void renderComponent(IMarkupWriter writer, IRequestCycle cycle) {
String pageName = getPageName();
if (pageName != null)
{
DynamicPage page = (DynamicPage) cycle.getPage(pageName);
page.setContainer(this.getContainer());
try
{
page.render(writer, cycle);
}
finally
{
// If we loaded a page, release it back to the page pool
page.setContainer(null);
IPageSource ps = cycle.getEngine().getPageSource();
ps.releasePage(page);
}
}
}
}
This hack seems to work pretty well, but I was wondering if there was a less hackish way of achieving this effect ?
I was also wondering if anybody else has come across the need to dynamically load components at runtime, and whether or not this could become a standard feature of Tapestry in a later release ?
An example usage of this feature would be a TappedPane that sourced its list of Tabs at runtime from a file system directory.
Any comments or feedback would be greatly appreciated.
Kind Regards
Stephen Clout
---------------------------------------------------------------------
To unsubscribe, e-mail: tapestry-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: tapestry-dev-help@jakarta.apache.org
Re: Tapestry Comment
Posted by Mikaƫl Cluseau <nw...@nwrk.dyndns.org>.
Hello,
You can use the Block and RenderBlock components, they are done for
this. An example near of yours (for more, see RenderBlock specification):
*** DynamicPage.java ***
public abstract class DynamicPage extends BasePage {
public abstract Block getBlock();
}
*** DynamicPageOne.html ***
[WYSIWYG editor header]
<span jwcid="block@Block">
[Real page contents]
</span>
[WYSIWYG editor footer]
*** DynamicPageOnePage.java ***
public class DynamicPageOne extends DynamicPage {
// DynamicPageOne.page uses this class
public Block getBlock() {
return getComponent("block");
}
}
*** HomePage.java ***
public class HomePage extends BasePage {
// Home.page uses this class
// Do some implementation of getContentPageName()
public Block getContent() {
DynamicPage page = (DynamicPage)
cycle.getPage(getContentPageName());
return page.getBlock();
}
}
*** Home.html ***
[...]
<span jwcid="@RenderBlock" block="ognl:content">
[replaced by dynamic content]
</span>
[...]
Stephen Clout wrote:
> Hello
>
> I would like to be able to dynamically choose which components to load
> at render time without resorting to a
>
> @contrib:Choose
> <http://jakarta.apache.org/tapestry/doc/ComponentReference/contrib.Choose.html>
> statement listing every possibility.
>
> To do this, I Dynamically load Pages at runtime, and use them as
> Components within other pages.
>
> To achieve this, I have overridden BasePage to move the call to
> cycle.commitPageChanges() until after the call to render(writer, cycle)
>
> /**
> * @see org.apache.tapestry.AbstractPage#renderPage(
> * org.apache.tapestry.IMarkupWriter, *
> org.apache.tapestry.IRequestCycle)
> */
> public void renderPage(IMarkupWriter writer, IRequestCycle cycle) {
>
> try
> {
> // Move call to render() before commitPageChanges()
> firePageBeginRender();
> render(writer, cycle);
> if (!cycle.isRewinding()) cycle.commitPageChanges();
> }
> finally
> {
> firePageEndRender();
> }
> }
>
> I have also created a custom component which can be used as follows:
>
> <span jwcid="@PageImporter" pageName="ognl:content">
>
> and whose implementation is as follows:
>
> public abstract class PageImporter extends BaseComponent {
>
> /**
> * * @return The Name of the DynamicPage instance to render
> */
> public abstract String getPageName();
>
>
> /**
> * @see org.apache.tapestry.BaseComponent#renderComponent(
> * org.apache.tapestry.IMarkupWriter,
> * org.apache.tapestry.IRequestCycle)
> */
> protected final void renderComponent(IMarkupWriter writer, IRequestCycle
> cycle) {
> String pageName = getPageName();
> if (pageName != null) {
> DynamicPage page = (DynamicPage) cycle.getPage(pageName);
> page.setContainer(this.getContainer());
> try
> {
> page.render(writer, cycle);
> }
> finally
> {
> // If we loaded a page, release it back to the page
> pool
> page.setContainer(null);
> IPageSource ps = cycle.getEngine().getPageSource();
> ps.releasePage(page);
> }
> }
> }
> }
>
> This hack seems to work pretty well, but I was wondering if there was a
> less hackish way of achieving this effect ?
>
> I was also wondering if anybody else has come across the need to
> dynamically load components at runtime, and whether or not this could
> become a standard feature of Tapestry in a later release ?
>
> An example usage of this feature would be a TappedPane that sourced its
> list of Tabs at runtime from a file system directory.
> Any comments or feedback would be greatly appreciated.
>
> Kind Regards
> Stephen Clout
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: tapestry-dev-unsubscribe@jakarta.apache.org
> For additional commands, e-mail: tapestry-dev-help@jakarta.apache.org
>
---------------------------------------------------------------------
To unsubscribe, e-mail: tapestry-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: tapestry-dev-help@jakarta.apache.org