ui:include includes wrong file in JSF 2.2 - jsf

Accorrding to the documentation of ui:include tag
Use this tag—which is very similar to JSP's jsp:include—to encapsulate
and reuse content among multiple XHTML pages. There are three things
this tag can include: plain XHTML, and XHTML pages that have either a
composition tag or a component tag.
You supply a filename, through ui:include's src attribute for JSF to
include. That filename is relative to the XHTML file that was rendered
as a result of the last request. So, for example, if JSF loaded the
view login.xhtml, and that file included pageDecorations/header.xhtml,
and pageDecorations/header.xhtml included companyLogo.xhtml, then
companyLogo.xhtml will not be found if it's in the pageDecorations
directory, because companyLogo.xhtml has to be in the same directory
as login.xhtml.
I created a simple test:
webapp/login.xhtml
<!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:ui="http://java.sun.com/jsf/facelets"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html">
<h:body>
<ui:include src="pageDecorations/header.xhtml" />
</h:body>
</html>
webapp/pageDecorations/header.xhtml
<ui:include
src="logo.xhtml"
xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
/>
webapp/pageDecorations/logo.xhtml
<h:outputText
value="Logo in /pageDecorations"
xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
/>
webapp/logo.xhtml
<h:outputText value="Logo in /"
xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
/>
When I ran this test (loaded login.xhtml page) using JSF 2.2 on WildFly 10.1 , I got Logo in /pageDecorations, while according to the documentation it should be: Logo in /
What is wrong ? Is there a bug in the documentation or Mojarra implementation ? Or my understanding is wrong ?

First, you are inside webapp/ and executing webapp/login.xhtml
inside that you get src="pageDecorations/header.xhtml" and for exectuing that you are in pageDecorations and from header.xhtml you are tring to find src="logo.xhtml" which will you get in the same directory (pageDecorations) so it will print
"Logo in /pageDecorations" .
Document looks wrong in this case.

Related

Composite component causes warning "no 'head' component has been defined within the view"

I have a working JSF page, but if I add xmlns:leaf="http://java.sun.com/jsf/composite/jsf2leaf" to it, and try to use any ot its tags, like <leaf:map center="42.120000,-72.540000" />, I get the following warning:
One or more resources have the target of 'head', but no 'head' component has been defined within the view.
Everything works fine, the map is there, I can add markers, but I can't get rid of the warning message.
My JSF page looks like this:
<?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:f="http://xmlns.jcp.org/jsf/core"
xmlns:h="http://xmlns.jcp.org/jsf/html"
xmlns:p="http://primefaces.org/ui" xml:lang="hu" lang="hu"
xmlns:c="http://xmlns.jcp.org/jsp/jstl/core"
xmlns:leaf="http://java.sun.com/jsf/composite/jsf2leaf"
>
<f:view contentType="text/html">
<f:metadata>
<f:viewAction action="#{dashboardController.readURLParam()}"/>
</f:metadata>
<h:head/>
<h:body>
...
<h:form>
...
<p:panel>
...
<c:forEach>
...
<p:panel>
<leaf:map center="42.120000,-72.540000" />
</p:panel>
</c:forEach>
</p:panel>
</h:form>
</h:body>
</f:view>
found the problem, it, in the jsf2leaf.jar the map.xhtml and advancedmap.xhtml uses <head></head> instead of <h:head></h:head>, changed it, repackaged the jar file, and it works fine

Parameter always null on ui:composite xhtml page [duplicate]

I have a simple JSF 2.0 composite component example.
<!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:cc="http://java.sun.com/jsf/composite"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core">
<head>
<title>
A panel box component
</title>
</head>
<body>
<cc:interface>
<cc:attribute name="model" required="true" type="at.test.Person"/>
</cc:interface>
<cc:implementation>
<h:inputText value="#{model.vorname}">
</h:inputText>
</cc:implementation>
</body>
And here is my JSF test page:
<!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:ui="http://java.sun.com/jsf/facelets"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:mc="http://java.sun.com/jsf/composite/mygourmet" >
<h:body>
<h:form>
<mc:inputTest model="#{person}">
</mc:inputTest>
<h:commandButton value=""/>
<h:outputText value="#{person.vorname}"/>
</h:form>
</h:body>
</html>
I want that my composite component saves a string value in a JSF session bean with <h:inputText>. But the problem is, when I submit the form with the <h:commandButton> I see the following error:
Caused by: javax.el.PropertyNotFoundException: /resources/mygourmet/inputTest.xhtml at line 18 and column 42 value="#{model.vorname}": Target Unreachable, identifier 'model' resolved to null
at org.apache.myfaces.view.facelets.el.TagValueExpression.getType(TagValueExpression.java:73)
at org.apache.myfaces.shared_impl.renderkit._SharedRendererUtils.findUIOutputConverter(_SharedRendererUtils.java:77)
You need to reference composite component attribute values by #{cc.attrs.<name>} where <name> is the attribute name. So, this should do:
<h:inputText value="#{cc.attrs.model.vorname}">
See also:
Java EE 6 tutorial - Facelets - Composite Components
Java EE 6 tutorial - Advanced Composite Components
<composite:xxx> tag documentation
Unrelated to the concrete problem, all that <html><head><body> in the composite is unnecessary. I suggest to use <ui:component> since that's more clear. See also our composite component wiki page for examples.

JSF2 EL html output

Background
I have an existing web application that relies on JSF2. In most pages, there are expressions that output text from various property files. Some properties might contain html. However, JSF expressions escape html into plain text. The solution I found was to use <h:outputText> with escape set to false. Using this would be cumbersome due to amount of expressions that would need to be wrapped.
Question
My question is, is there a way to configure all expressions to not escape html?
If I were you I would create my own composite component wich can be called In xhtml with
<myComponents:outputText value="<STRONG>the html taged value</STRONG>">
Simply add this custom component in a new xhtml file in the defaut jsf folder src/webapp/components.
Like :
src/webapp/components/myComponents/outputText.xhtml
<!DOCTYPE composition PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:c="http://java.sun.com/jsp/jstl/core"
xmlns:cc="http://java.sun.com/jsf/composite">
<cc:interface>
<cc:attribute name="value" required="true"/>
</cc:interface>
<cc:implementation>
<h:outputText value="#{cc.attrs.value}" escape="false"/>
</cc:implementation>
</ui:composition>
Don't forget to add the folowwing namespace in your xhtml pages where the components are used xmlns:field="http://java.sun.com/jsf/composite/components/myComponents in the ui:composition tag
Hope this helps...

JSF Facelets how to include external html?

I have an app that i'm developing and my company has a header banner that is required to be on all pages. We have about 6 different versions floating around my team of that header banner and I now want to make it so that I just include the banner from the source into my app so that if they update the source of the banner, my app's version of the banner is automatically updated as well.
using <ui:include src="http://mycompany.com/banner.html" /> causes the error The markup in the document following the root element must be well-formed..
How can i include this banner even if it's not well formed xml?
My current template:
<!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:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:p="http://primefaces.org/ui"
xmlns:ui="http://java.sun.com/jsf/facelets">
<ui:composition>
<h:body>
<div>
<ui:include src="http://mycompany.com/banner.html" />
</div>
<ui:insert name="content" />
</h:body>
</ui:composition>
</html>
The Facelets <ui:include> tag is the wrong tool for the purpose of embedding external resources in a HTML document.
Use the HTML <iframe> element instead.
<iframe src="http://mycompany.com/banner.html"></iframe>

JSF Javascript failure - myfaces not defined

I'm working on a web solution using myfaces and primefaces. We have several pages in our solution, and some of the get this mystical error myfaces not defined because there is a javascript file that is not included on the page, namely the jsf.js file:
<script type="text/javascript" src="/driwkraft-hig/javax.faces.resource/jsf.js.xhtml?ln=javax.faces&stage=Development">
The error occurs when clicking on certain commandlinks on the page, where the generated javascript has been set to onClick="myfaces.oam.submitForm...
Now, I understand that this is something that the JSF framework adds to the page based on some mystical criteria which I fail to understand. There are pages that appear to be equal with regards to what elements are used, and it succeeds on one and fails on the other.
I have tried to create a test-file where I copied content of one of the failing pages and then removed parts until it would work to figure out what was the source of the problem, but this did not give me anything. My next hunch is that it might be some configuration-error somewhere. But I am completely and utterly blank as to where to start.
I understand I should probable add some code or xml in to this question, but I cannot post the entire solution so I think it is best to do so upon request. Would the web.xml be useful? How about the faces-config.xml?
Any guidance and thoughts are much appreciated!
Edit - adding template
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:ui="http://java.sun.com/jsf/facelets">
<ui:insert name="metadata" />
<h:head>
....
<title>
<ui:insert name="title">
....
</ui:insert>
</title>
</h:head>
<h:body>
....
<ui:insert name="content">
....
</ui:insert>
...
</h:body>
</html>
Edit - adding template client
<!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:ui="http://java.sun.com/jsf/facelets"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:p="http://primefaces.org/ui"
xmlns:dp="http://java.sun.com/jsf/composite/dapsys">
<ui:composition template="/templates/default.xhtml">
<ui:define name="title">TITLE</ui:define>
<ui:define name="metadata">
<f:metadata>
<f:viewParam name="customerId" value="#{CustomerController.customerId}">
</f:viewParam>
<f:viewParam name="edit" value="#{CustomerController.edit}">
</f:viewParam>
<f:viewParam name="activeTab" value="#{CustomerController.activeTab}">
</f:viewParam>
</f:metadata>
</ui:define>
<ui:define name="content">
...
</ui:define>
</ui:composition>
</html>
It's auto-included if there's a <h:head> in the template which automatically renders CSS/JS dependencies from UIViewRoot#getComponentResources() which are added via #ResourceDependency annotation on the JSF component.
Those problem symptoms suggests that there's no <h:head> in the template, but a plain <head>. Therefore JSF is unable to auto-include CSS/JS resource dependencies which in turn causes this JS error.
To fix this problem, just make sure that there's a <h:head> instead of <head> in the template.
<!DOCTYPE html>
<html lang="en"
xmlns="http://www.w3.org/1999/xhtml"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:ui="http://java.sun.com/jsf/facelets">
<h:head> <!-- Look here. -->
<title>Blah</title>
</h:head>
<h:body>
<h1>Blah</h1>
<p>Blah blah.</p>
</h:body>
</html>

Resources