1 eXo Skins
eXo provides support for skining the entire portal UI including your own portlets. Skins intend to help you pack and reuse common graphic resources.1.1 Skin switching
Skins can be switched dynamically at runtime by the Skin Settings action in User Workspace?.
When you switch, the whole portal will be repainted and new styles will be applied to the UI.
1.2 Skins in pages markup
An eXo skin contains css styles for eXo portal's components but also shared components that may be reused in portlets. When eXo generates a portal page markup, it inserts stylesheet links in the page's head tag.<head> ... <link id="CoreSkin" rel="stylesheet" type="text/css" href="/eXoResources/skin/Stylesheet.css" /> <link id="web_FooterPortlet" rel="stylesheet" type="text/css" href= "/web/skin/portal/webui/component/UIFooterPortlet/DefaultStylesheet.css" /> <link id="web_NavigationPortlet" rel="stylesheet" type="text/css" href= "/web/skin/portal/webui/component/UINavigationPortlet/DefaultStylesheet.css" /> <link id="web_HomePagePortlet" rel="stylesheet" type="text/css" href= "/portal/templates/skin/webui/component/UIHomePagePortlet/DefaultStylesheet.css" /> <link id="web_BannerPortlet" rel="stylesheet" type="text/css" href= "/web/skin/portal/webui/component/UIBannerPortlet/DefaultStylesheet.css" /> ... </head>
- Portal skin stylesheet (id="CoreSkin"):
- Portlets skin stylesheets (all others) : each portlet within the page may contribute its own styles.
1.3 Portal style
A portal skin is typically made of 3 types of styles:- Portlet themes? : decorations for portlet windows
- Portal styles? : default styles for html tags (ex div,th,td...) + the portal UI including the sidebar and portal admin screens
- Shared styles? : eXo Webui components styles reused among different eXo portlets
@import url(/eXoResources/skin/PortletThemes/Stylesheet.css) ; @import url(MacSkin/portal/webui/component/UIPortalApplicationSkin.css) ; @import url(MacSkin/webui/component/Stylesheet.css) ;
1.4 Portlet styles
Portlets often require additionnal styles that may not be defined by the portal skin. eXo allows portlets to define additional stylesheets for each portlet and will append the corresponding link tags to the head. The link ID will be of the form ${portletAppName}_${PortletName}. For example: ContentPortlet in content.war, will give id="content_ContentPortlet"2 How to configure a portal skin
2.1 SkinService
The SkinService is an eXo service that manages portal skin, portlet styles and portlet themes (windows borders). Below is an excerpt of the API offered by this service./** * Register the stylesheet for a portal Skin. * @param module skin module identifier * @param skinName skin name * @param cssPath path uri to the css file. This is relative to the root context, use leading '/' * @param scontext the webapp's {@link ServletContext} */ public void addPortalSkin(String module, String skinName, String cssPath, ServletContext scontext) { [...] } /** * Register a portlet stylesheet for a Skin. * @param module skin module. Typically of the form 'portletAppName/portletName' . * @param skinName Name of the skin * @param cssPath path uri to the css file. This is relative to the root context, use leading '/' * @param scontext the webapp's {@link ServletContext} */ public void addSkin(String module, String skinName, String cssPath, ServletContext scontext) { [...] } /** * Get a skin configuration for a given Skin * @param module skin module such as registered in {@link #addSkin(String, String, String, ServletContext)} * @param skinName skin name * @return the skin configuration or, if not found try to find the default skin */ public SkinConfig getSkin(String module, String skinName) { [...] } /** * Register multiple portlet themes * @param categoryName portlet theme category * @param themesName names of the themes */ public void addTheme(String categoryName, List<String> themesName) { [...] }
2.2 SkinConfigListener
eXo provides a servlet listener that allows you to register your own skins and styles when your webapp starts up. You first step is to add this to your portlet app web.xml.<web-app> [...] <listener> <listener-class>org.exoplatform.portal.webui.skin.SkinConfigListener</listener-class> </listener> [...] </web-app>
2.3 SkinConfigScript.groovy
The SkinListener looks for the groovy script file located in your war under : /WEB-INF/conf/script/groovy/SkinConfigScript.groovy In this script, you have full access to the SkinService and ServletContext which are bound as scripting variables under the same name. As an example, take a look at the following script. It can be found in the eXoResources.war and is used by eXo to register the Default portal skin and some portlet themes.SkinService.addPortalSkin("CoreSkin","Default", "/eXoResources/skin/Stylesheet.css", ServletContext); SkinService.addTheme("Simple", ["SimpleBlue","SimpleViolet","SimpleOrange","SimplePink","SimpleGreen"]); SkinService.addTheme("RoundConer", ["RoundConerBlue","RoundConerViolet","RoundConerOrange","RoundConerPink","RoundConerGreen"]); SkinService.addTheme("Shadow", ["ShadowBlue","ShadowViolet","ShadowOrange","ShadowPink","ShadowGreen"]); SkinService.addTheme("MacStyle", ["MacTheme","MacGray","MacGreenSteel","MacBlack"]); SkinService.addTheme("VistaStyle", ["VistaTheme","VistaBlue"]);
SkinService.addSkin("mywebapp/MyPortlet", "MyPortalSkin", "/mywebapp/skin/Stylesheet.css", ServletContext);
SkinService.addSkin("myportalname", "skin", "/path/to/skin/Stylesheet.css", ServletContext);
3 Tips and tricks
3.1 Easier css debugging
By default, CSS files are cached and their imports are merged, at the server side, into a single CSS file to reduce the number of HTTP requests from the browser to the server. The ServletContext parameter is there to allow the direct access to the CSS files from the SkinService. The optimization code is quite simple as all the CSS files are parsed at the server startup time and all the @import and url(...) references are rewritten to support a single flat file. The result is stored in a cache directly used from the ResourceRequestFilter. Although the optimization is usefull for the production environements, you may find easier to desactivate this optimization while debugging your stylesheets. For that, you simply need to set the java system property exo.product.developing to true. For example, you can pass the property as a JVM parameter with the -D option in your eXo.sh startup script:EXO_OPTS="-Dexo.product.developing=true"3.2 Change portlet icons
Each portlet is represented by an icon that you can see in the portlet registry, or the webos dock. You can change this icon by adding an image in the directory : $project/portlet/myportlets/src/main/webapp/skin/DefaultSkin/portletIcons/ and by naming the icon after the portlet, eg: ExoPortlet.png For example, in portal we have an account portlet named AccountPortlet, the icon is located in : portal/tags/2.1.1/portlet/exoadmin/src/main/webapp/skin/DefaultSkin/portletIcons/AccountPortlet.png3.3 How to set the default skin for portal
When not configured, the default skin of portal is Default. If you want to change this value (to Mac skin, Vista skin, or your own), add a skin tag in the portal.xml that defines your portal :<portal-config> <portal-name>classic</portal-name> <locale>en</locale> <factory-id>office</factory-id> <access-permissions>Everyone</access-permissions> <edit-permission>*:/platform/administrators</edit-permission> <creator>root</creator> <skin>Mac</skin> ...
3.4 Some CSS techniques we use
eXo relies heavily on CSS to create the layout and special effects for the UI. Below we explain some common techniques you may find often inside eXo's markup. We explain them here to help you better understand eXo generated markup, ease css issues fixing or get inspration for styling your own apps.Decorator pattern
The decorator is a pattern to create a contour or a curve around an area. In order to achieve this effect you need to create 9 cells. The BODY is the central area that you want to decorate. The other 8 cells are distributed around the BODY cell. You can use the width, height and background image properties to achieve any decoration effect that you want.----------------------------------------------------------------------- | | | | | TopLeft | TopCenter | TopRight | | | | | ----------------------------------------------------------------------- | | | | | | | | | CenterLeft | BODY | CenterRight | | | | | | | | | ----------------------------------------------------------------------- | | | | | BottomLeft | BottomCenter | BottomRight | | | | | ----------------------------------------------------------------------- <div class="Parent"> <div class="TopLeft"> <div class="TopRight"> <div class="TopCenter"></div> </div> </div> <div class="CenterLeft"> <div class="CenterRight"> <div class="CenterCenter">BODY</div> </div> </div> <div class="BottomLeft"> <div class="BottomRight"> <div class="BottomCenter"></div> </div> <div> </div>
Left margin left pattern
Left margin left pattern is a technique to create 2 blocks side by side. The left block will have a fixed size and the right block will take the rest of the available space. When the user resize the browser the added or removed space will be taken from the right block.---------------------------------------------------------------------------- | | | | | | | |<--- fixed width --->| | will expand to right ------> | | | | | | | | | | ---------------------------------------------------------------------------- <div class="Parent"> <div style="float: left; width: 100px"> </div> <div style="margin-left: 105px; width: 100%"> <div> </div>
on 04/12/2008 at 04:18