How do I conditionally render a <ui:define>
?
The data in the template depends on a required <f:viewParam>
.
But if an invalid view parameter is provided, then the <ui:define>
should not be rendered since the default content of the template should be used.
I tried using <c:if>
but it is not working.
Use <ui:fragment>
instead.
<ui:define name="description">
<ui:fragment rendered="false">
<meta name="description" content="do not render" />
</ui:fragment>
</ui:define>
Duplicate of ui:define with rendered="false" attribute still rendering
It's not possible to conditionally render/build an <ui:define>
. You can only do for its contents. Anything outside <ui:define>
is ignored in templates.
Better is to conditionally build the <ui:insert>
instead. The <ui:insert>
runs during view build time, so it's not possible to conditionally render it by a property which is set via <f:viewParam>
. You can only conditionally build it (the <ui:insert>
tag itself) using a conditional view build time tag such as JSTL <c:if>
which in turn checks the raw request parameter directly (and thus not the <f:viewParam>
property).
In the master template, it would look like this, assuming that just the sole presence of the request parameter is sufficient (if you need to perform validation, you'd need to do it inside the EL expression, or in a managed bean wherein the property is preinitialized via @ManagedProperty("#{param.foo}")
.
E.g., in the master template:
<c:if test="#{not empty param.foo}">
<ui:insert name="content" />
</c:if>
<c:if test="#{empty param.foo}">
<p>Default content</p>
</c:if>
or, more clear but more verbose
<c:choose>
<c:when test="#{not empty param.foo}">
<ui:insert name="content" />
</c:when>
<c:otherwise>
<p>Default content</p>
</c:otherwise>
</c:choose>
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