jsf - tag - ¿Cómo hacer referencia al recurso CSS/JS/image en la plantilla Facelets?
style jsf (3)
He hecho un tutorial sobre la creación de plantillas Facelets .
Ahora he tratado de crear una página que no está en el mismo directorio que la plantilla. Tengo problemas con el estilo de página porque los estilos se referencian con una ruta relativa como esta:
<link rel="stylesheet" href="style_resource_path.css" />
Puedo usar referencias absolutas comenzando con /
:
<link rel="stylesheet" href="/project_root_path/style_resource_path.css" />
Pero esto me traerá problemas cuando traslade la aplicación a un contexto diferente.
Entonces, me pregunto cuál es la mejor manera de referenciar los recursos CSS (y JS e imágenes) en Facelets.
Introducción
La forma correcta de JSF 2.x es usar <h:outputStylesheet>
, <h:outputScript>
y <h:graphicImage>
con un name
referencia a la ruta relativa a la carpeta webapp /resources
. De esta manera, no necesita preocuparse por la ruta de contexto como lo haría en JSF 1.x. Consulte también ¿Cómo incluir CSS en relación con la ruta de contexto en JSF 1.x?
Estructura de la carpeta
Coloque los archivos CSS / JS / de imagen en /resources
carpeta /resources
del contenido web público como se muestra a continuación (solo cree uno si aún no existe en el mismo nivel que /WEB-INF
y /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
:
En el caso de Maven, debería estar en /main/webapp/resources
y por lo tanto no /main/resources
(esos son recursos de Java (properties / xml / text / config files) que deben terminar en classpath en tiempo de ejecución, no en contenido web) . Ver también la estructura de aplicaciones web de Maven y JSF, donde exactamente poner los recursos JSF .
Hacer referencia en Facelets
En última instancia, esos recursos están disponibles a continuación en todas partes sin la necesidad de jugar con rutas relativas:
<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>
El atributo de name
debe representar la ruta completa relativa a la carpeta /resources
. No necesita comenzar con /
. No necesita el atributo de library
siempre que no esté desarrollando una biblioteca de componentes como PrimeFaces o un archivo JAR de módulo común compartido por varias aplicaciones web.
Puede hacer referencia a <h:outputStylesheet>
cualquier lugar, también en <ui:define>
de clientes de plantilla sin la necesidad de una <h:head>
adicional. A través del componente <h:head>
de la plantilla maestra, automáticamente terminará en <head>
generado.
<ui:define name="...">
<h:outputStylesheet name="css/style.css" />
...
</ui:define>
También puede hacer referencia a <h:outputScript>
cualquier lugar, pero de forma predeterminada terminará en el HTML exactamente allí donde lo declaró. Si desea que termine en <head>
través de <h:head>
, agregue target="head"
atributo target="head"
.
<ui:define name="...">
<h:outputScript name="js/script.js" target="head" />
...
</ui:define>
O bien, si desea que termine al final de <body>
(justo antes de </body>
, de modo que, por ejemplo, window.onload
y $(document).ready()
etc. no sean necesarios) a través de <h:body>
, luego agrega target="body"
atributo target="body"
.
<ui:define name="...">
<h:outputScript name="js/script.js" target="body" />
...
</ui:define>
PrimeFaces HeadRenderer
En caso de que esté utilizando PrimeFaces, su HeadRenderer
confundirá el orden predeterminado del script <h:head>
como se describe arriba. Básicamente, se ve obligado a forzar el pedido a través de <f:facet name="first|middle|last">
específico de PrimeFaces, que puede terminar en un código desordenado e "imposible de calificar". Es posible que desee desactivarlo como se describe en esta respuesta .
Embalaje en JAR
Incluso puede empaquetar los recursos en un archivo JAR. Consulte también Estructura para múltiples proyectos JSF con código compartido .
Hacer referencia en EL
En EL, puede usar la asignación #{resource}
para permitir que JSF imprima básicamente una URL de recurso como /context/javax.faces.resource/folder/file.ext.xhtml?ln=library
para que pueda usarla como, por ejemplo, fondo CSS imagen o favicon. El único requisito es que el archivo CSS también se sirva como un recurso JSF; de lo contrario, las expresiones EL no se evaluarán. Consulte también Cómo hacer referencia al recurso de imagen JSF como url de imagen de fondo de CSS .
.some {
background-image: url("#{resource[''images/background.png'']}");
}
Aquí está el ejemplo @import
.
@import url("#{resource[''css/other.css'']}");
Aquí está el ejemplo de favicon. Ver también Agregar favicon al proyecto JSF y referenciarlo en <link> .
<link rel="shortcut icon" href="#{resource[''images/favicon.ico'']}" />
Hacer referencia a archivos CSS de terceros
Los archivos CSS de terceros cargados a través de <h:outputStylesheet>
que a su vez hacen referencia a fuentes y / o imágenes pueden necesitar ser alterados para usar expresiones #{resource}
como se describe en la sección anterior; de lo contrario, debe instalarse UnmappedResourceHandler
para poder para servir a quienes usan JSF. Consulte también la página Bootsfaces aparece en el navegador sin ningún estilo y ¿Cómo se utiliza el archivo CSS Font Awesome 4.x con JSF? El navegador no puede encontrar archivos de fuentes .
Ocultar en / WEB-INF
Si tiene la intención de ocultar los recursos del acceso público moviendo la carpeta completa /resources
a /WEB-INF
, entonces desde JSF 2.2 puede cambiar opcionalmente la ruta relativa al contenido /WEB-INF
través de un nuevo parámetro de contexto web.xml
siguiente manera:
<context-param>
<param-name>javax.faces.WEBAPP_RESOURCES_DIRECTORY</param-name>
<param-value>/WEB-INF/resources</param-value>
</context-param>
En versiones anteriores de JSF esto no es posible.
Ver también:
Estas respuestas me ayudaron a solucionar el mismo problema. Aunque mi problema era más complejo ya que estaba usando SASS y GULP.
Tuve que cambiar (tenga en cuenta la "/" delante del #. Probablemente el efecto secundario de gulp:
<h:outputStylesheet library="my_theme" name="css/default.css"/>
background: $blue url("/#{resource[''my_theme/images/background-homepage-h1.png'']}");
Supongamos que está ejecutando el en los subdirectorios de la aplicación web. Puede intentarlo así:
<link href="${facesContext.externalContext.requestContextPath}/css/style.css" rel="stylesheet" type="text/css"/>
El enlace ''${facesContext.externalContext.requestContextPath}/''
te ayudará a regresar inmediatamente a la raíz del contexto.
En URL relativas, la barra diagonal / apunta a la raíz del dominio. Por lo tanto, si la página JSF se solicita, por ejemplo, en http://example.com/context/page.jsf , la URL CSS apuntará definitivamente a http://example.com/styles/decoration.css . Para conocer la URL relativa válida, necesita conocer la URL absoluta tanto de la página JSF como del archivo CSS y extraer la una de la otra.
Supongamos que su archivo CSS se encuentra realmente en http://example.com/context/styles/decoration.css , luego debe eliminar la barra diagonal para que sea relativa al contexto actual (el de la página. jsp):
<link rel="stylesheet" type="text/css" href="styles/decoration.css" />