jsf - 如何在 Facelets 模板中引用 CSS/JS/图片资源?

标签 jsf resources jsf-2 facelets templating

我已经完成了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 stylingHow 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 版本中,这是不可能的。

也可以看看:
  • Java EE 6 tutorial - Facelets - Resources (距离您的链接仅两章)
  • What is the JSF resource library for and how should it be used?
  • How do I override default PrimeFaces CSS with custom styles?
  • 关于jsf - 如何在 Facelets 模板中引用 CSS/JS/图片资源?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35306603/

    相关文章:

    jsf - 如何将内容呈现为纯文本和 URL 编码

    java - JSF 页面中删除按钮中的错误

    c# - Silverlight 动态资源文件位置

    android - 为什么不在 Android 开发中只使用最高分辨率的图像?

    java - 创建一个 C++ 静态库以在 Android 上与 Java 一起使用

    java - Webfilter 只能在第二个响应中登录用户(记住我)

    jquery - 无法让 jQuery 与 Icefaces + Liferay 一起使用

    javascript - 通过ajax重新加载JavaScript函数/重新读取jsf-bean值

    javascript - JSF 动态 javascript 转义引号

    java - 样式表不适用于第一个 JSF 页面