I have been playing with JSF and have a project working that has a header/footer/navigation/content
panels. The project, however, goes from page 1 to page 2, etc., with each page having a different layout. How can I create a reusable template that keeps the same look and feel from page to page, i.e., header/footer/navigation stay the same, but content is updated?
This sounds like a classic case of a master template. In such a template you put everything that's common to all pages and then your actual pages reference this template and "fill in the blanks". In a way it's the reverse of the also classic include.
E.g.
/WEB-INF/templates/masterTemplate.xhtml:
<!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>
<title>
<ui:insert name="title">Some title</ui:insert>
</title>
</h:head>
<ui:include src="header.xhtml"/>
<h:body>
<ui:insert name="content" />
</h:body>
<ui:include src="footer.xhtml"/>
</html>
A page uses this as follows, e.g.
/hello.xhtml
<ui:composition template="/WEB-INF/templates/masterTemplate.xhtml"
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"
>
<ui:define name="title">hello</ui:define>
<ui:define name="content">
Hi, this is the page
</ui:define>
</ui:composition>
Related
I have written a template page for using in every page.In this template includes a left div a haed div and a footer.So central is for my forms.But forms are viewing below of footer.How to solve this layout problem.Here is my using of template
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://xmlns.jcp.org/jsf/html"
xmlns:ui="http://xmlns.jcp.org/jsf/facelets">
<h:head>
<title>Hakkında</title>
</h:head>
<body>
<ui:composition template="/templates/mainTemplate.xhtml">
<h:form>
Some components
</h:form>
</ui:composition>
</body>
Add in template space for body
<ui:insert name="body">Default Body</ui:insert>
and redefine it in your view (page)
<ui:define name="body">
<h:form id="homeForm">
<!-- your components -->
</h:form>
</ui:define>
I'm having a problem using template that has another nested template within it.
I get
java.io.FileNotFoundException
at org.apache.naming.resources.DirContextURLConnection.getInputStream(DirContextURLConnection.java:403)
I have this basic template :
(./resources/css/template.xhtml)
<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">
<h:head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<h:outputStylesheet library="css" name="stylesheet.css"/>
<title><ui:insert name="title"> Facelets template </ui:insert></title>
</h:head>
<h:body>
<div id="top" class="top_content">
<ui:insert name="top">Top</ui:insert>
</div>
<div>
<div id="content" class="center_content">
<ui:insert name="content">Content</ui:insert>
</div>
</div>
</h:body>
and templateLogin which "inherits" template :
(./resources/css/templateLogin.xhtml)
<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"
template="./resources/css/template.xhtml">
<ui:define name="title">
Some title
</ui:define>
<ui:define name="top">
<div id="top">
...code here
</div>
</ui:define>
</ui:composition>
and I have welcome file which is welcome file of the web application which uses templateLogin:
<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"
template="./resources/css/templateLogin.xhtml">
<ui:define name="title">
Welcome title
</ui:define>
As I said, I get file not found exception. When I define as template template.xhtml for the welcome file , there's no error. It's as it doesn't see templateLogin.xhtml in the specified path, but it's definetely there.
Any ideas? Thanks.
Get rid of the leading period in your template paths. The leading period makes it relative to the current folder of the template client. If the template path starts with / then it becomes absolute to the web content root.
Thus, so:
template="/resources/css/template.xhtml"
and
template="/resources/css/templateLogin.xhtml"
Unrelated to the concrete problem, there are 2 problems with those paths:
Template files are not CSS files.
Template files are not supposed to be publicly accessible.
Put them in /WEB-INF folder. E.g.
template="/WEB-INF/templates/layout.xhtml"
and
template="/WEB-INF/templates/login.xhtml"
See also:
Which XHTML files do I need to put in /WEB-INF and which not?
Well if i look to your code then i see some strange things. Your main template is located in
resources/css Thats fine. But then your other template is also located in /resources/css
In your include you say:
template="./resources/css/template.xhtml"
So you suggest that it is in /resources/resources/css and yes the file is not there.
So trie in your include this:
template="template.xhtml"
I don't know where your templateLogin.xhtml is but also here pay attention to your include
Use:
#{request.contextPath}/resources/css/default.css
this is a summary of what i understood:
ui:decorate
can use ui:define
can use ui:param
can have external content
ui:composition
can use ui:define
can use ui:param
-> can NOT have external content
ui:include
-> can NOT use ui:define
can use ui:param
can have external content
assumed these, i can use
ui:decorate as ui:composition
<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">
<!-- no content here -->
<ui:decorate template="templates/page.xhtml">
<ui:define name="test">
<h:outputText value="#{someBean.someProperty}"/>
</ui:define>
</ui:decorate>
<!-- no content here -->
</html>
ui:decorate as ui:include
<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">
<h:panelGroup>...</h:panelGroup>
<ui:decorate template="fragments/page.xhtml">
<ui:param name="test" value="#{someBean.someProperty}"/>
</ui:decorate>
<h:panelGroup>...</h:panelGroup>
</html>
so, am i missing something? misunderstanding?
if i'm right, why are there 3 different components? (please do not say that they are used for different goals, if i'm right)
I have the following template:
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html xmlns:h="http://java.sun.com/jsf/html"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:f="http://java.sun.com/jsf/core">
<h:head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>
<ui:insert name="title" />
</title>
</h:head>
<h:body>
<div id="header">Some header</div>
<div id="content">
<ui:insert name="content" />
</div>
<div id="footer">Some Footer</div>
</h:body>
</html>
and the following client template:
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
template="templates/template.xhtml">
<ui:define name="title">
English Online
</ui:define>
<ui:define name="content">
<h1>Кириллический шрифт</h1>
</ui:define>
</ui:composition>
Now the problem is:
When I invoke the master template from the composite with the Cyrillic font in "h1"-tag, the browswer gives out:
com.sun.org.apache.xerces.internal.impl.io.MalformedByteSequenceException: Invalid byte 2 of 2-byte UTF-8 sequence.
Even though I use the Cyrillic font in the master-client template it is ok. And when the client template h1-tag contains English it also works.
How can I fight this problem?
That can happen if those files are not saved as UTF-8. The answer depends on the editor used to save the files. If it's for example Eclipse (your question history hints that you're using it or are at least familiar with it), then you need to change Window > Preferences > General > Workspace > Text file encoding to UTF-8.
After making this change, edit and re-save the file(s).
See also:
Unicode - How to get the characters right?
I would like to use a Facelets template within another template. Currently I have a "base" template that so far has been enough for all pages I've done. It has a top and a content area.
The top has logo, menu, login/logout functionality, while the content area shows, well, the content.
Now I need to do another page (to hold user profile information) where I'd like to have a menu to the left and show result to the right. This page shall be inserted in the base template content area.
Is it possible to create a new template which defines those two areas (profile_left and profile_content) and somehow still use the base template?
I see no reason why I couldn't just copy the code in the base template and add the new "defines" that I want (profile_left and profile_content), but I still wonder if it's possible to keep using the original base template.
You can extend from templates as deep as you want. It's not true that you can extend from only one template or something as you seem to think.
For example:
/WEB-INF/templates/base.xhtml
<!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>
<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>
/WEB-INF/templates/profile.xhtml
<ui:composition template="/WEB-INF/templates/base.xhtml"
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"
>
<ui:define name="content">
<div id="profile_left"><ui:insert name="profile_left" /></div>
<div id="profile_right"><ui:insert name="profile_right" /></div>
</ui:define>
</ui:composition>
/user.xhtml
<ui:composition template="/WEB-INF/templates/profile.xhtml"
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"
>
<ui:define name="title">User profile</ui:define>
<ui:define name="profile_left">
Profile left.
</ui:define>
<ui:define name="profile_right">
Profile right.
</ui:define>
</ui:composition>
See also:
How to include another XHTML in XHTML using JSF 2.0 Facelets?