我已经完成了tutorial about Facelets templating .
现在我尝试创建一个与模板不在同一目录中的页面。我的页面样式有问题,因为样式是用相对路径引用的,如下所示:
<link rel="stylesheet" href="style_resource_path.css" />
我可以从
/
开始使用绝对引用:<link rel="stylesheet" href="/project_root_path/style_resource_path.css" />
但是当我将应用程序移动到不同的上下文时,这会给我带来麻烦。
所以我想知道在 Facelets 中引用 CSS(以及 JS 和图像)资源的最佳方式是什么?
最佳答案
介绍
正确的 JSF 2.x 方式是使用 <h:outputStylesheet>
, <h:outputScript>
和 <h:graphicImage>
与 name
引用相对于 webapp 的 /resources
的路径文件夹。这样您就不必像在 JSF 1.x 中那样担心上下文路径。另见 How to include CSS relative to context path in JSF 1.x?
文件夹结构
将 CSS/JS/图像文件放到 /resources
中公共(public)网络内容的文件夹如下(如果与 /WEB-INF
和 /META-INF
处于同一级别,则只需创建一个)。
WebContent
|-- resources
| |-- css
| | |-- other.css
| | `-- style.css
| |-- js
| | `-- script.js
| `-- images
| |-- background.png
| |-- favicon.ico
| `-- logo.png
|-- META-INF
| `-- MANIFEST.MF
|-- WEB-INF
| |-- faces-config.xml
| `-- web.xml
|-- page.xhtml
:
如果是 Maven,它应该在
/main/webapp/resources
因此不是/main/resources
(这些用于 Java 资源(properties/xml/text/config 文件),它们必须以运行时类路径结束,而不是在 webcontent 中)。另见 Maven and JSF webapp structure, where exactly to put JSF resources .Facelets 中的引用
最终,这些资源在任何地方都可以使用,而无需摆弄相对路径:
<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>
name
属性必须表示相对于 /resources
的完整路径文件夹。不需要以/
开头.你做 不是 需要library
只要您不开发像 PrimeFaces 这样的组件库或由多个 Web 应用程序共享的通用模块 JAR 文件,属性。您可以引用
<h:outputStylesheet>
任何地方,也在<ui:define>
模板客户端,无需额外的 <h:head>
.它将通过 <h:head>
主模板组件自动生成<head>
.<ui:define name="...">
<h:outputStylesheet name="css/style.css" />
...
</ui:define>
您可以引用
<h:outputScript>
也可以在任何地方,但默认情况下,它会在您声明它的地方出现在 HTML 中。如果您希望它以 <head>
结尾通过 <h:head>
,然后添加 target="head"
属性。<ui:define name="...">
<h:outputScript name="js/script.js" target="head" />
...
</ui:define>
或者,如果您希望它在
<body>
的末尾结束(就在 </body>
之前,因此不需要 window.onload
和 $(document).ready()
等)通过 <h:body>
,然后添加 target="body"
属性。<ui:define name="...">
<h:outputScript name="js/script.js" target="body" />
...
</ui:define>
PrimeFaces
HeadRenderer
如果您使用 PrimeFaces,它的
HeadRenderer
会破坏默认的 <h:head>
如上所述的脚本排序。您基本上是被迫通过特定于 PrimeFaces 的 <f:facet name="first|middle|last">
强制订购。 ,这可能会导致困惑和“不可模板化”的代码。您可能希望按照 this answer 中的说明关闭它。 .JAR 包装
您甚至可以将资源打包到 JAR 文件中。另见 Structure for multiple JSF projects with shared code .
在 EL 中引用
您可以在 EL 中使用
#{resource}
映射让 JSF 基本上打印一个资源 URL,如 /context/javax.faces.resource/folder/file.ext.xhtml?ln=library
这样您就可以将其用作例如CSS 背景图像或网站图标。唯一的要求是 CSS 文件本身也应该作为 JSF 资源,否则 EL 表达式不会计算。另见 How to reference JSF image resource as CSS background image url ..some {
background-image: url("#{resource['images/background.png']}");
}
这是
@import
例子。@import url("#{resource['css/other.css']}");
这是网站图标示例。另见 Add favicon to JSF project and reference it in <link> .
<link rel="shortcut icon" href="#{resource['images/favicon.ico']}" />
如果您使用的是 SCSS 编译器(例如 Sass Compiler Plugin for Maven ),请记住 SCSS 处理器可能会解释
#
作为一个特殊字符。在这种情况下,您需要使用 \
对其进行转义。 ..some {
background-image: url("\#{resource['images/background.png']}");
}
引用第三方 CSS 文件
通过
<h:outputStylesheet>
加载的第三方 CSS 文件反过来,可能需要更改引用字体和/或图像才能使用 #{resource}
如前一节所述的表达式,否则为 UnmappedResourceHandler
需要安装以便能够为使用 JSF 的用户提供服务。另见 a.o. Bootsfaces page shows up in browser without any styling和 How to use Font Awesome 4.x CSS file with JSF? Browser can't find font files .隐藏在/WEB-INF
如果您打算通过移动整个
/resources
来隐藏公共(public)访问的资源文件夹到 /WEB-INF
,那么您可以从 JSF 2.2 开始选择性地通过新的 web.xml
更改 webcontent-relative 路径上下文参数如下:<context-param>
<param-name>javax.faces.WEBAPP_RESOURCES_DIRECTORY</param-name>
<param-value>/WEB-INF/resources</param-value>
</context-param>
在较旧的 JSF 版本中,这是不可能的。
也可以看看:
关于jsf - 如何在 Facelets 模板中引用 CSS/JS/图片资源?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35306603/