This article describes the two different ways of skinning a component and explains how the various skin-related resources are prepared at build time to be served by JSF. It also explains how to add more components and skins to this process. Finally, it describes how all CSS files of a skin are merged into one file.
JSF 2 has its own resource handling mechanism. It is explained in detail in section 2.6 of the JSF 2.0 specification. The relevant points to this article are the following:
Therefore, in ICEfaces, all resources used for skinning components (i.e. CSS and image files) are prepared at build time for JSF 2's resource handling mechanism. Optionally, these resources will undergo an optimization that consists of generating sprite images. In any case, the resulting resources (i.e. modified CSS files and generated images) will ultimately be prepared in the same way for JSF's resource handling mechanism.
It is important to first clarify what is meant by original files in this context. These are all the raw, unprocessed skin-related files (i.e. CSS and image files). They are placed, by convention, in a directory named 'skins' inside the component's source directory. However, it is possible to place these files in any location. Inside this directory, there should be a subdirectory for every skin that the component supports. The name of this subdirectory should match the name of the skin across the entire project. For example, at the moment of this writing, the only supported skins are 'sam' and 'rime', so all components that support these skins have subdirectories inside 'skins' named exactly 'sam' and 'rime'.
The CSS files inside these skin directories can reference image files in the usual way (i.e. with relative paths to the image files inside url() expressions). It is important not to reference images that are outside of the skin subdirectory.
Even if two components use the same image, they must have their own copy. The purpose of this is to ease the job of customizing the look of specific components, without affecting others. If sprites are enabled, SmartSprites will automatically detect duplicate images and only include one copy of it in the generated sprite image.
The source files described above will be taken from their original location and placed inside the org.icefaces.component.skins resource library, so that they can be actually served when the application is deployed. The CSS files will be modified so that the URLs of the images they reference are in the format required by the JSF2 resource handling mechanism. Optionally, sprite images for each skin will be generated from all the individual images used by all components supporting that skin.
For example, the original skin files for a determined component could have the following structure.
At the end of the process, the files would be placed in the org.icefaces.component.skins resource library directory, as illustrated below.
The generated sprite images will always be placed directly under a org.icefaces.component.skins/<skin-name> directory. Here is the concrete example for the sam skin:
This process will be carried out when building the main sparkle project (i.e. by just typing 'ant'). If one only wishes to perform the skins processing, one can just run the 'skins' target (i.e. by typing 'ant skins'). Likewise, one can clean only the skins by running the 'clean-skins' target. The 'skins' target depends on the 'cssurlmapper' target, which builds the tool that carries out the URL mapping.
One can choose to use sprite images or not by setting/unsetting the 'use.sprites' property in the 'build.properties' file. Using sprites is only a performance optimization. The components should look exactly the same whether sprites are used or not. If 'use.sprites' is set, then, at build time, sprite images will be generated using the source images explained above, and the source CSS files will be modified to reference these generated images at the right offsets. More information on sprite generation can be found here. If 'use.sprites' is not set, then all images will be accessed individually.
The 'cssurlmapper' tool will parse all CSS files (the original ones or the ones generated by SmartSprites) and will map all URLs contained in it to the format required by the JSF2 resource handling mechanism. The build script is configured to place the output files in a specified resource library directory.
For example, the following URL appears in an original CSS file.
It will be mapped as follows.
More specific information about the CSS URL mapper can be found here.
New skin resources are added on a per-component, per-skin basis. Each such addition requires a declaration in the build file.
We need to add an 'includeresources' declaration inside the 'skins' target and provide the following three pieces of information:
A real example of this declaration would be the following:
If we are creating a completely new skin, then we must also call the task 'generatesprites', specifying its name in the 'skin' attribute. This is done only once per skin. An example of this would be the following.
When using a skin, each component requires it's own CSS files, which would necessitate manually including all of the CSS files for each component in the page. This would obviously be a burden for the application developer. It would be easier to include a single CSS file that contains the styling for all components for a given skin. This problem is solved by concatenating all of the CSS files for a given skin into a single CSS file. This is done at build time by using the following macro at the end of the 'skins' task:
Where 'name' refers to the name of the skin. The skin names have to be the same that are used throughout the build script. The resulting files are placed in the 'org.icefaces.component.skins' resource library.They have the exact same name as the skin name specified and have the extenstion .css (e.g. '/resources/org.icefaces.component.skins/rime.css').
© Copyright 2018 ICEsoft Technologies Canada Corp.