web-dev-qa-db-fra.com

Comment référencer une ressource CSS/JS/image dans le modèle Facelets?

J'ai fait tutoriel sur la modélisation de Facelets

Maintenant, j'ai essayé de créer une page qui ne se trouve pas dans le même répertoire que le modèle. J'ai des problèmes avec le style de page, car les styles sont référencés avec un chemin relatif comme ceci:

<link rel="stylesheet" href="style_resource_path.css" />

Je peux utiliser le référencement absolu en commençant par /:

<link rel="stylesheet" href="/project_root_path/style_resource_path.css" />

Mais cela me posera des problèmes lorsque je déplacerai l'application dans un contexte différent.

Je me demande donc quel est le meilleur moyen de référencer les ressources CSS (et JS et image) dans Facelets?

50
kravemir

Introduction

La méthode JSF 2.x appropriée utilise <h:outputStylesheet> , <h:outputScript> et <h:graphicImage> avec un name faisant référence au chemin relatif au dossier /resources de la Webapp. De cette façon, vous n'avez pas à vous soucier du chemin de contexte comme vous le feriez dans JSF 1.x. Voir aussi Comment inclure CSS par rapport au chemin de contexte dans JSF 1.x?

Structure de dossier

Déposez les fichiers CSS/JS/image dans le dossier /resources du contenu Web public, comme indiqué ci-dessous (créez-en un s'il n'existe pas déjà au même niveau que /WEB-INF et /META-INF).

WebContent
 |-- META-INF
 |-- WEB-INF
 |-- resources
 |    |-- css
 |    |    |-- other.css
 |    |    `-- style.css
 |    |-- js
 |    |    `-- script.js
 |    `-- images
 |         |-- background.png
 |         |-- favicon.ico
 |         `-- logo.png
 |-- page.xhtml
 :

Dans le cas de Maven, il devrait être dans /main/webapp/resources et donc not/main/resources (il s’agit de ressources Java (fichiers properties/xml/text/config) qui doivent se retrouver dans le chemin de classe d’exécution, pas dans le contenu Web). Voir aussi Maven et la structure d'application Web JSF, où placer exactement les ressources JSF .

Référencement dans Facelets

En fin de compte, ces ressources sont disponibles partout comme ci-dessous sans qu'il soit nécessaire de manipuler des chemins relatifs:

<h:head>
    ...
    <h:outputStylesheet name="css/style.css" />
    <h:outputScript name="js/script.js" />
</h:head>
<h:body>
    ...
    <h:graphicImage name="images/logo.png" />
    ...
</h:body>

L'attribut name doit représenter le chemin d'accès complet par rapport au dossier /resources. Il n'est pas nécessaire de commencer par /. Not n'a pas besoin de l'attribut library tant que vous ne développez pas de bibliothèque de composants telle que PrimeFaces ou un fichier JAR de module commun partagé par plusieurs applications Web.

Vous pouvez référencer le <h:outputStylesheet> n'importe où, également dans <ui:define> des clients modèles sans avoir besoin d'un <h:head> supplémentaire. Par le biais du composant <h:head> du modèle principal, il se retrouvera automatiquement dans le <head> généré. 

<ui:define name="...">
    <h:outputStylesheet name="css/style.css" />
    ...
</ui:define>

Vous pouvez référencer <h:outputScript> également n'importe où, mais il se retrouvera par défaut dans le code HTML exactement là où vous l'avez déclaré. Si vous voulez qu'il se retrouve dans <head> via <h:head>, ajoutez ensuite l'attribut target="head"

<ui:define name="...">
    <h:outputScript name="js/script.js" target="head" />
    ...
</ui:define>

Ou, si vous voulez qu'il se termine à la fin de <body> (juste avant le </body>, de sorte que, par exemple, window.onload et $(document).ready(), etc. ne soit pas nécessaire) via <h:body>, ajoutez ensuite l'attribut target="body".

<ui:define name="...">
    <h:outputScript name="js/script.js" target="body" />
    ...
</ui:define>

PrimeFaces HeadRenderer

Si vous utilisez PrimeFaces, sa HeadRenderer modifiera l'ordre de script par défaut <h:head> comme décrit ci-dessus. Vous êtes essentiellement obligé de forcer la commande via le <f:facet name="first|middle|last"> spécifique à PrimeFaces, qui peut se retrouver dans un code compliqué et "sans modèle". Vous voudrez peut-être l'éteindre comme décrit dans cette réponse .

Emballage dans JAR

Vous pouvez même regrouper les ressources dans un fichier JAR. Voir aussi Structure pour plusieurs projets JSF avec code partagé .

Référencement en EL

En EL, vous pouvez utiliser le mappage #{resource} pour permettre à JSF d’imprimer une URL de ressource telle que /context/javax.faces.resource/folder/file.ext.xhtml?ln=library, de sorte que vous puissiez l’utiliser comme exemple. Image de fond ou favicon CSS. La seule exigence est que le fichier CSS lui-même soit également servi en tant que ressource JSF, sinon les expressions EL ne seront pas évaluées. Voir aussi Comment référencer une ressource image JSF en tant qu'image d'arrière-plan CSS url .

.some {
    background-image: url("#{resource['images/background.png']}");
}

Voici l'exemple @import.

@import url("#{resource['css/other.css']}");

Voici l'exemple de favicon. Voir aussi Ajouter un favicon au projet JSF et le référencer dans <link> .

<link rel="shortcut icon" href="#{resource['images/favicon.ico']}" />

Référencement de fichiers CSS tiers

Les fichiers CSS tiers chargés via <h:outputStylesheet>, qui à leur tour référencent des polices et/ou des images, doivent éventuellement être modifiés pour utiliser les expressions #{resource} comme décrit dans la section précédente. Sinon, une UnmappedResourceHandler doit être installée pour pouvoir servir ceux qui utilisent JSF. Voir aussi a.o. La page Bootsfaces apparaît dans le navigateur sans style et Comment utiliser le fichier CSS Font Awesome 4.x avec JSF? Le navigateur ne trouve pas les fichiers de polices .

Se cacher dans/WEB-INF

Si vous souhaitez masquer les ressources de l'accès public en déplaçant l'intégralité du dossier /resources dans /WEB-INF, vous pouvez, depuis JSF 2.2, modifier le chemin relatif relatif au contenu Web via un nouveau paramètre de contexte web.xml, comme suit:

<context-param>
    <param-name>javax.faces.WEBAPP_RESOURCES_DIRECTORY</param-name>
    <param-value>/WEB-INF/resources</param-value>
</context-param>

Dans les anciennes versions de JSF, cela n’est pas possible.

Voir également:

102
BalusC

Supposons que vous exécutiez le dans les sous-répertoires de l'application Web. Vous pouvez essayer comme ça:

 <link href="${facesContext.externalContext.requestContextPath}/css/style.css" rel="stylesheet" type="text/css"/>

Le lien '${facesContext.externalContext.requestContextPath}/' vous aidera à revenir immédiatement à la racine du contexte.

Dans les URL relatives, la barre oblique/pointe vers la racine du domaine. Donc, si la page JSF est par exemple demandée par http://example.com/context/page.jsf , l'URL CSS pointe absolument sur http://example.com/styles/decoration.css . Pour connaître l'URL relative valide, vous devez connaître l'URL absolue de la page JSF et du fichier CSS, et extraire l'une de l'autre.

Laissez deviner que votre fichier CSS est en fait situé à l’emplacement http://example.com/context/styles/decoration.css , vous devez ensuite supprimer la barre oblique principale de sorte qu’elle soit relative au contexte actuel de la page.jsp):

<link rel="stylesheet" type="text/css" href="styles/decoration.css" />
7

Ces réponses m'ont aidé à résoudre le même problème. Bien que mon problème était plus complexe depuis que j'utilisais SASS et GULP.

Je devais changer (notez le "\" devant le #. Probablement un effet secondaire de gulp:

 <h:outputStylesheet library="my_theme" name="css/default.css"/>  

 background: $blue url("\#{resource['my_theme/images/background-homepage-h1.png']}");
2
Mircea Stanciu

Resourcehandlers.UnmappedResourceHandler aide à mapper les ressources JSF sur un modèle d'URL de /javax.faces.resource/*.

Pour moi, ces 2 configurations xml dans faces-config.xml: org.omnifaces.resourcehandler.UnmappedResourceHandler

et dans web.xml:

<servlet-mapping>
<servlet-name>facesServlet</servlet-name>
<url-pattern>/javax.faces.resource/*</url-pattern>
<url-pattern>*.xhtml</url-pattern>
</servlet-mapping>

aidé avec css et images. 

0
Behruz Zaripov