Introduction
The Portal product documentation describes how to create custom themes and you may have already created a custom theme with static components in WebDAV and dynamic components in a WAR file. This article describes how you can create a theme with all the components together, except layouts, in one WAR file.
The process to create this kind of theme is divided into three parts:
1. Create the WAR directory with the dynamic resources
2. Add the static resources to the WAR
3. Deploy the WAR and register the theme
Create the WAR directory with the dynamic resources
Follow these steps to create the WAR directory:
1. Copy the contents of the original PageBuilder2 theme into a new WAR directory. The PageBuilder2 theme is located here:
<portal-root>/theme/wp.mashup.cc.theme/installedApps/wp.mashup.cc.theme.ear/PageBuilder2.war
2. Remove the "skins" directory from the contents as it contains skins that are already registered. If you want to add additional skins then you should remove the skins contained in this directory and replace them with your new skins.
3. Change the name of the "PageBuilder2" directory (located in "/themes/html/") to a name of your choosing, i.e. "MyTheme".
4. Remove the "plugin.xml" file from the WEB-INF directory but do not remove the "decorations.xml" file or the "tld" directory.
5. Change the <display-name /> element in the "web.xml" file to a name of your choosing.
6. In the "ibm-web-bnd.xmi" and "ibm-web-ext.xmi" change the <webapp /> element to match the name in the <display-name /> element.
Default for the element is:
<webapp href="WEB-INF/web.xml#PageBuilder2_Theme"/>
Change to:
<webapp href="WEB-INF/web.xml#<replace with your display-name>"/>
Notes:You may want to replace the web.xml, ibm-web-bnd.xmi and ibm-web-ext.xmi file with your own so you can specify a different web-app version or other tags. The tags that control class reloading have changed in WAS V7. If you want to enable class reloading then add the following tags to the "ibm-web-ext.xml" file:
<jsp-attribute name="reloadEnabled" value="true" />
<jsp-attribute name="reloadInterval" value="5" />
Add the static resources to the WAR
Follow these steps to add the static resources to the WAR:
1. Locate the PageBuilder2 theme folder in the WebDAV file store using the URI:
http://<host>:10039/wps/mycontenthandler/dav/fs-type1/themes/PageBuilder2
2. Copy the entire PageBuilder2 WebDAV theme directory to the "/themes/html/CustomThemeName" directory.
Note:Some of the files will go into existing directories under your "CustomThemeName" directory so you will have to respond to the prompt that asks if you want to overwrite those directories. Select "yes" as there should be no file collisions.
3. Change all the dynamic-content spots in theme.html (or theme_<locale>.html), except for the layout one, to point to the dynamic resources in your new WAR file.
Example of out-of-box dynamic-content spot:
<link rel="dynamic-content" href="dyn-cs:id:head@tl:oid:csa2.theme">
Change to:
<link rel="dynamic-content" href="res:/CustomThemeName/themes/html/YourThemeDir/head.jsp">
Deploy the WAR and register the theme
Follow these steps to finish the process:
1. Package your directory into a new WAR file and deploy to the WebSphere_Portal server using the WAS administration console.
Note:Document the context root you assigned to the WAR as it will be used later.
2. Start your new Enterprise Application.
3. Export the themes using this xml file:
<?xml version="1.0" encoding="UTF-8"?>
<request
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="PortalConfig_7.0.0.xsd" type="export"
create-oids="true">
<portal action="locate">
<theme action="export" objectid="*" />
</portal>
</request>
4. Locate the PageBuilder2 theme (the uniquename is "csa2.theme") and remove all other <theme /> tags and all their child tags.
5. Remove the objectId attribute and its value from the
element.
Note:If you fail to remove the objectId you will end up modifying an existing theme.
6. Ensure that the "default" attribute on the
element is set to false.
7. Change the "context-root", "resourceroot" and "uniquename" attributes to match your custom theme WAR that was creating in previous steps.
8. Change the theme title on the <localedata /> tags for the locales in which your Portal supports.
9. Change the "com.ibm.portal.friendly.name" parameter, if it exists, to differentiate this theme from the others.
10. Change the "com.ibm.portal.theme.template.ref" parameter to point to your new custom theme context root.
Example:
<parameter name="com.ibm.portal.theme.template.ref" type="string" update="set">
<![CDATA[res:CustomThemeName/themes/html/CustomThemeDir/]]>
</parameter>
Notes:"CustomThemeName" is the context-root of your theme. "CustomThemeDir" is the name of your theme directory in the WAR.
11. Save these modifications as a new xml file, as to not overwrite the original export of all themes.
12. Import the new xml file using xmlaccess.
You now have a functional Page Builder theme that can be assigned to pages without the static resources being located on WebDAV.
Troubleshooting
Problem: The context-root of your new web applciation can not be found
Solution: Make sure you started the new enterprise application. Also, if you are accessing the portal via the Web server then make sure you re-generated the plugin file and distributed it to the web servers. Also, make sure you mapped the WAR module to both your Portal server and your web server.
Problem: Your xmlacces import changed the base PageBuilder2 theme
Solution: Import the XML file from the export of all themes (step 3 in the "Deploy the WAR and register the theme" section). This should restore all themes to their original state.
Problem: Updating the theme war after initial deployment causes errors (typically with com.ibm.wps.resolver.data.exceptions.URIProcessingIOException: EJCBD0021E)
Solution: Try changing the cache.expiration for themes and skins to 30 seconds on the WP Config Service resource environment provider (stop and restart portal). For example:
filestore.cache.expiration.0.re=themes/.*
filestore.cache.expiration.0.seconds=30
filestore.cache.expiration.0.re=skins/.*
filestore.cache.expiration.0.seconds=30