J'ai cette structure:
WebContent
resources
components
top.xhtml
company
about_us.xhtml
index.xhtml
top.xhtml
est un composant utilisé dans index.xthml
et about_us.xhtml
aussi.
top.xhtml
<ul>
<li><a href="index.xhtml">Home</a></li>
<li><a href="company/about_us.xhtml">About us</a></li>
...
</ul>
Mon problème est donc, quand la page en cours est index.xhtml
le composant génère correctement les URL, mais lorsque la page en cours est about_us.xhtml
, il génère des URL incorrectes. Je ne peux pas utiliser de chemin relatif car il va générer une mauvaise URL aussi. Je pense que c'est parce que le composant est basé sur le chemin actuel du *.xhtml
page.
La seule solution que j'ai pu trouver est la suivante:
<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>
Mais je pense que ce n'est pas "élégant" du tout. Des idées?
Les URL ne sont pas résolues en fonction de la structure de fichier côté serveur. Les URL sont résolues en fonction des adresses Web publiques réelles des ressources en question. C'est le navigateur Web qui doit les invoquer, pas le serveur Web.
Il y a plusieurs façons d'atténuer la douleur:
JSF EL propose un raccourci pour ${pageContext.request}
Avec une saveur de #{request}
:
<li><a href="#{request.contextPath}/index.xhtml">Home</a></li>
<li><a href="#{request.contextPath}/about_us.xhtml">About us</a></li>
Vous pouvez éventuellement utiliser <c:set>
balise pour la rendre encore plus courte. Mettez-le quelque part dans le modèle principal, il sera disponible pour toutes les 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 offre le <h:link>
Qui peut prendre un ID de vue relatif à la racine de contexte dans outcome
et ajoute le chemin de contexte et le mappage FacesServlet
automatiquement:
<li><h:link value="Home" outcome="index" /></li>
<li><h:link value="About us" outcome="about_us" /></li>
HTML propose la balise <base>
qui rend toutes les URL relatives du document relatives à cette base. Vous pourriez vous en servir. Mettez-le dans le <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: cela nécessite EL 2.2, sinon vous feriez mieux d'utiliser JSTL fn:substring()
, voir aussi cette réponse )
Cela devrait aboutir dans le HTML généré quelque chose comme
<base href="http://example.com/webname/" />
Notez que la balise <base>
A une mise en garde: elle crée également des ancres de saut de la page telles que <a href="#top">
! Voir aussi Est-il recommandé d'utiliser la balise <base> html? Dans JSF, vous pouvez le résoudre comme <a href="#{request.requestURI}#top">top</a>
Ou <h:link value="top" fragment="top" />
.
<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}" />