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><a href="index.xhtml">Home</a></li> <li><a href="company/about_us.xhtml">About us</a></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><a href="${pageContext.request.contextPath}/webname/index.xhtml">Home</a></li> <li><a href="${pageContext.request.contextPath}/webname/about_us.xhtml">About us</a></li> ... </ul>
But I think is not 'elegant' at all. Any ideas?
The context path is the path to Confluence relative to the root directory of the webserver. For example, the context path for this site is an empty string, because it is deployed at the root. The context path for a Confluence instance deployed at http://www.example.com/confluence would be /confluence .
String getContextPath() Returns the context path of the web application. The context path is the portion of the request URI that is used to select the context of the request. The context path always comes first in a request URI.
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><a href="#{request.contextPath}/index.xhtml">Home</a></li> <li><a href="#{request.contextPath}/about_us.xhtml">About us</a></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><a href="#{root}index.xhtml">Home</a></li> <li><a href="#{root}about_us.xhtml">About us</a></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><a href="index.xhtml">Home</a></li> <li><a href="about_us.xhtml">About us</a></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 <a href="#top">
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</a>
or <h:link value="top" fragment="top" />
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With