myfaces-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Leonardo Uribe <lu4...@gmail.com>
Subject [core] fix c:forEach var and varStatus scope (MYFACES-3520)
Date Thu, 14 Jun 2012 15:25:04 GMT
Hi

Trying to solve this issue:

https://issues.apache.org/jira/browse/MYFACES-3520

To keep things simple this is the example:

Some xhtml:
<c:forEach var="item" begin="1" end="3">
    <div>
        <ui:include src="templateContextTestInclude.xhtml">
            <ui:param name="item" value="#{item + 10}" />
        </ui:include>
    </div>
</c:forEach>

templateContextTestInclude.xhtml:
        <ui:composition>
            Item: <h:outputText value="#{item}" /><br/>
        </ui:composition>

In few words, the problem is that the included page should not be
affected by c:forEach tag. In this case the outer variable is used and
the passed through ui:param is ignored.

The current implementation uses facelets VariableResolver to store
"var" and "varStatus values, but the problem is that it can "pass" across
everything, including other templates and composite components and
breaks encapsulation principle.

Looking more carefully the spec javadoc of "var", it say this:

"... Name of the exported scoped variable for the current item of
the iteration. This scoped variable has nested visibility. Its type
depends on the object of the underlying collection ...."

In jsp, "nested visibility" means "... it can only be accessed within the
body of the <c:forEach> tag. ....". This is clear, but in facelets the original
intention was lost.

So, here we have an intepretation problem just like in:

[jsf-spec] ui:param and c:set implementations does not work as
expected (shouldn't page context and template context exists?)

http://markmail.org/message/rlp6napyd6flhpje

Like <c:set> and <ui:param>, <c:forEach> needs to be fixed. At
first view I suggested to use TemplateContext, but now I'm thinking
on use myfaces PageContext attribute map and restrict the scope.
For example, the same example but using ui:decorate should
work in the same way as with ui:include:

Some xhtml:
<c:forEach var="item" begin="1" end="3">
    <div>
        <ui:decorate template="templateContextTestInclude.xhtml">
            <ui:param name="item" value="#{item + 10}" />
        </ui:decorate>
    </div>
</c:forEach>

templateContextTestInclude.xhtml:
        <ui:composition>
            Item: <h:outputText value="#{item}" /><br/>
        </ui:composition>

The intention with this change is the same as with the chance of
c:set and ui:param : enforce encapsulation principle. I know
c:forEach is a "relic from the past", and there are better components
to do the same as this tag, but anyway I think it is worth to do it.

I'll attach a patch to solve this issue soon.

If no objections, I'll commit the changes soon.

regards,

Leonardo Uribe

Mime
View raw message