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

j'ai fait tutoriel sur Facelets templating .

Maintenant, j'ai essayé de créer une page qui n'est pas dans le même répertoire que le modèle. J'ai des problèmes avec le style de la page, à cause des styles sont référencés avec le chemin relatif comme cela:

<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 ça m'apportera des ennuis quand je partirai application à un contexte différent.

alors je me demande Quelle est la meilleure façon de faire référence aux ressources CSS (et JS et image) dans les Facelets?

45
demandé sur BalusC 2011-12-03 15:47:07

3 réponses

Introduction

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

structure du dossier

supprimez les fichiers CSS/JS/image dans le dossier /resources du contenu Web public comme ci-dessous (il suffit d'en créer 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 et non /main/resources (ceux sont pour les ressources Java (propriétés / xml/text / config files) qui doivent se retrouver dans runtime classpath, pas dans webcontent). Voir aussi maven et JSF webapp structure, où exactement mettre les ressources JSF .

Référencement dans Facelets

en fin de compte, ces ressources sont disponibles comme ci-dessous partout sans avoir besoin de jouer avec 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 complet par rapport au dossier /resources . Il n'a pas besoin de commencer avec / . Vous faites pas besoin de l'attribut library tant que vous ne développez pas une bibliothèque de composants comme PrimeFaces ou un fichier JAR de module commun qui est partagé par plusieurs webapps.

vous pouvez référencer le <h:outputStylesheet> n'importe où, aussi dans <ui:define> des clients de modèle sans avoir besoin d'un <h:head> supplémentaire . Il se terminera automatiquement par le composant <h:head> de master template généré <head> .

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

vous pouvez faire référence à <h:outputScript> aussi n'importe où, mais il finira par défaut dans le HTML exactement là où vous l'avez déclaré. Si vous voulez qu'il se termine dans <head> via <h:head> , puis Ajouter target="head" attribut.

<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 </body> , de sorte que par exemple window.onload et $(document).ready() etc n'est pas nécessaire) via <h:body> , alors ajouter l'attribut target="body" .

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

PrimeFaces HeadRenderer

dans le cas où vous utilisez PrimeFaces, son HeadRenderer brouillera l'ordre de script par défaut <h:head> comme décrit ci-dessus. Vous êtes essentiellement forcé de forcer l'ordre via PrimeFaces-spécifique <f:facet name="first|middle|last"> , qui peut se retrouver dans le désordre et "intemplateable" code. Vous pouvez l'éteindre comme décrit dans cette réponse .

emballage en pot

vous pouvez même empaqueter les ressources dans un fichier JAR. Voir Aussi Structure pour plusieurs projets JSF avec le code partagé .

Référencement dans les EL

vous pouvez dans EL utiliser le #{resource} cartographie pour laisser JSF essentiellement imprimer une URL de ressource comme /context/javax.faces.resource/folder/file.ext.xhtml?ln=library afin que vous puissiez l'utiliser comme par exemple CSS image de fond ou favicon. La seule exigence est que le fichier CSS lui-même devrait également servir de ressource JSF, sinon EL expressions ne sera pas évalué. Voir aussi Comment faire référence à la ressource d'image JSF en tant que CSS background image 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 favicon au projet JSF et le renvoyer dans < link> .

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

faisant référence à un tiers Fichiers CSS

fichiers CSS tiers chargés via <h:outputStylesheet> qui, à leur tour, les polices de référence et/ou les images peuvent avoir besoin d'être modifiés pour utiliser les expressions #{resource} comme décrit dans la section précédente, sinon un UnmappedResourceHandler doit être installé afin de pouvoir servir ceux qui utilisent JSF. Voir aussi a. O. la page Bootfaces apparaît dans le navigateur sans aucun style et comment utiliser la police impressionnante 4.X Fichier CSS avec JSF? Le navigateur ne peut pas trouver les fichiers de police .

se cacher dans / WEB-INF

si vous avez l'intention de cacher les ressources de l'accès public en déplaçant l'ensemble du dossier /resources dans /WEB-INF , alors vous pouvez depuis JSF 2.2 modifier le webcontent-chemin relatif 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 versions JSF plus anciennes, ce n'est pas possible.

voir aussi:

91
répondu BalusC 2017-05-23 12:26:17

Supposons que vous exécutez dans les sous répertoires de l'application web. Vous pouvez essayer comme ceci :

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

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

dans les URL relatives, la barre oblique / pointant vers la racine du domaine. Ainsi, si la page JSF est par exemple demandée par http://example.com/context/page.jsf , L'URL CSS pointera absolument vers 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'un de l'autre.

supposons que votre fichier CSS est effectivement situé à http://example.com/context/styles/decoration.css , puis vous devez supprimer la barre oblique principale afin qu'elle soit relative au contexte actuel (celui de la page.jsp):

<link rel="stylesheet" type="text/css" href="styles/decoration.css" />
7
répondu Abimaran Kugathasan 2017-07-12 08:21:33

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

j'ai dû changer (veuillez noter que le "\" devant le #. Probablement un effet secondaire de la gorgée:

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

 background: $blue url("\#{resource['my_theme/images/background-homepage-h1.png']}");
2
répondu Mircea Stanciu 2017-06-25 03:46:19