Image via Wikipedia
If you need to dynamically change CSS based on page location, you probably have seen something like this: background-image: url('../../../../resources/images/background.gif');You can remove all of the ../../../../ from the CSS by using Expression Language (EL) selectively in your CSS for example the above example can be modified to use the
FacesContext
to determine the location of an image resource from any page. See the example below. background-image: url('#{facesContext.externalContext.requestContextPath}/resources/images/background.gif');This will always have the correct path to the resources no matter how nested the pages are in your application. This same technique can be used to manipulate other CSS entries dynamically. This technique works on JSF 1.2 and JSF 2.0.
UPDATE:
As a friend pointed out in the comments it can be shortened further. I want to make a point that this technique gives you access to the
FacesContext
object which gives you a lot more flexibility.
Great post. This question still gets asked a lot. You can, however, make it shorter by used #{request.contextPath}.
ReplyDeleteThanks for posting the shorter version. This is a better solution for the more general case.
ReplyDeleteI was trying to point out that you have access to the whole FacesContext which I did not really make clear in my post.
if the following css is in an external CSS file, let's say /resources/css/myapp.css, it cannot do that. JSF framework should solve this. Furthermore, sometimes we also need to know the context path from Javascript. This also not work in external javascript files. I think JSF framework should provide us some method to retrieve the context path from the resources. In the JSP, we can just rename the .css or .js into .jsp. The application server will treat them as a JSP page.
ReplyDeletebackground-image: url('#{facesContext.externalContext.requestContextPath}/resources/images/background.gif');
Eric that is not true. You can use the same trick on an external css file. However, you must use a JSF tag to load it.
ReplyDelete<h:outputStylesheet library="css" name="style.css"/>
style.css has the following:
body {
background-image: url('#{facesContext.externalContext.requestContextPath}/resources/images/background.gif');
}
It loads completely fine as I would expect with the correct background image.