我可以为JSF使用EL来引用外部CSS文件吗?

6
在我当前的JSF项目的外部样式表中,存在硬编码的指向外部资源的链接,例如:
.someId { background-image:url(/context/resources/images/example.jpg); }

在JSF xhtml文档中,我可以使用像${request.contextPath}这样的EL表达式,但如何将EL处理应用于CSS文件?
(相关:如何在JSF中嵌入CSS背景图片链接?
硬编码上下文路径的缺点是:Web应用程序的上下文路径 - 在示例中为/context - 可以通过修改web.xml(或者如果在web.xml中未指定上下文,则通过重命名Web应用程序存档文件)在部署时更改,但CSS文件中资源的链接仍将指向未更改的硬编码上下文,并导致资源未找到错误。
6个回答

12

也许我误解了你的问题,但是如果你所说的外部CSS只是指你自己的不是内联样式的CSS,那么使用JSF 2.0,你可以在CSS中使用EL表达式,只要你在<h:outputStylesheet>中包含它。例如,我有一个这样的项目结构:

war
|__ WEB-INF
|   |__ *standardStuff*
|__ resources
|   |__ css
|   |   |__ style.css
|   |__ images
|       |__ image1.png
|__ xhtml
|   |__ index.xhtml

这显然不是完整的文件列表,但应该足以理解。然后我在我的index.xhtml中有这个:

<f:view xmlns:f="http://java.sun.com/jsf/core" 
    xmlns:h="http://java.sun.com/jsf/html" 
    xmlns:ui="http://java.sun.com/jsf/facelets">
  <h:head/>
  <h:body>
    <h:outputStylesheet library="css" name="style.css" target="head"/>
    <ui:include src="content.xhtml"/>
  </h:body>
</f:view>

在我的CSS文件中有如下代码:

.someClass {
    background-image: url('#{resource['images/image1.png']}');
}

10

我通常将CSS图像放置在CSS文件夹的子文件夹中,例如:

  • /resources/css/style.css
  • /resources/css/images/example.jpg

这样做可以获得以下效果:

.someId { background-image:url(images/example.jpg); }

是的,它们是相对于 CSS 文件本身的 URL 解析,而不是相对于主 JSF/HTML 页面解析。


BalusC,我知道这个评论没有提供任何有用的反馈,但我必须说。你是一个天才。 - arg20
@arg20:谢谢 :) 顺便提一下相关答案:https://dev59.com/QGw15IYBdhLWcg3wFH3f#6835701 - BalusC

7
你可以使用表达式语言(EL)和FacesContext一起解决这个问题。我经常使用这种技术。
background-image: url('#{facesContext.externalContext.requestContextPath}/resources/images/background.gif');

这使您可以利用JSF根据应用程序输入或更改提供动态内容。

此技术适用于JSF 1.2和JSF 2.0。


4

@Bozho的回答基本上涵盖了您的选项。

另一个可能性是继续使用静态样式表,在文档头中填写动态部分,您可以在那里访问您的表达式:

<head>

<!-- The style sheet contains 99% of the CSS ->
<link rel="stylesheet" href="static.css" type="text/css">

<!-- The remaining 1% is done here -->
<style type="text/css">
 .someClass { --- your dynamic values  here --- }
</style>

</head>

在PHP的世界中,这是最佳实践,因为它可以避免为样式表调用创建昂贵的PHP进程。我不知道在JSP的世界中情况如何,但我认为它是类似的。

3
不行,你有几个选择:
  • 硬编码绝对路径(当然是域名相关的)- 不太好
  • 使用相对路径 - 当你有嵌套的URL时可能会有问题,例如/view/external/foo/bar.jsf
  • 在构建过程中预处理它们以设置正确的路径
  • 使用Filter(同时客户端和服务器端缓存)来设置正确的路径。
(我感觉我漏掉了什么)

2
如何使用自定义资源处理程序? - tasel
请看我今天发布的答案。它被插入到顶部某个位置,这让我有点困惑 o_O - tasel

3
@Bozho: JSF允许定义一个ResourceHandler来替换标准的处理程序。您只需子类化javax.faces.application.ResourceHandler,处理特定请求并将其他请求委托给基类即可。
对于给定示例,自定义资源处理程序应确定上下文并替换绝对路径定义。这样可以实现每个请求动态路径解析。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接