Perhaps somebody can enlighten me.
If putting
<f:metadata>
<f:viewParam name="test" value="#{test.value}"/>
</f:metadata>
inside a template, the setter
setValueis never called, i.e. the preRender method 'call()' is called without prior call to setter (see below in code example for reference).
If however, putting the metadata block inside the composition, it gets called as expected.
Is this normal behaviour or am I doing something wrong?
Thanks very much for any insights.
Hanspeter
For reference, here the complete code example of the non working version:
testtemplate.xhtml
<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:ui="http://java.sun.com/jsf/facelets">
<f:metadata>
<f:viewParam name="test" value="#{test.value}"/>
</f:metadata>
<f:event type="preRenderView" listener="#{test.call}" />
<h:head>
<title>Test Template</title>
</h:head>
<h:body>
<ui:insert name="text" />
</h:body>
</html>
testcomposition.xhtml
<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<ui:composition xmlns:ui="http://java.sun.com/jsf/facelets"
template="/templates/testtemplate.xhtml"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html">
<ui:define name="text">
some text
</ui:define>
</ui:composition>
and here the complete code example of the working version:
testtemplate.xhtml
<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:ui="http://java.sun.com/jsf/facelets">
<f:event type="preRenderView" listener="#{test.call}" />
<h:head>
<title>Test Template</title>
</h:head>
<h:body>
<ui:insert name="text" />
</h:body>
</html>
testcomposition.xhtml
<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<ui:composition xmlns:ui="http://java.sun.com/jsf/facelets"
template="/templates/testtemplate.xhtml"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html">
<f:metadata>
<f:viewParam name="test" value="#{test.value}"/>
</f:metadata>
<ui:define name="text">
some text
</ui:define>
</ui:composition>
This is by specification. It's mentioned in <f:metadata>
tag documentation:
Declare the metadata facet for this view. This must be a child of the
<f:view>
. This tag must reside within the top level XHTML file for the given viewId, or in a template client, but not in a template. The implementation must insure that the direct child of the facet is a UIPanel, even if there is only one child of the facet. The implementation must set the id of the UIPanel to be the value of theUIViewRoot.METADATA_FACET_NAME
symbolic constant.
The simple reason is because the metadata is supposed to be view-specific, not template-specific. To achieve your requirement anyway, and you can't /don't want to place <f:metadata>
inside an <ui:define>
of each template client, then your best bet is using some common bean with a @ManagedProperty
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With