3

i'm in trouble here. I have a JSF application that has a template file called baseTemplate.xhtml. This file is located in /resources/template folder. Follows the file code:

<?xml version='1.0' encoding='UTF-8' ?> 
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
  xmlns:ui="http://java.sun.com/jsf/facelets"
  xmlns:h="http://java.sun.com/jsf/html"
  xmlns:f="http://java.sun.com/jsf/core">
    <h:head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
        <h:outputStylesheet library="css" name="default.css"/>
        <h:outputStylesheet library="css" name="cssLayout.css"/>
        <h:outputStylesheet library="css" name="menu.css"/>
        <h:outputStylesheet library="css" name="rodape.css"/>
        <title>JSF Project</title>
    </h:head>
    <h:body>
        <div id="estrutura">
            <div class="top">
                <ui:insert name="top">
                    <ui:include src="somefile"/>
                </ui:insert>
            </div>
            <div id="menu">
                <ui:insert name="menu">
                    <ui:include src="somefile"/>
                </ui:insert>
            </div>
            <div>
                <div id="left">
                    <ui:insert name="left">
                    </ui:insert>
                </div>
                <div id="content" class="left_content">
                    <ui:insert name="content"></ui:insert>
                </div>
            </div>
            <div id="bottom">
                <ui:insert name="bottom">
                    <ui:include src="somefile"/>
                </ui:insert>
            </div>
        </div>    
      </h:body>
</html>

In my cssLayout.css file, located inside /resources/css folder, i have the following rule:

.top {
   position: relative;
   height: 120px;
   padding: 0;
   margin: 0 0 15px 0;
   background-image: url('imgSite/sisLogo.png');
   background-repeat: no-repeat;
}

The image sisLogo.png is located under /resources/css/imgSite. All pages from my app are inside /pages. When i use the template, he doesn't load the image background for top, but other css properties are loaded. Seems to be a background-image url path problem. How i could solve this?

The project folder structure is as follows:

/
 pages/
     home.xhtml (using the template)
 resources/
     css/
         cssLayout.css
         imgSite/
             sisLogo.png
     templates/
         baseTemplate.xhtml
mnatan.brito
  • 883
  • 5
  • 18
  • 32
  • Look at this answer http://stackoverflow.com/questions/6835499/changing-jsf-prefix-to-suffix-mapping-forces-me-to-reapply-the-mapping-on-css-ba/6835701#6835701 – Ravi Kadaboina Aug 29 '12 at 06:31

2 Answers2

8

CSS background images are loaded relative to the request URL of the CSS file (and thus not immediately relative to its physical location in the web content). If you explore the generated HTML output of the <h:outputStylesheet>, then you'll see that the request URL has become different. Assuming a context path of /somecontext and a FacesServlet mapping of *.xhtml, it'll look like this:

<link rel="stylesheet" type="text/css" href="/somecontext/javax.faces.resource/cssLayout.css.xhtml?ln=css" />

Note that your (improper btw) usage of the library has moved the /css to ?ln=css. You'd need to fix the background image url() accordingly so that it's properly relative to the real request URL of the CSS. E.g.

background-image: url("../resources/css/imgSite/sisLogo.png");

A more reliable way, which takes JSF resource identifier rules and FacesServlet mapping into account, is to use #{resource} in EL:

background-image: url("#{resource['css:imgSite/sisLogo.png']}");

See also:

Community
  • 1
  • 1
BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
  • How are those EL expressions like `#{resource['css:imgSite/sisLogo.png']}` in **external CSS files** parsed? Are CSS files themselves parsed along with XHTML files (from top to bottom)? Is this else done somewhat magically? I do by far, envision a different thing in case of **external JavaScript files** in which neither XML special characters are required to be escaped nor the code in those files needs to be enclosed in ugly `CDATA` tag(s) - because the code in external JavaScript files is simply included in the generated HTML - the files themselves are not parsed. Is it? – Tiny Dec 13 '14 at 09:53
  • 1
    @Tiny: it isn't supported on external CSS files. It's only supported on internal CSS files, served by the same webapp. It isn't supported in JS files in any way (although it'd have been nice as well). EL evaluating is done via a special input stream reader which recognizes `#{..}` and then evaluates them via the current faces context. Note that the presence of EL in a CSS file is checked only once per CSS file applicationwide. If no EL is found in CSS, then JSF will continue to read it the regular way. – BalusC Dec 13 '14 at 11:37
  • @BalusC is there any way to point to folder as a whole, not a single file? I am having trouble with MarkClusterer from Google Developers, one of its options points to a folder where images are, and I don't know how to do that I tried "#{resource['img:m']}" where **img** and **m** are folders – hocikto Aug 01 '17 at 11:19
0

Your case is simple. I copy it :

/
 pages/
     home.xhtml (using the template)
 resources/
     css/
         cssLayout.css
         imgSite/
             sisLogo.png
     templates/
         baseTemplate.xhtml

Small pertinent advice : when you do not know how to use relative path or when you have problem to implement it, simply use absolute path. Absolute paths have the powerful advantage in some cases to be mesured from the root. So they are more simple.

In your case, regardless of the structure, you can do this :

/Name of your project/PathToTheImage

Exemple :(Let's suppose your project is called "NewYork". It's just a name! You should do)

/NewYord/resources/css/imgSite/sisLogo.png

I suppose you know that you have to include the css path in the jsf code.

Exemple : (in your case, you have to put this in your code xhtml who need this css)

<h:outputStylesheet library="css" name="cssLayout.css" />

hope help.

Thanks

Aucxence
  • 73
  • 2
  • 8