JSF h:outputStylesheet renders nothing - jsf

This
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:ui="http://java.sun.com/jsf/facelets">
<h:outputStylesheet name="test.css" />
renders nothing. Do I have to add some configuration? The test.css is avaible in my resource folder.

JSF injects stylesheets to either HTML head or body elements (head is the default, IIRC). For JSF to find head or body, you have to declare them as <h:head></h:head> and <h:body></h:body> (not plain <head></head> etc).

JSF will inject scripts inline at the tag location if you omit the target, so using <h:outputScript> will work if even you don't have <h:head> or <h:body> tags. The <h:outputStylesheet> tag will alway inject into the head section regardless of target, so there has to be <h:head> elements defined in order to use that tag.

Related

passing data to the jsf template [duplicate]

What is the most correct way to include another XHTML page in an XHTML page? I have been trying different ways, none of them are working.
<ui:include>
Most basic way is <ui:include>. The included content must be placed inside <ui:composition>.
Kickoff example of the master page /page.xhtml:
<!DOCTYPE html>
<html lang="en"
xmlns="http://www.w3.org/1999/xhtml"
xmlns:f="http://xmlns.jcp.org/jsf/core"
xmlns:h="http://xmlns.jcp.org/jsf/html"
xmlns:ui="http://xmlns.jcp.org/jsf/facelets">
<h:head>
<title>Include demo</title>
</h:head>
<h:body>
<h1>Master page</h1>
<p>Master page blah blah lorem ipsum</p>
<ui:include src="/WEB-INF/include.xhtml" />
</h:body>
</html>
The include page /WEB-INF/include.xhtml (yes, this is the file in its entirety, any tags outside <ui:composition> are unnecessary as they are ignored by Facelets anyway):
<ui:composition
xmlns="http://www.w3.org/1999/xhtml"
xmlns:f="http://xmlns.jcp.org/jsf/core"
xmlns:h="http://xmlns.jcp.org/jsf/html"
xmlns:ui="http://xmlns.jcp.org/jsf/facelets">
<h2>Include page</h2>
<p>Include page blah blah lorem ipsum</p>
</ui:composition>
This needs to be opened by /page.xhtml. Do note that you don't need to repeat <html>, <h:head> and <h:body> inside the include file as that would otherwise result in invalid HTML.
You can use a dynamic EL expression in <ui:include src>. See also How to ajax-refresh dynamic include content by navigation menu? (JSF SPA).
<ui:define>/<ui:insert>
A more advanced way of including is templating. This includes basically the other way round. The master template page should use <ui:insert> to declare places to insert defined template content. The template client page which is using the master template page should use <ui:define> to define the template content which is to be inserted.
Master template page /WEB-INF/template.xhtml (as a design hint: the header, menu and footer can in turn even be <ui:include> files):
<!DOCTYPE html>
<html lang="en"
xmlns="http://www.w3.org/1999/xhtml"
xmlns:f="http://xmlns.jcp.org/jsf/core"
xmlns:h="http://xmlns.jcp.org/jsf/html"
xmlns:ui="http://xmlns.jcp.org/jsf/facelets">
<h:head>
<title><ui:insert name="title">Default title</ui:insert></title>
</h:head>
<h:body>
<div id="header">Header</div>
<div id="menu">Menu</div>
<div id="content"><ui:insert name="content">Default content</ui:insert></div>
<div id="footer">Footer</div>
</h:body>
</html>
Template client page /page.xhtml (note the template attribute; also here, this is the file in its entirety):
<ui:composition template="/WEB-INF/template.xhtml"
xmlns="http://www.w3.org/1999/xhtml"
xmlns:f="http://xmlns.jcp.org/jsf/core"
xmlns:h="http://xmlns.jcp.org/jsf/html"
xmlns:ui="http://xmlns.jcp.org/jsf/facelets">
<ui:define name="title">
New page title here
</ui:define>
<ui:define name="content">
<h1>New content here</h1>
<p>Blah blah</p>
</ui:define>
</ui:composition>
This needs to be opened by /page.xhtml. If there is no <ui:define>, then the default content inside <ui:insert> will be displayed instead, if any.
<ui:param>
You can pass parameters to <ui:include> or <ui:composition template> by <ui:param>.
<ui:include ...>
<ui:param name="foo" value="#{bean.foo}" />
</ui:include>
<ui:composition template="...">
<ui:param name="foo" value="#{bean.foo}" />
...
</ui:composition >
Inside the include/template file, it'll be available as #{foo}. In case you need to pass "many" parameters to <ui:include>, then you'd better consider registering the include file as a tagfile, so that you can ultimately use it like so <my:tagname foo="#{bean.foo}">. See also When to use <ui:include>, tag files, composite components and/or custom components?
You can even pass whole beans, methods and parameters via <ui:param>. See also JSF 2: how to pass an action including an argument to be invoked to a Facelets sub view (using ui:include and ui:param)?
Design hints
The files which aren't supposed to be publicly accessible by just entering/guessing its URL, need to be placed in /WEB-INF folder, like as the include file and the template file in above example. See also Which XHTML files do I need to put in /WEB-INF and which not?
There doesn't need to be any markup (HTML code) outside <ui:composition> and <ui:define>. You can put any, but they will be ignored by Facelets. Putting markup in there is only useful for web designers. See also Is there a way to run a JSF page without building the whole project?
The HTML5 doctype is the recommended doctype these days, "in spite of" that it's a XHTML file. You should see XHTML as a language which allows you to produce HTML output using a XML based tool. See also Is it possible to use JSF+Facelets with HTML 4/5? and JavaServer Faces 2.2 and HTML5 support, why is XHTML still being used.
CSS/JS/image files can be included as dynamically relocatable/localized/versioned resources. See also How to reference CSS / JS / image resource in Facelets template?
You can put Facelets files in a reusable JAR file. See also Structure for multiple JSF projects with shared code.
For real world examples of advanced Facelets templating, check the src/main/webapp folder of Java EE Kickoff App source code and OmniFaces showcase site source code.
Included page:
<!-- opening and closing tags of included page -->
<ui:composition ...>
</ui:composition>
Including page:
<!--the inclusion line in the including page with the content-->
<ui:include src="yourFile.xhtml"/>
You start your included xhtml file with ui:composition as shown above.
You include that file with ui:include in the including xhtml file as also shown above.

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.

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:

Netbeans errors "The attribute target is not defined in the component outputStylesheet"

I have entered the following code:
<h:outputStylesheet library="css" name="style.css" target="body" />
The problem is that it is giving me an error on target="body" saying:
The attribute target is not defined in the component outputStylesheet
In the html part if the html I have the following:
<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:pe="http://primefaces.org/ui/extensions">
How can I solve this issue?
Thanks
Look in the tag documentation of <h:outputStylesheet>. It indeed doesn't list target attribute. Perhaps you're confusing with the one from <h:outputScript>.
The <h:outputStylesheet> is by default always relocated to HTML <head>, for the very simple reason because it's illegal to have a <style> or <link> element inside the HTML <body>. The <h:outputScript> however is by default located at exactly the same location as where it's been declared. The <script> element as generated by it may be placed anywhere in the HTML <head> or <body>. You can let JSF auto-relocate this by setting the target attribute to head (will then appear in <head>) or body (will then appear in end of <body>).
Just remove it. If target="body" would theoretically have worked, it would only end up in illegal HTML output anyway.
<h:outputStylesheet library="css" name="style.css" />
Unrelated to the concrete problem, a resource library name of "css" is semantically wrong. Put it in the resource name.
<h:outputStylesheet name="css/style.css" />
See also:
What is the JSF resource library for and how should it be used?

How to include another XHTML in XHTML using JSF 2.0 Facelets?

What is the most correct way to include another XHTML page in an XHTML page? I have been trying different ways, none of them are working.
<ui:include>
Most basic way is <ui:include>. The included content must be placed inside <ui:composition>.
Kickoff example of the master page /page.xhtml:
<!DOCTYPE html>
<html lang="en"
xmlns="http://www.w3.org/1999/xhtml"
xmlns:f="http://xmlns.jcp.org/jsf/core"
xmlns:h="http://xmlns.jcp.org/jsf/html"
xmlns:ui="http://xmlns.jcp.org/jsf/facelets">
<h:head>
<title>Include demo</title>
</h:head>
<h:body>
<h1>Master page</h1>
<p>Master page blah blah lorem ipsum</p>
<ui:include src="/WEB-INF/include.xhtml" />
</h:body>
</html>
The include page /WEB-INF/include.xhtml (yes, this is the file in its entirety, any tags outside <ui:composition> are unnecessary as they are ignored by Facelets anyway):
<ui:composition
xmlns="http://www.w3.org/1999/xhtml"
xmlns:f="http://xmlns.jcp.org/jsf/core"
xmlns:h="http://xmlns.jcp.org/jsf/html"
xmlns:ui="http://xmlns.jcp.org/jsf/facelets">
<h2>Include page</h2>
<p>Include page blah blah lorem ipsum</p>
</ui:composition>
This needs to be opened by /page.xhtml. Do note that you don't need to repeat <html>, <h:head> and <h:body> inside the include file as that would otherwise result in invalid HTML.
You can use a dynamic EL expression in <ui:include src>. See also How to ajax-refresh dynamic include content by navigation menu? (JSF SPA).
<ui:define>/<ui:insert>
A more advanced way of including is templating. This includes basically the other way round. The master template page should use <ui:insert> to declare places to insert defined template content. The template client page which is using the master template page should use <ui:define> to define the template content which is to be inserted.
Master template page /WEB-INF/template.xhtml (as a design hint: the header, menu and footer can in turn even be <ui:include> files):
<!DOCTYPE html>
<html lang="en"
xmlns="http://www.w3.org/1999/xhtml"
xmlns:f="http://xmlns.jcp.org/jsf/core"
xmlns:h="http://xmlns.jcp.org/jsf/html"
xmlns:ui="http://xmlns.jcp.org/jsf/facelets">
<h:head>
<title><ui:insert name="title">Default title</ui:insert></title>
</h:head>
<h:body>
<div id="header">Header</div>
<div id="menu">Menu</div>
<div id="content"><ui:insert name="content">Default content</ui:insert></div>
<div id="footer">Footer</div>
</h:body>
</html>
Template client page /page.xhtml (note the template attribute; also here, this is the file in its entirety):
<ui:composition template="/WEB-INF/template.xhtml"
xmlns="http://www.w3.org/1999/xhtml"
xmlns:f="http://xmlns.jcp.org/jsf/core"
xmlns:h="http://xmlns.jcp.org/jsf/html"
xmlns:ui="http://xmlns.jcp.org/jsf/facelets">
<ui:define name="title">
New page title here
</ui:define>
<ui:define name="content">
<h1>New content here</h1>
<p>Blah blah</p>
</ui:define>
</ui:composition>
This needs to be opened by /page.xhtml. If there is no <ui:define>, then the default content inside <ui:insert> will be displayed instead, if any.
<ui:param>
You can pass parameters to <ui:include> or <ui:composition template> by <ui:param>.
<ui:include ...>
<ui:param name="foo" value="#{bean.foo}" />
</ui:include>
<ui:composition template="...">
<ui:param name="foo" value="#{bean.foo}" />
...
</ui:composition >
Inside the include/template file, it'll be available as #{foo}. In case you need to pass "many" parameters to <ui:include>, then you'd better consider registering the include file as a tagfile, so that you can ultimately use it like so <my:tagname foo="#{bean.foo}">. See also When to use <ui:include>, tag files, composite components and/or custom components?
You can even pass whole beans, methods and parameters via <ui:param>. See also JSF 2: how to pass an action including an argument to be invoked to a Facelets sub view (using ui:include and ui:param)?
Design hints
The files which aren't supposed to be publicly accessible by just entering/guessing its URL, need to be placed in /WEB-INF folder, like as the include file and the template file in above example. See also Which XHTML files do I need to put in /WEB-INF and which not?
There doesn't need to be any markup (HTML code) outside <ui:composition> and <ui:define>. You can put any, but they will be ignored by Facelets. Putting markup in there is only useful for web designers. See also Is there a way to run a JSF page without building the whole project?
The HTML5 doctype is the recommended doctype these days, "in spite of" that it's a XHTML file. You should see XHTML as a language which allows you to produce HTML output using a XML based tool. See also Is it possible to use JSF+Facelets with HTML 4/5? and JavaServer Faces 2.2 and HTML5 support, why is XHTML still being used.
CSS/JS/image files can be included as dynamically relocatable/localized/versioned resources. See also How to reference CSS / JS / image resource in Facelets template?
You can put Facelets files in a reusable JAR file. See also Structure for multiple JSF projects with shared code.
For real world examples of advanced Facelets templating, check the src/main/webapp folder of Java EE Kickoff App source code and OmniFaces showcase site source code.
Included page:
<!-- opening and closing tags of included page -->
<ui:composition ...>
</ui:composition>
Including page:
<!--the inclusion line in the including page with the content-->
<ui:include src="yourFile.xhtml"/>
You start your included xhtml file with ui:composition as shown above.
You include that file with ui:include in the including xhtml file as also shown above.

Resources