现在我试图创建一个与模板不在同一目录中的页面。我有页面样式的问题,因为样式引用相对路径如此:
<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>
,其名称引用相对于webapp的/ resources文件夹的路径。这样,您不需要担心上下文路径,就像在JSF 1.x中一样。参见How to include CSS relative to context path in JSF 1.x?
文件夹结构
删除公共web内容的/ resources文件夹中的CSS / JS /图像文件如下(只是创建一个,如果不存在与/ WEB-INF和/ 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 :
在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文件夹的完整路径。它不需要以/开头。你不需要库属性,只要你不是开发一个组件库像PrimeFaces或一个通用的模块JAR文件,由多个webapps共享。
您可以参考< 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 =
<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背景图片或favicon。只需要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']}");
这是favicon例子。参见Add favicon to JSF project and reference it in <link>。
<link rel="shortcut icon" href="#{resource['images/favicon.ico']}" />
引用第三方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文件夹移动到/ WEB-INF中来隐藏资源,那么您可以从JSF 2.2中可选地通过新的web.xml上下文参数更改web内容相对路径,如下所示:
<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(距离您的链接只有2个章节)
> What is the JSF resource library for and how should it be used?
> How do I override default PrimeFaces CSS with custom styles?