Hi,

I would like to share some thoughts about the way the PropertyDisplay works
(inside the beanDisplay). I choose the PropertyDisplay but it's the same for
the PropertyEdit.

As we know, we can contribute a BeanBlock to tell tapestry how to display a
specific datat type. For example I already have overridden the way the date
is diplayed, or added a BeanBlock for a custom datatype (here for the
"Decimal" class).

    public static void contributeDefaultDataTypeAnalyzer(
            MappedConfiguration<Class, String> configuration) {

        configuration.add(Decimal.class, "decimal");
    }

    public static void contributeBeanBlockOverrideSource(
            Configuration<BeanBlockContribution> configuration) {

        configuration.add(new BeanBlockContribution("date",
                "MyDisplayDateBlock", "date", false));

        configuration.add(new BeanBlockContribution("decimal",
                "MyDecimalEditBlock", "decimal", true));
        configuration.add(new BeanBlockContribution("decimal",
                "MyDecimalDisplayBlock", "decimal", false));

    }

And the other hand, many times in this mailing list, beginner asks how to
choose dynamically a component to display on the page. The classic response
is that it's not possible because the page tree (page and components
contained in the page) must be known before page execution, Tapestry has
dynamic behavior but a static structure
http://tapestry.apache.org/principles.html

But, searching how the BeanDisplay works, I discovered that this component
cheats and is not so static. To explain rapidly, the BeanDisplay loops on
each java bean property, and use the PropertyDisplay to display it. The
PropertyDisplay then use the BeanBlockSource service to lookup how to
display this property, which finally use the PageCache (an *internal*
Tapestry service :  org.apache.tapestry5.internal.services.RequestPageCache
) to dynamically load the page and extracts the Block that will be
displayed.

[In org.apache.tapestry5.internal.services.BeanBlockOverrideSourceImpl]
        Page page = pageCache.get(contribution.getPageName());
        return page.getRootElement().getBlock(contribution.getBlockId());


My point is :
1. The Core Component BeanDisplay, which is sometime presented as a sample
of what can be done, cannot be realized without using an internal service
(PagePool), and that is discouraged for upgrade compatibility.
2. Dynamic structure is finally possible in Tapestry.

I'm using Tapestry 5 on a daily basis at work. For a dynamic navigation, for
example, PageRenderLinkSource helped us to check if a specific configuration
page exists for a product (RuntimeException is thrown on
createPageRenderLink), and if not then the link we generate directs the user
to the generic configuration page. Sometimes, I would like to be able to do
the same for components, but until now, I've already managed to do that in
an other way, but not always very simple.

It would be nice if the PageCache trick could be possible using a public
API, because I'm not comfortable using an internal service to reach the
behavior I would like to have

Any ideas ?

Nicolas.

Reply via email to