Setting ui:param conditionally

facelets, jsf-2, primefaces

Solution

As indicated by `<ui:composition template>`, this page represents a template client.

Any `<ui:param>` outside `<ui:define>` applies to the master template (the file which you declared in `template` attribute) and is ignored inside the template client itself. If you intend to prepare variables for inside the template client, you should put `<ui:param>` inside `<ui:define>`.

But there's another thing: the original purpose of `<ui:param>` is to pass variables to the file referenced by `<ui:composition template>`, `<ui:decorate template>` or `<ui:include src>`, not to prepare/set variables inside the current facelet context. For the sole functional requirement of preparing/setting variables in the current EL context, you'd better be using JSTL `<c:set>` for the job. You can use `<ui:param>` for this, but this isn't its original intent and didn't work that way in older MyFaces versions.

Thus, so:

<ui:define>
    <c:if test="#{subscriptionListController.model.listViewName eq 'mySubscriptions'}">
        <c:set var="title" value="#{msg.subscriptionTitleMySubscriptions}"/>
    </c:if>
    <c:if test="#{subscriptionListController.model.listViewName eq 'paidSubscriptions'}">
        <c:set var="title" value="#{msg.subscriptionTitlePaidSubscriptions}"/>
    </c:if>
    <c:if test="#{subscriptionListController.model.listViewName eq 'allSubscriptions'}">
        <c:set var="title" value="#{msg.subscriptionTitleAllSubscriptions}"/>
    </c:if>
    ...
</ui:define>

Unrelated to the concrete problem, you can optimize this as follows without the need for an unmaintainable `<c:if>` group which would only grow with every subscription type:

<ui:define>
    <c:set var="subscriptionTitleKey" value="subscriptionTitle.#{subscriptionListController.model.listViewName}">
    <c:set var="title" value="#{msg[subscriptionTitleKey]}"/>
    ...
</ui:define>

with those keys

subscriptionTitle.mySubscriptions = Title for my subscriptions
subscriptionTitle.paidSubscriptions = Title for paid subscriptions
subscriptionTitle.allSubscriptions = Title for all subscriptions

Problem

I want to set a ui:param depending on a bean value and I thought using c:if was a good idea. So I put in my page the following code: ``` <ui:composition xmlns="http://www.w3.org/1999/xhtml" xmlns:ui="http://java.sun.com/jsf/facelets" xmlns:h="http://java.sun.com/jsf/html" xmlns:f="http://java.sun.com/jsf/core" xmlns:c="http://java.sun.com/jsp/jstl/core" xmlns:wai="http://www.id.ethz.ch/wai/jsf" template="/view/listView.xhtml"> <c:if test="#{subscriptionListController.model.listViewName eq 'mySubscriptions'}"> <ui:param name="title" value="#{msg.subscriptionTitleMySubscriptions}"/> </c:if> <c:if test="#{subscriptionListController.model.listViewName eq 'paidSubscriptions'}"> <ui:param name="title" value="#{msg.subscriptionTitlePaidSubscriptions}"/> </c:if> <c:if test="#{subscriptionListController.model.listViewName eq 'allSubscriptions'}"> <ui:param name="title" value="#{msg.subscriptionTitleAllSubscriptions}"/> </c:if> .... ``` but the parameter is not set... If I let print out the value of `#{subscriptionListController.model.listViewName eq 'mySubscriptions'}` I get true in the corresponding case and false in the other two cases. At the beginning I had only 2 possibilities and solved it with the ternary operator: ``` <ui:param name="title" value="#{subscriptionListController.model.listViewName eq 'mySubscriptions' ? msg.subscriptionTitleMySubscriptions : msg.subscriptionTitlePaidSubscriptions}"/> ``` and it worked. But now I have more possibilities... What am I doing wrong?

Original source

Related problems