How get the base URL via context path in JSF? - jsf

I have this structure:
WebContent
resources
components
top.xhtml
company
about_us.xhtml
index.xhtml
top.xhtml is a component, that is used in index.xthml and about_us.xhtml too.
top.xhtml
<ul>
<li>Home</li>
<li>About us</li>
...
</ul>
So my problem is, when the current page is index.xhtml the component generates URLs correctly, but when the current page is about_us.xhtml, it generates wrong URLs. I cannot use relative path because it's going to generate the wrong URL too. I think it is because the component is based on the current path of the *.xhtml page.
The only solution I could found out is:
<ul>
<li>Home</li>
<li>About us</li>
...
</ul>
But I think is not 'elegant' at all. Any ideas?

URLs are not resolved based on the file structure in the server side. URLs are resolved based on the real public web addresses of the resources in question. It's namely the webbrowser who has got to invoke them, not the webserver.
There are several ways to soften the pain:
JSF EL offers a shorthand to ${pageContext.request} in flavor of #{request}:
<li>Home</li>
<li>About us</li>
You can if necessary use <c:set> tag to make it yet shorter. Put it somewhere in the master template, it'll be available to all pages:
<c:set var="root" value="#{request.contextPath}/" />
...
<li>Home</li>
<li>About us</li>
JSF 2.x offers the <h:link> which can take a view ID relative to the context root in outcome and it will append the context path and FacesServlet mapping automatically:
<li><h:link value="Home" outcome="index" /></li>
<li><h:link value="About us" outcome="about_us" /></li>
HTML offers the <base> tag which makes all relative URLs in the document relative to this base. You could make use of it. Put it in the <h:head>.
<base href="#{request.requestURL.substring(0, request.requestURL.length() - request.requestURI.length())}#{request.contextPath}/" />
...
<li>Home</li>
<li>About us</li>
(note: this requires EL 2.2, otherwise you'd better use JSTL fn:substring(), see also this answer)
This should end up in the generated HTML something like as
<base href="http://example.com/webname/" />
Note that the <base> tag has a caveat: it makes all jump anchors in the page like relative to it as well! See also Is it recommended to use the <base> html tag? In JSF you could solve it like <a href="#{request.requestURI}#top">top or <h:link value="top" fragment="top" />.

JSTL 1.2 variation leveraged from BalusC answer
<c:set var="baseURL" value="${pageContext.request.requestURL.substring(0, pageContext.request.requestURL.length() - pageContext.request.requestURI.length())}${pageContext.request.contextPath}/" />
<head>
<base href="${baseURL}" />

Related

Dynamic menu in JSF

I am trying to implement a dynamic menu with JSF2/RichFaces. The idea is simple, the menu is defined in the database, and depends on the connected user.
The menu is correctly generated, but the action is not working, and I don't understand why.
This is my JSF code:
<c:forEach items="${sessionMenu.menus}" var="menu"><!-- Menus -->
<li>
${menu.label}
<ul class="sub-menu" id="sub-${menu.label}">
<c:forEach items="${menu.submenus}" var="submenu"><!-- Sub menus -->
<li>
<a4j:commandLink value="${submenu.label}" action="${sessionMenu.action}"/>
</li>
</c:forEach>
</ul>
</li>
</c:forEach>
${sessionMenu.action} returns a string which should redirect to another page (defined as a navigation-case in the faces-config file).
I also tried to replace the action with a hard-coded string, and it works, I guess that the problem arrives with the EL which is not correctly interpreted.
If some one can help me to understand what is wrong?
Edit:
Here is an example of the links generated:
<a id="mainForm:j_id_g_0_2_0_2" onclick="RichFaces.ajax("mainForm:j_id_g_0_2_0_2",event,{"incId":"1"} );return false;" name="mainForm:j_id_g_0_2_0_2" href="#">Screen</a>
This one was generated dynamically and it does nothing;
<a id="mainForm:j_id_g_0_2_0_4" onclick="RichFaces.ajax("mainForm:j_id_g_0_2_0_4",event,{"incId":"1"} );return false;" name="mainForm:j_id_g_0_2_0_4" href="#">Screen</a>
And this one used a static string and the redirection is working properly.
These 2 links were generated in the same page and on the same request.
Finally, I got it working, I just changed the action value to the method name as it is defined in my bean, that means:
<a4j:commandLink value="#{submenu.label}" action="#{sessionMenu.getAction()}" />
If some one can explain why, I am curious.

h:link in JavaServer Faces

I’m trying to add link in jsf:
<h:link value="#{msgs.addproject}" styleClass="addBtn" outcome="/ profile/addproject.xhtml" />
But in page source i get only this:
<span class="addBtn">Add project</span>
Where can be problem? Thanks!
If outcome does not evaluate to a proper link JSF renders a <span> tag instead. Check your / profile/addproject.xhtml whether it is correct(there is a space before profile).

jsf 2 components doesnt have name attribute

In my application after clicking to a link I want to focus to a part of a page after the page load. With static html we can do this by code parts below.
Go to Chapter 4
and the chapter 4 is defined;
<h2><a name="C4">Chapter 4</a></h2>
<p>This chapter explains ba bla bla</p>
In jsf 2 I can not find even name attribute in order to use for this purpose.
Any help will greatly be appreciated.
In JSF, the name attribute is computed based on the combination of the 'id' atribute of the jsf component and the 'id' attribute of the form. The reason for this is explained by BalusC here. So if you specify an id for a JSF component, then the name is also computed for it.
Anyways, starting HTML5 usage of name attribute for <a> tag is made obsolete instead it is recommended to use the id attribute of the nearest container. So do not rely on the name attribute.
Though you can try to focus any of these:
<h2 id="top4">This is a heading</h2> or
<h2><a id="top4">This is a heading</a></h2>
Or simply focus a container on the target page like this:
In HTML 4.01
<div id="top4">
<h2>This is a heading</h2>
<p>This is a paragraph</p>
</div>
In HTML 5
<article id="top4">
<h2>This is a heading</h2>
<p>This is a paragraph</p>
</article>
Now in JSF, this is how you focus the container on the target page:
When the outcome is a different page but in the same application:
<h:link id="link1" value="link1" outcome="welcome" fragment="top4" />
where the outcome is welcome.xhtml which is relative to the context root, and "top4" is the id of the container to be focused when the target page is rendered.
When linking an external site:
<h:outputLink id="link2" value="http://www.msn.com/#spotlight">link2</h:outputLink>
Within the same page:
<h:link id="link3" value="link3" fragment="top4" />
Here there is no outcome specified, so the outcome will be the same page.
See also:
http://dev.w3.org/html5/markup/a.html
h:link
h:outputLink

JSF navigate to external url using image button

Simple question (using JSF 2.0 and primefaces 2.2.1):
I need to create a button or link that will take me to an external url (i.e. www.facebook.com) and I need that button to look like the facebook icon instead of having the literal word. How can I do this? Thank you.
You basically want to end up with the following in the JSF-generated HTML code:
<a><img /></a>
There are several ways how to achieve this in JSF.
Just do it:
<a href="http://www.facebook.com">
<img src="#{request.contextPath}/resources/images/facebook.png" />
</a>
Use <h:graphicImage>:
<a href="http://www.facebook.com">
<h:graphicImage name="images/facebook.png" />
</a>
Eventually, with <h:outputLink>:
<h:outputLink value="http://www.facebook.com">
<h:graphicImage name="images/facebook.png" />
</h:outputLink>
What way to choose depends on whether you really need it to be a JSF component. E.g. in order to be able to grab/manupulate it in backing bean, and/or to re-render by ajax, etc.

how to place dynamic href from a tag in JSF?

I want to use a tag in my JSF page, but i also want to have dynamic href content. I know there is a h:commandLink in JSF but i don`t want use it for my purposes. I have t:dataTable elemet which iterates via results and shows them on my page. Here is the situation:
<t:dataList id="dataTable" value="#{manBean.fullResult}" var="element" first="0" rows="10">
<div class="photos">
<img src="myimages/IN THIS TOO.../image.jpg"
</div>
...
</t:dataList>
I have tried code like this:
<img src="myimages/#element[0]/image.jpg"
. #element[0] is an element of result list from dataTable and contains values like: 0,1,2,3... etc.
this ends witch error that i could not use #{...} in a template. What should i do? Anybody knows a good solution for this?
If you're using JSF on JSP, use <h:outputLink> and <h:graphicImage> instead of <a> and <img>.
<h:outputLink value="myimages/#{element}/image.jpg">
<h:graphicImage value="myimages/#{element}/image.jpg" />
</h:outputLink>
If you're using JSF on Facelets, you can just use EL in template text.
<a href="myimages/#{element}/image.jpg">
<img src="myimages/#{element}/image.jpg" />
</a>

Resources