1

I'm implementing a web application using JSF 2.1.8 and I have a problem with the ui:include tag. I have this code

<h:panelGroup id="panelContenido">

        <ui:fragment rendered="#{!empty navigationManagerSystem._Navegable}">
            <ui:include src="#{navigationManagerSystem._Navegable._IncludePath}" />

        </ui:fragment>
        <ui:fragment rendered="#{empty navigationManagerSystem._Navegable}">
            <ui:include src="/system/navigation/error.xhtml" />
        </ui:fragment>
    </h:panelGroup>

The navigationManagerSystem bean is JSF session managed and when this piece of code is firstly rendered, it is supposed to show the include path content. This include works if I do it in a constant like that <ui:include /system/home/index.xhtml" /> but not if I put it in the variable, even I have seen the variable is holding that value before the screen prints. I don't know if it can be related with the bean that holds /system/home/index.xhtml page, which is View Scoped.

Anyway, if I do a page refresh just after page rendering, the xthml is properly included. By the way, I have simplified the page to be included in order to not have any jstl tags, because I know they can cause problems with View Scope.

Any idea about that?

Aritz
  • 30,971
  • 16
  • 136
  • 217

1 Answers1

6

As to the cause of the problem, the <ui:include> runs during view build time (restore view phase) not during view render time (render response phase) as you seem to expect. So if the include path changes during for example invoke action phase or even render response phase, then it won't be reflected in the view unless it's completely rebuilt.

Currently, your best bet is to use multiple static <ui:include> tags which are each conditionally rendered during view render time. True, this ends up with an unnecessarily large component tree. There is still no "holy grail" solution for this problem. The problem is clearly understood, but the solution is hard given the JSF/Facelets lifecycle. I have for OmniFaces done some experiments on that as well, however the simplest attempt fails hard in MyFaces while it works (to certain degree) in Mojarra.

See also:

Community
  • 1
  • 1
BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
  • "... however the simplest attempt fails hard in MyFaces while it works (to certain degree) in Mojarra. ..." I don't believe it by a simple reason: in most cases get FaceletContext in a bean is illegal, and if works it is just by luck, because FaceletContext expires as soon as the view is built or refreshed. I suppose use a c:if instead ui:fragment works better. If you find a bug please report it in [MyFaces Issue Tracker](https://issues.apache.org/jira/browse/MYFACES) – lu4242 Dec 21 '12 at 18:10
  • @lu4242: please check 2nd "see also" link for concrete example of the component based attempt and stacktrace in MyFaces. – BalusC Dec 21 '12 at 18:12
  • BalusC: I already did and the call of includeFacelet from encodeChildren is illegal. I know that worked in JSF 1.2 but with PSS algorithm introduced in JSF 2, it will not work. Why is that illegal? because in that time FaceletContext is not active, even in 1.2 is illegal. I don't think we can make it work, the best hope is wait for JSF 2.2 (in the latest JSF 2.2 Public Review Draft, FaceletFactory idea was dropped because the risk of introduce too many inconsistencies). See [this message](http://java.net/projects/javaserverfaces-spec-public/lists/jsr344-experts/archive/2012-11/message/91) – lu4242 Dec 22 '12 at 02:46
  • 1
    Thanks both of you, I'm newbye in JSF and now I begin to understand the phases of a page rendering. I noticed it's imposible to include something that is dynamically being set in page rendering time when I'm still building the page. – Aritz Jan 02 '13 at 12:34