Implementing JSF Composite Component in Maven project - jsf

It seems people are able to implement composite components in SWF 2.3.1, but I cannot find a clear reference for how this is done. I have followed the basic structure for a JSF composite component, but my SWF application does not seem to recognize the taglib namespace.
There is a toolkit/IDE warning, but more importantly there is a runtime warning seen in the browser, JSF is displaying the following warning on the screen to the user:
Warning: This page calls for XML namespace http://java.sun.com/jsf/composite/myjsf declared with prefix mj but no taglibrary exists for that namespace.
Component definition:
src/main/resources/myjsf/testComponent.xhtml :
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:composite="http://java.sun.com/jsf/composite">
<composite:interface>
<composite:attribute name="attr" />
</composite:interface>
<composite:implementation>
#{cc.attrs.attr});
</composite:implementation>
</html>
Referenced in a given xhtml:
<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:p="http://primefaces.org/ui"
xmlns:mj="http://java.sun.com/jsf/composite/myjsf">
<!-- snip -->
<mj:testComponent attr="x" />
</ui:composition>

The folder src/main/resources/myjsf/ isn't right place for your composite component. Composite component in maven projects should be in src/main/webapp/resources/ and in your case it should be src/main/webapp/resources/myjsf/testComponent.xhtml.
As you are using Maven you should know that webapp folder is folder whose content will be deployed in root folder of your application, and thus it is somehow analogue as WebContent folder in standard dynamic web project in Eclipse.

Related

ui:include includes wrong file in JSF 2.2

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.

jsf - facelets - pack library jar with *.xhtml-s and beans only

I could read the tutorial which describes how to pack facelets to jar to reuse tags as library...
The thing is the instruction recommends using both JSP and JSF in manner as (see code snippet);
<jsp:root xmlns:jsp="http://java.sun.com/JSP/Page"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:c="http://java.sun.com/jstl/core"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core" version="2.0">
<ui:composition>
...
</ui:composition>
</jsp:root>
...and using both .taglib.xml + .tld conf files... :(
So I don't get it may ui:composition in *.xhtml be started as usual by (see code snippet) ...
<ui:composition
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:c="http://java.sun.com/jstl/core"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core" version="2.0">
...
</ui:composition>
...not to deal with jsp at all? And if, yes, how this kind of library can be added to dynamic web project in eclipse for example?
So my question concerning the tutorial is...
A) is there a way to avoid using *.tld and use have *.taglib.xml only for the lib if the tag library will contain xhtml files only?
B) is there a way to have xhtml-s in non META-INF sub-folder but in some random one?
C) How to automate this kind of library creation process? I mean should I create a project in eclipse (?project category) to have correct folders structure by default to make possible re-compile it and test it and only after that pack it as a jsf library?
I googled a lot but couldn't find solutions variations so please share your experience;
Thanks

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...

Extract XML namespace declarations into separate tagfile/taglib

I would like to seperate my XML namespace declarations at the top of the page into a seperate (tag)file in which I can include in any Facelets page I wish.
Is this possible? Or do I need to copypaste all XML namespaces in each Facelets file?
Here's a theoretical example, xmlns.xhtml:
<something
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"
xmlns:c="http://java.sun.com/jsp/jstl/core"
...
/>
And the template file which could use it: mypage.xhtml:
<f:view xmlns="xmlns.xhtml">
<h:head>
...
</h:head>
<h:body>
...
</h:body>
</f:view>
Nope, not possible. They must be present during XML compile time already.
Your best bet is creating or configuring XHTML template(s) in your IDE so that you can choose from them in New File without the need to copypaste/retype the boilerplate.
Here are some screens from Eclipse + JBoss Tools:

param reference to bean not being passed into composite component

i'm having a bit of trouble with a composite component in JSF 2.1 vanilla (on glassfish 3.1). the simplified version of my problem is here:
[composite component]
<?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://java.sun.com/jsf/core"
xmlns:c="http://java.sun.com/jsp/jstl/core"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:p="http://primefaces.org/ui"
xmlns:cc="http://java.sun.com/jsf/composite">
<!-- INTERFACE -->
<cc:interface>
<cc:attribute name="value" required="true"/>
<cc:attribute name="title" required="false" default=""/>
<cc:editableValueHolder name="inputTarget" targets="labeledInputField"/>
</cc:interface>
<!-- IMPLEMENTATION -->
<cc:implementation>
<p:inputText id="labeledInputField"
label="#{cc.attrs.title}"
value="#{cc.attrs.value}"
title="#{cc.attrs.title}">
<cc:insertChildren/>
</p:inputText>
</cc:implementation>
</html>
[implemented in]
<!-- thisPerson is passed in via ui:param to the facelet containing this code.
it works in other (non-composite) components on the page -->
<comp:labeledInputText
id="baseUsername"
value="#{controller.username}"
title="#{bundle.Username}">
<f:validator for="inputTarget" binding="#{thisPerson.usernameValidator}"/>
<f:converter for="inputTarget" converterId="#{whiteSpaceTrimConverter}"/>
</comp:labeledInputText>
the problem is, the "thisPerson.usernameValidator" is evaluating to NULL, which then causes the com.sun.faces.facelets.tag.jsf.ValidatorTagHandlerDelegateImpl to then skip to the code that attempts to load the validator by "validatorID" which is not set because we're trying to send in the validator by "binding". is there a way to get the composite to evaluate the ui:param value, or a workaround that does not require reworking the validator (it's a huge anti-pattern and i don't have time to reverse the damage right now). assume the validator HAS to come in via binding.
i know the composite works because in a different facelet, i have the validator binding against a concrete bean reference, rather than a "soft" reference, and it works like a champ.
TIA
Without knowing your exact JSF implementation, I am going to assume Mojarra, you may be running into the following known bug.
http://java.net/jira/browse/JAVASERVERFACES-2040
Regardless if this is your exact problem or not, you can try to disable partial state saving and see if this resolves your issue. If it does then that means that you are facing this issue, which apparently was (fixed?) in later versions of Mojarra.
Another possibility would be to simply use renderFacet instead of insertChildren and insert your validators in the form of a facet.

Resources