5

In my JSF 2.0 Facelets application I have one glorious template that I want all the pages to use. It is in the root directory of the web-app disguised with the name template.xhtml. So it is referenced as you would expect:

<ui:composition template="./template.xhtml">

However I do navigate now and then to client files in sub-directories. It is useful to organize them this way because of different privilege levels. The facelets in those subdirectories would have a reference to the same template like this:

<ui:composition template="../template.xhtml">

So far so good. However in the header of the template I pull in the css like this:

<link href="./resources/css/default.css" rel="stylesheet" type="text/css" />
<link href="./resources/css/tableLayout.css" rel="stylesheet" type="text/css" />
<link href="../resources/css/default.css" rel="stylesheet" type="text/css" />
<link href="../resources/css/tableLayout.css" rel="stylesheet" type="text/css" />

The reason for the redundant references is that I haven't found any other way to get the template to work from the context of the root directory or the sub-directory. A pathname that starts with a / doesn't work unless you put the application name in it like this

/TheApp-Ver1_0/resources/css/default.css

The problem with this is that the absolute pathname starts with a variable, not a constant. The variable is dependent on how the app is deployed in the container. Is there any clean way of resolving this?

I did some searches to find this question. Honest. However I suspect this is another one of those where BalusC swoops in an provides a link to the blindingly obvious solution extensively discussed somewhere I missed.

AlanObject
  • 8,408
  • 18
  • 72
  • 122

1 Answers1

14

The template path in <ui:composition> is relative to the webapp's own folder structure, not to the domain root (because it does not represent an URL!). So if you start it with /, it's just resolved relative to the context root.

<ui:composition template="/WEB-INF/inc/template.xhtml">

(putting in /WEB-INF has the advantage that the enduser cannot open it directly by guessing the URL)

The name path of <h:outputStylesheet>, <h:outputScript> and <h:graphicImage> is always relative to /resources root folder, regardless of if you start it with / or not.

<h:outputStylesheet name="css/default.css" />
<h:outputScript name="js/default.js" />
<h:graphicImage name="img/logo.png" />

If you want to use plain HTML instead of JSF components to include CSS/JS/images for some reason, then best is to prepend the path with #{request.contextPath} yourself, so that you can make it a domain-relative URL, so that you don't need to fiddle with context-relative URLs. See also: How get the base URL?

Community
  • 1
  • 1
BalusC
  • 992,635
  • 352
  • 3,478
  • 3,452
  • You did it again. I notice that these tags have not yet been included in some of the online references mentioned here: http://stackoverflow.com/questions/539041/whats-the-best-online-reference-for-jsf-tags – AlanObject Sep 11 '11 at 16:51
  • 1
    A lot has been changed in JSF 2.x (introduced in 2nd half of 2009). The link you mentioned is from Feb 2009 and refers JSF 1.x documentation only. For all JSF 2.x tags, check the JSF 2.x documentation: http://download.oracle.com/javaee/6/javaserverfaces/2.1/docs/vdldocs/facelets/ When you use JSF 2.x, ensure that you're reading JSF 2.x targeted tutorials/books/documentation/answers. – BalusC Sep 11 '11 at 16:55
  • So there is no any chance to refer to css or js file that is not in resource folder? Neither it possible to reach js/css resource from browser like this myhost/resources/partials/my.css ? – ses Jan 27 '14 at 17:37