Facelets: how to pass a ui:insert value as an html attribute? - jsf

I'm trying to accomplish a small tweak in a Facelets/JSF environment. I know next to nothing how all of it fits together.
I have a value defined on various pages as "title"
<ui:define name="title">PageUID_123</ui:define>
On another page I am referencing this with:
<ui:insert name="title"/>
I can wrap html tags around the insert just fine, but I need to be able to output the value of "title" as an attribute of another element. My end goal is for it to render in html like this:
<meta name="pageid" content="PageUID_123"/>
If I try putting the insert tag in the content="" bit, it throws a parsing error. Is there a way to do this?

I don't have a working environment in front of me, but I believe you don't want to you use <ui:define>, but instead you want to use <ui:param> and then use ${x} or #{x} (or forget which or if it matters) to pull them out.
So, for you example you would have:
<ui:param name="title" value="PageUID_123" />
And then:
<meta name="pageid" content="${title}"/>
My only concern with that is that you are using include to have nice templates, i.e.
template:
<html>
<head>
<meta name="pageid" content="${title}"/>
</head>
<body>
<ui:insert name="content" />
</body>
</html>
Inner page:
<html xmlns="...so many">
<ui:param name="title" value="PageUID_123" />
<ui:define name="content">
<!-- content goes here -->
</ui:define>
</html>
And I really don't know if that will fly...
Edit: You may want to try ${title} or #{title} just for kicks the way you're doing it now, it might Just Work.

Related

JSF 2.2: How to set UI parameter using template

I have a template (I removed some lines to keep code simple):
<html xmlns="http://www.w3.org/1999/xhtml">
<h:head>
<title>#{title}</title>
</h:head>
</html>
And I want to set the window title with a String result from a resource bundle:
<ui:composition ... template="default.xhtml">
<ui:param name="title">
<h:outputFormat value="#{0} - Testing">
#{mycontroller.title}
<h:outputFormat>
</ui:param>
</ui:composition ...>
But for my surprise ui:param doesn't support body content. I changed to Omnifaces, that supports body content.
<ui:composition ... template="default.xhtml">
<o:param name="title">
<h:outputFormat value="#{0} - Testing">
#{mycontroller.title}
<h:outputFormat>
</o:param>
</ui:composition ...>
But doesn't works. The #{title} is empty in my template file. There are some way to set complex texts to my template file?

Nested JSF composite components not fully compatible with Primefaces

I'm trying to create a nested JSF composite control wrapped in a Primefaces Accordion control. However when the tab components are placed within the nested component they are not rendered at all.
outerComponent.xhtml
<composite:interface/>
<composite:implementation>
<p:accordionPanel>
<composite:insertChildren/>
</p:accordionPanel>
</composite:implementation>
innerComponent.xhtml
<composite:interface>
<composite:attribute name="title" type="java.lang.String"/>
</composite:interface>
<composite:implementation>
<p:tab id="#{cc.attrs.title}" title="#{cc.attrs.title}">
Some content
</p:tab>
</composite:implementation>
testPage.xhtml
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:w="http://java.sun.com/jsf/composite/wizard"
xmlns:p="http://primefaces.org/ui">
<h:head>
</h:head>
<h:body>
<w:outerComponent>
<w:innerComponent title="tab1"/>
</w:outerComponent>
</h:body>
</html>
HTML output:
<html xmlns="http://www.w3.org/1999/xhtml"><head><link type="text/css"
rel="stylesheet" href="/iip/javax.faces.resource/theme.css.xhtml?ln=primefaces-
aristo-custom" /><link type="text/css" rel="stylesheet" href="/iip/
javax.faces.resource/primefaces.css.xhtml?ln=primefaces" /><script type="text/
javascript" src="/iip/javax.faces.resource/jquery/jquery.js.xhtml?
ln=primefaces"></script><script type="text/javascript" src="/iip/
javax.faces.resource/primefaces.js.xhtml?ln=primefaces"></script></head>
<body>
<div id="j_idt7:j_idt10" class="ui-accordion ui-widget ui-helper-reset ui-hidden-
container" role="tablist"><input type="hidden" id="j_idt7:j_idt10_active"
name="j_idt7:j_idt10_active" value="0" /></div>
<script id="j_idt7:j_idt10_s" type="text/
javascript">PrimeFaces.cw('AccordionPanel','widget_j_idt7_j_idt10',
{id:'j_idt7:j_idt10'});</script>
</body</html>
When it runs there are no errors and while the Accordion divs are rendered, the tabs are not. However if I move the <p:tab> tags into the outerComponent.xhtml file then they are rendered correctly, but that is not what I require.
Any suggestions?
Iterating components like <p:dataTable>, <p:tabView>, <p:accordionPanel>, etc cannot have composites as direct children. They should have fullworthy <p:column> or <p:tab> components as direct children. While iterating during view render time, they loop over children and do an instanceof UIColumn or instanceof Tab check on them before rendering. If it fails (the composite is NamingContainer), then it would be plain ignored. This is "by design".
Your best bet is using a tag file instead of a composite component as child of an iterating component.
Note that this isn't specfic to PrimeFaces. Standard <h:dataTable> has exactly the same problem.
See also:
When to use <ui:include>, tag files, composite components and/or custom components?
How to create a composite component for a datatable column?
Did you try to do this without composite - I mean put it all together in the testPage.xhtml. I haven't tried this specific combination but I've had problems with both tab and accordion in combination with other components. To check if the problem lies in the composite or in the combination of components.
It seems that there are some javascript that is "not compatible" with one another.
If you still have the problem, you could try to encapsulate the tab. I tried different combinations and it seems that some are working depending on which components are causing the problem. I'd try with a <div id="tabContainer"> around the tab first and eventually go to p:panel if it doesn't work.

AutoSuggest running problem

This XML file does not appear to have any style information associated with it. The document tree is shown below.
<html xmlns="http://www.w3c.org/1999/xhtml" xmlns:h="http://java.sun.com/jsf/html" xmlns:p="http://primefaces.prime.com.tr/ui">
<h:head>
<link type="text/css" rel="stylesheet" href="themes/bluesky/skin.css"/>
</h:head>
<h:body>
<center>
<p:panel header="Login Form" style="width: 350;">
<h:form>
<h:panelGrid columns="2" cellpadding="2">
<h:outputLabel for="#{UserManagedBean.username}" value="UserName"/>
<h:inputText value="#{UserManagedBean.username}" label="UserName"/>
<h:outputLabel for="#{UserManagedBean.password}" value="Password"/>
<h:inputSecret value="#{UserManagedBean.password}"/>
<h:commandButton type="submit" value="Login" action="#{UserManagedBean.login}"/>
</h:panelGrid>
</h:form>
</p:panel>
<div>
<h:messages/>
</div>
</center>
</h:body>
</html>
What could be the possible problem here? I really don't know.
This XML file does not appear to have any style information associated with it. The document tree is shown below.
This is a typical MSIE warning message whenever you request a X(HT)ML file which does not have a XSL stylesheet (which is basically like CSS for HTML).
That you're getting this on a Facelet page can only mean that the request URL did not match the URL pattern of the FacesServlet as definited in your webapp's web.xml. In other words, the FacesServlet has never got any chance to run, parse that Facelet file and do all the JSF works to generate a bunch of HTML so that the webbrowser has something sensible to work with.
There are 2 solutions for this problem:
Fix your request URL (the one in browser address bar) to match the URL pattern of the FacesServlet in web.xml. If it is for example <url-pattern>*.jsf</url-pattern>, then you need to replace .xhtml extension in URL by .jsf.
Change the URL pattern of your FacesServlet to <url-pattern>*.xhtml</url-pattern>. This way you do not need to worry about accidently seeing XHTML source anymore.
Please note that this all has nothing to do with "autosuggest problem". Work yourself through some basic JSF tutorials first. Our JSF wiki page has some good links.
Oh, before I forgot, the <center> element is deprecated since HTML4 in 1998. Do not use it. Use CSS margin: 0 auto;. Try to avoid reading tutorials/books older than 2 years.

How to set a define inside other define

I'm developing a web application in jboss, seam, richfaces.
I'm using a template(xhtml) as master page of all others and there i set two insert tags. <ui:insert name="head"/>
<ui:insert name="body"/>
The problem is that in pages that use this master page as template, the <ui:define name="head">...</ui:define> must be defined inside the <ui:define name="body">...</ui:define>.
How can i do this?
Basically, what i want is to do the following:
<ui:define name="body">... <ui:define name="head"> <meta name="title" content="#{something.title}" /> </ui:define> ...</ui:define>
the master page must return : <meta name="title" content="#{something.title}" /> on the <ui:insert name="head"/>
Thanks in advance
I don't think facelets work like that. It compiles and reads the template.
So I think you can just define how many definitions you want and dont care about nesting.
ie:
//In your template.xhtml
<ui:insert name="outer">
BLA BLA BLA
<ui:insert name="inner"/>
BLA BLA BLA
</ui:insert>
And when you want to use this template simply:
<ui:define name="outer">
Here you can overwrite outer (This will probably overwrite inner, not sure, you need to test it)
</ui:define>
<ui:define name="inner">
Or you can ONLY overwrite inner here if you want
</ui:define>
You can use <ui:param> in order to define content on each page. For example
in the template:
<meta name="title" content="#{titleParam}" />
in the page that uses the template:
<ui:param name="titleParam" value="customValueForThisPage" />

Netbeans, jsp:include

I'm using JSF in NetBeans. All I want to do is to include a page within another page. But whatever I tried, and when I run the main page, I get no error but I can't see my included page in a main page. Why?
My main page is:
<jsp:root version="2.1" xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:jsp="http://java.sun.com/JSP/Page"
xmlns:webuijsf="http://www.sun.com/webui/webuijsf">
<jsp:directive.page contentType="text/html;charset=UTF-8" pageEncoding="UTF-8"/>
<f:view>
<webuijsf:page id="page1">
<webuijsf:html id="html1">
<webuijsf:head id="head1">
<webuijsf:link id="link1" url="/css/front.css"/>
<webuijsf:script id="script1" url="/scripts/front2.js"/>
<webuijsf:link url="favicon.ico" rel="shortcut icon" type="image/x-icon"/>
</webuijsf:head>
<webuijsf:body id="body1" style="-rave-layout: grid">
<webuijsf:form id="form1">
<!-- This is where I include my page -->
<f:subview id="nav">
<jsp:include page="frontsitemenu.jsp" />
</f:subview>
</webuijsf:form>
</webuijsf:body>
</webuijsf:html>
</webuijsf:page>
</f:view>
My included page is:
<f:subview id="frontsitemenu">
<f:verbatim>
<p>rrrrrrrrrrrrrrrrrr</p>
</f:verbatim>
</f:subview>
Can someone please help me? Thanks
I suggest you use:
<%#include file="_frontsitemenu.jsp" %>
Thats whats working for me
You should have ony one f:subview per include. Now you've two, a <f:subview id="nav"> which wraps the jsp:include and a <f:subview id="frontsitemenu"> inside the include page itself. The normal practice is that they're placed in the include file only. So, remove the <f:subview id="nav"> from the parent page.

Resources