Showing posts with label theme70. Show all posts
Showing posts with label theme70. Show all posts

Using custom dynamic content spot in PageBuilder2 theme

Page Builder2 theme makes use of dynamic content spots, which are nothing but .jsp's that are included in theme.html. I wanted to see if i can create a custom dynamic content spot and include it in my theme so i tried these steps and it worked


  • First i did create a simple testds.jsp file, it looks like this

    <h3>This is sample text generated by testds.jsp</h3>

    I am just generating one h1 element inside the testds.jsp

  • Then i copied the testds.jsp file inside the /PortalServer/theme/wp.mashup.cc.theme/installedApps/wp.mashup.cc.theme.ear/PageBuilder2.war/themes/html/PageBuilder2 folder like this


  • Once your testds.jsp is copied into the PageBuilder2.war you have two options for including it in the theme.html, one is directly using the path to PageBuilder2 and second is using the dynamic content spot matching service

    <a rel="dynamic-content" href="res:/PageBuilder2/themes/html/PageBuilder2/testds.jsp"></a>

    <a rel="dynamic-content" href="dyn-cs:id:testds@tl:oid:csa2.theme"></a>


    In this the href="res:/PageBuilder2/themes/html/PageBuilder2/testds.jsp" is sample of how you can directly include the testds.jsp inside your theme.html, it does not require any further steps

    But if you dont want to hardcode path to testds.jsp in your theme.html then you can can create a mapping in the dynamic content spot mapping service and use the mapped name. In my case i did create mapping to testds name so i have to use dyn-cs:id:testds@tl:oid:csa2.theme as value of href

  • Next step is to create mapping that maps testds name to res:/PageBuilder2/themes/html/PageBuilder2/testds.jsp, you will have to use WAS Admin console





With mapping in place i copied my theme_en.html file to the nls folder and now when i try accessing the portal page i can see the testds.jsp getting included once because of direct .jsp reference and once because of content spot mapping reference like this




Important Note: After i copied testds.jsp in the PageBuilder2 theme i tried accessing theme.html and first it was throwing test.jsp not found error but then i did export of PageBuilder2.war and updated it and it started working, you might want to do same thing in ND environment.

Working with PageBuilder2 theme .html, theme.html, skin.html

For last few days i was struggling to figure out how to modify theme.html and finally i got help from my colleagues Evan and Sanjay and now i am able to modify markup generated for theme.html. Take a look at the screen shot, i did add <h1>This is test modification in theme.html</h1> as first element to the body tag



You will have to use following steps to get it working


  • First of all create WebDav connection to /wps/mycontenthandler/dav/fs-type1 URL, this is the URL that you should use. It seems that http://localhost:10039/wps/mycontenthandler/dav/themelist url is not a valid URL for WebDav, it will keep throwing some weired error


  • Once your WebDav connection is established go to themes/PageBuilder2 folder, you will find a theme.html file here and there is locale specific version of theme.html in nls folder. I tried changing the theme.html in PageBuilder2 folder but somehow it never gets picked up instead portal always picks up locale specific version from nls folder



  • Make changes in theme.html and save those changes, if your using WebDav client(WebFolders, BitKinex) on Windows, first you will have to copy the file to local machine, modify it and then copy it back






Once your changes are updated you can refresh the page and you should be able to see the modified markup

PageBuilder 2 skin architecuter - skin.html

The PageBuilder 2 theme makes use of theme.html for defining layout of the page, it makes use of skin.html for generating markup for the skin. Note that it does not have UnlayeredContainer-H.jsp, UnlayeredContainer-V.jsp, control.jsp any more. It seems that layout.html will replace the horizontal and vertical container related functionality and the skin.html has functionality corresponding to Control.jsp.

This is how the skin.html from my local machine looks like

<div class="ibmPortalControl lotusWidget2 decoration-aria-region"><!--START LOCALE LINKS-->
<a rel="alternate" href="nls/skin_en.html" hreflang="en" class="ibmHideTemplate"></a>
<!-- decoration marks the Dojo resource name of the decoration object instantiated at the root of this layout control -->
<span style="display:none" class="decoration">com.ibm.skins.Standard.skin</span>
<!-- asa.portlet.id marks the node whose contents are the id of this layout control;
set at runtime by script in the decoration instance -->
<span style="display:none" class="asa.portlet.id"></span>
<!-- decoration classes are used by DecorationManager for adding javascript event handlers -->
<h2 class="decoration-titlebar decoration-dndHandle">
<span class="lotusLeft"> <!-- lm-dynamic-title node marks location for dynamic title support -->
<span class="lm-dynamic-title asa.portlet.title decoration-title">
<a rel="dynamic-content" href="lm:title"></a>
</span>
</span>
<a aria-haspopup="true" title="${nls.Theme:a11y_display_menu:xml}" href="javascript:;"
class="lotusIcon lotusActionMenu decoration-contextMenuAction">
<span class="lotusAltText">${nls.Theme:theme_actions:xml}</span>
</a>
</h2>
<!-- decoration-contextMenu is the anchor node to build the context menu link and widget around -->
<div style="display:none" class="decoration-contextMenu"></div>
<div class="lotusWidgetBody"> <!-- lm:control dynamic spot injects markup of layout control -->
<a rel="dynamic-content" href="lm:control"></a>
</div>
</div>


The skin.html also makes use of concept of dynamic content spot.


  • lm:title : represents the title of the portlet

  • lm:control : represents the body of the portlet

PageBuilder2 theme architecture - Dynamic Content Spot

In the PageBuilder2 theme architecture - theme.html i mentioned that the theme.html makes use of concept of dynamic content spot. The basic concept is that the theme.html want to include .jsp page, since the .html page cannot directly add .jsp page since .jsp pages need servlet context to compile and execute, those .jsps are packaged in the PageBuilder2.war along with Default.jsp.



Ex. the theme.html wants to forward control to asa.jsp for generating active sight analytics(asa) related markup, so you can include that .jsp in the theme.html like this

<a rel="dynamic-content"
href="res:/PageBuilder2/themes/html/PageBuilder2.0/asa.jsp"></a>


But this approach has following problems

  • Reference by name abstracts the dynamic content away from the implementation. This is necessary if the theme needs to run on multiple runtimes, for example WebSphere Portal and IBM® Mashup Center. The portal implementation of the navigation tabs can be a JSP that contains portal specific code. The Mashup Center on the other hand cannot execute portal JSP code, but provides an iWidget instead.

  • Reference by name isolates the theme author from having to know the underlying code information. This is useful if the theme author is an HTML and CSS designer, but not a J2EE or JavaScript developer. The HTML and CSS developer needs to know only the list of named content spots and the simple syntax to add it. This developer can then write code without having to know JSP path names etc.



So in order to provide one more layer of indirection, WPS has WP_DynamicContentSpotMappings resource provider that lets you map a symbolic name to the location of .jsp like this




Now inside your theme.html you can refer to the asa.jsp like this

<a rel="dynamic-content" href="dyn-cs:id:asa@tl:oid:csa2.theme" />


The resolver framework takes care of finding the actual .jsp file from this symbolic name. Also if you start digging into the .jsp files you will notice that they also include other .jsps by using this type of syntax


<r:dataSource uri="dyn-cs:id:configGlobal@tl:oid:csa2.theme" escape="none">
<r:param name="pragma" value="cache"/>
</r:dataSource>
<r:dataSource uri="dyn-cs:id:configDynamic@tl:oid:csa2.theme" escape="none"/>

PageBuilder2 theme architecture - theme.html

In the PageBuilder2 Theme architecture - bootstrap jsps, i mentioned that the Default.jsp of the PageBuilder2 theme does not have any HTML markup, instead it just initializing few values and then forwarding control to theme.html.

This is how the theme.html which ships with the WPS looks like. As you can see the theme.html is pretty clean and small,


<!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" lang="${locale}" xml:lang="${locale}">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<!-- rel=dynamic-content indicates an element that is replaced with the contents produced by the specified href.
dyn-cs:* URIs are resolved using the WP DynamicContentSpotMappings resource environment provider. These values can
also be set using theme metadata if a theme is specified in the URI (e.g. @tl:oid:theme_unique_name). -->
<link rel="dynamic-content" href="dyn-cs:id:head@tl:oid:csa2.theme">
<script type="text/javascript">
dojo.addOnLoad(function(){
com.ibm.pb.themes.commonInit({
setWindowTitle:true,
useNavigationController: true,
useRenderingController: true,
useDNDController: true,
initLiveTextService: true,
lazyLoadModeWidgets: true,
navPrimingContainers: ["selectionPathPrimer","topNavLinks","navTabsRoot"],
customInit: com.ibm.themes.PageBuilder2.init
});
dojo.publish("com.ibm.portal.theme.portlet_ready"); // notifies ASA that portlet IDs are ready to be found in the DOM
});
</script>
<!-- rendering is delegated to the specified href for each locale --><!--START LOCALE LINKS-->
<link rel="alternate" href="nls/theme_en.html" hreflang="en">
</head>
<body class="lotusui tundra${rtl| lotus_rtl mumrtl} locale_${locale}" ${bidi.dir.attribute} >

<div class="lotusFrame">
<div class="lotusui lotusTitleBar">
<div class="lotusRightCorner">
<div class="lotusInner">
<a rel="dynamic-content" href="dyn-cs:id:tabNav@tl:oid:csa2.theme"></a>
<div style="clear: both;"></div>
</div>
</div>
</div><!--end titleBar-->
<a rel="dynamic-content" href="dyn-cs:id:pageToolbar@tl:oid:csa2.theme"></a>
<div class="lotusMain" id="lotusMain">
<!-- pb-pageMode-edit indicates that an iwidget should be lazy-loaded upon entering edit mode for the page -->
<div class="iw-iWidget iw-Standalone pb-pageMode-edit" id="customizeShelfContainer">
<a class="iw-Definition"
href="/mccbuilder/widget-catalog/customizeShelf.xml?pragma=cache&max-age=1209600&cache-scope=public&vary=none"></a>
</div>
<div style="clear:both;"></div>
<a id="lotusMainContent" name="lotusMainContent"></a>
<div id="layoutContainers" class="ibmLayoutContainers ibmLayoutContainersHidden" role="main">
<a rel="dynamic-content" href="dyn-cs:id:layout@tl:oid:csa2.theme"></a>
</div>
</div><!--end main-->
<div class="lotusFooter"></div><!-- page footer -->
</div><!--end frame-->
<!-- active site analytics additions -->
<a rel="dynamic-content" href="dyn-cs:id:asa@tl:oid:csa2.theme"></a>
<!-- This is responsible for bootstrapping the configuration for the javascript framework.
This is located here instead of the head section to improve client performance. -->
<a rel="dynamic-content" href="dyn-cs:id:config@tl:oid:csa2.theme"></a>

<div id="systemWidgets">
<div class="iw-iWidget iw-Standalone" id="templateLayout">
<a class="iw-Definition"
href="/mccbuilder/widget-catalog/templateLayout.xml?pragma=cache&max-age=1209600&cache-scope=public&vary=none"></a>
</div>
<div class="iw-iWidget mumHiddenWidget iw-Standalone" id="pageActionsMenu">
<a class="iw-Definition"
href="/mccbuilder/widget-catalog/ContentSetMenu.xml?pragma=cache&max-age=1209600&cache-scope=public&vary=none"></a>
<span class="iw-ItemSet" title="attributes" style="display: none;">
<a class="iw-Item" href="#contextMenuID">pageActions</a>
<a class="iw-Item" href="#anchorCSSClass">lotusCommonActionMenuAnchor</a>
<a class="iw-Item" href="#menuCSSClass">lotusCommonActionMenu</a>
<a class="iw-Item" href="#resourceType">com.ibm.mashups.enabler.navigation.NavigationNode</a>
<a class="iw-Item" href="#openEvent">PageActions.open</a>
<a class="iw-Item" href="#closeEvent">PageActions.close</a>
</span>
</div>
<div class="iw-iWidget mumHiddenWidget iw-Standalone" id="userActionsMenu">
<a class="iw-Definition" href="/mccbuilder/widget-catalog/ContentSetMenu.xml?pragma=cache&max-age=1209600&cache-scope=public&vary=none"></a>
<span class="iw-ItemSet" title="attributes" style="display: none;">
<a class="iw-Item" href="#contextMenuID">userActions</a>
<a class="iw-Item" href="#anchorCSSClass">lotusCommonActionMenuAnchor</a>
<a class="iw-Item" href="#menuCSSClass">lotusCommonActionMenu</a>
<a class="iw-Item" href="#resourceType">com.ibm.mashups.enabler.user.User</a>
<a class="iw-Item" href="#openEvent">UserActions.open</a>
<a class="iw-Item" href="#closeEvent">UserActions.close</a>
</span>
</div>
<div class="iw-iWidget mumHiddenWidget iw-Standalone pb-pageMode-edit" id="newPage">
<a class="iw-Definition"
href="/mccbuilder/widget-catalog/NewPageDialog.xml?pragma=cache&max-age=1209600&cache-scope=public&vary=none"></a>
<span class="iw-ItemSet" style="display:none" title="attributes">
<a class="iw-Item" href="#controller">ibmCfg.controllers.navigation</a>
<a class="iw-Item" href="#allowFriendlyURL">true</a>
<a class="iw-Item" href="#allowPrivate">true</a>
</span>
</div>
<!-- The lazyLoad attribute is used for widgets that are explicitly loaded by another source at a later point in time
(in this case the displayHelper). -->
<div class="iw-iWidget mumHiddenWidget iw-Standalone" lazyLoad="true" id="sharePage">
<a class="iw-Definition"
href="/mccbuilder/widget-catalog/accessControl.xml?pragma=cache&max-age=1209600&cache-scope=public&vary=none"></a>
</div>
<div class="iw-iWidget mumHiddenWidget iw-Standalone" lazyLoad="true" id="reorderPage">
<a class="iw-Definition"
href="/mccbuilder/widget-catalog/reorderPageWidget.xml?pragma=cache&max-age=1209600&cache-scope=public&vary=none"></a>
</div>
<div class="iw-iWidget mumHiddenWidget iw-Standalone" lazyLoad="true" id="viewMorePage">
<a class="iw-Definition"
href="/mccbuilder/widget-catalog/viewMorePage.xml?pragma=cache&max-age=1209600&cache-scope=public&vary=none"></a>
</div>
<div class="iw-iWidget mumHiddenWidget iw-Standalone" lazyLoad="true" id="wireInterface">
<a class="iw-Definition"
href="/mccbuilder/widget-catalog/wireInterfaceWithSettings.xml?pragma=cache&max-age=1209600&cache-scope=public&vary=none"></a>
<span class="iw-ItemSet" title="attributes" style="visibility: hidden; display: none">
<a class="iw-Item" style="visibility:hidden;display:none;" href="#displaySettings">true</a>
<a class="iw-Item" style="visibility:hidden;display:none;" href="#displayPortletsAndWidgetsWarningMessage">true</a>
</span>
</div>
<div class="iw-iWidget mumHiddenWidget iw-Standalone pb-pageMode-edit" id="autoWiringManager">
<a class="iw-Definition"
href="/mccbuilder/widget-catalog/autoWiringManager.xml?pragma=cache&max-age=1209600&cache-scope=public&vary=none"></a>
</div>
<div class="iw-iWidget iw-Standalone" id="dialogDisplayer">
<a class="iw-Definition" style="visibility:hidden;display:none;"
href="/mccbuilder/widget-catalog/displayHelper.xml?pragma=cache&max-age=1209600&cache-scope=public&vary=none"> </a>
<span class="iw-ItemSet" title="attributes" style="visibility: hidden; display: none;">
<a class="iw-Item" style="visibility:hidden;display:none;" href="#sharePage">sharePage</a>
<a class="iw-Item" style="visibility:hidden;display:none;" href="#reorderPage">reorderPage</a>
<a class="iw-Item" style="visibility:hidden;display:none;" href="#viewMorePage">viewMorePage</a>
<a class="iw-Item" style="visibility:hidden;display:none;" href="#wireInterface">wireInterface</a>
<a class="iw-Item" style="visibility:hidden;display:none;" href="#autoWiringManager">autoWiringManager</a>
</span>
</div>
</div>
</body>
</html>



If you compare the theme.html to the markup generated for the portal page you will notice that the portal page has more markup(as expected it has markup generated by portal, markup for navigation,..)



Also if you compare this markup to the markup generated for portal page you will notice that most of the markup for normal page is generated inside div class="lotusFrame", which is the highlighted code. There is lot of code under div id="systemWidgets" but my guess is that code kicks in only in case of iwidget on a page.

Now the basic question would be then who is generating the portal markup, who takes care of generating navigation, forwarding control to portal aggregation engine,.. The answer would be its the dynamic content spots in the .html

PageBuilder2 Theme architecture - bootstrap jsps

In the PageBuilder2 theme architecture i mentioned that first thing that Default.jsp does is forward control to bootstrap.jspf and bootstrapPortal.jspf.

These two files are used for calculating portal level variables such as


  • isPageRenderModeCSA: If the page render mode is CSA or SSA

  • Locale: Avaiable locale, default locale

  • user Id: user id of the anonymous and authenticated user, if user is logged in

  • ContentHandlerURI: The URI for the ContentHandler by default it will always be /wps/contenthandler for anonymous or /wps/mycontenthandler for authenticated user, this URI is also used a base for all the resources

  • portalContext: /wps

  • portalProxyUrl: /wps/proxy

  • Dojo information: dojoRoot /portal_dojo/v1.4.3 and dojoContextRoot is /portal_dojo

  • themeWebDAVBaseURI: dav:fs-type1/themes/PageBuilder2/

  • themeWebAppBaseURI: /PageBuilder2/themes/html/PageBuilder2

  • colorPalette: By default its empty but you can override these values at page level

  • pageStyle:By default its empty but you can override these values at page level

  • navTabsLevel,navTabRootNode: Navigation generation related information

PageBuilder2 theme architecture - Default.jsp

IBM introduced PageBuilder2 theme in WPS 7.0, it allows user to define the theme using static html file, it seems that there are different pieces and i wanted to check how the different pieces fit together, so i started debugging theme and these are my notes

Even though the PageBuilder2 theme is changed one thing is still same which is Default.jsp file in the theme acts as entry point, it controls the overall theme. This is how the Default.jsp of PageBuilder2 theme looks like


<%@ page session="false" buffer="none" %>
<%@ page trimDirectiveWhitespaces="true" %>
<%-- Licensed Materials - Property of IBM, 5724-E76, (C) Copyright IBM Corp. 2001, 2004, 2006, 2010 - All Rights reserved. --%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@taglib uri="http://java.sun.com/jsp/jstl/functions" prefix="fn" %>
<%@taglib uri="http://www.ibm.com/xmlns/prod/websphere/portal/v7.0/portal-core" prefix="portal-core" %>
<%@taglib uri="http://www.ibm.com/xmlns/prod/websphere/portal/v7.0/portal-logic" prefix="portal-logic" %>
<%@taglib uri="http://www.ibm.com/xmlns/prod/websphere/portal/v7.0/portal-fmt" prefix="portal-fmt" %>
<%@taglib uri="/WEB-INF/tld/portal-internal.tld" prefix="portal-internal" %>
<%@taglib uri="/WEB-INF/tld/resolver-v7.tld" prefix="r" %>
<portal-core:constants/>
<portal-core:defineObjects/>
<portal-internal:adminNavHelper/>
<%@ include file="./bootstrap.jspf" %>
<%@ include file="./bootstrapPortal.jspf" %>
<%-- The theme template is determined by whether there is a value set in page meta data,
if no value is set in the meta data, then it defaults to the template stored in webdav --%>
<c:choose>
<c:when test="${empty themeWebDAVBaseURI}">
<c:set var="themeTemplateURI" value="" />
</c:when>
<c:when test="${empty dirMD['com.ibm.portal.theme.template.file.name.html']}">
<c:set var="themeTemplateURI" value="${themeWebDAVBaseURI}theme.html" />
</c:when>
<c:otherwise>
<c:set var="themeTemplateURI" value="${themeWebDAVBaseURI}${dirMD['com.ibm.portal.theme.template.file.name.html']}" />
</c:otherwise>
</c:choose>
<c:choose>
<c:when test="${!empty themeTemplateURI}">
<r:dataSource uri="spa:${wp.identification[wp.selectionModel.selected]}" escape="none">
<r:param name="themeURI" value="${themeTemplateURI}"/>
<r:param name="mime-type" value="text/html"/>
</r:dataSource>
</c:when><%-- If no theme template is found, the fallback.jsp is rendered--%>
<c:otherwise>
<%@ include file="./fallback.jsp" %>
</c:otherwise>
</c:choose>


The Default.jsp is very simple and it does not have any HTML markup generation code at all. The functionality of Default.jsp can be broken into 3 parts


  • Initializing variables required for the theme: At the start of the Default.jsp it is forwarding control to bootstrap.jspf and bootstrapPortal.jspf, It looks like these two files are used for initializing all the variables that are required for theme. Things like if user is logged in, if yes what is userId, available locale, paths to contenthandler and also some variables that are required for calculating themeTemplateURI

  • Cacluate value of themeTemplateURI Next it tries to calculate value of themeTemplateURI. In the default implementation it will always be dav:fs-type1/themes/PageBuilder2/theme.html but your allowed to override this value at page level as well as at theme level

  • Forwarding control to r:dataSource for generating markup Once the value of themeTemplateURI is calculated control will fowarded to r:dataSource jsp tag, and this tag will be responsible for parsing theme.html, evaluating dynamic content spot, and generating final html markup

Where is source code for Page Builder 2 theme

The WebSphere portal server has a very different directory layout/ application deployment structure compared to the previous version, i think this was done to support multiple profiles but i need to dig into that part.

I am trying to learn about PageBuilder2(CSA2) theme that was introduced in WPS 7.0, so i thought i will look into the source code to find out how it works so i went to wp_profiles/installedApps folder but i could not see PageBuilder2.ear. In fact it seems that installedApps folder has few applications



But when i tried accessing any portal page i could see some PageBuilder2 theme related jsp's being initialized

[9/29/10 6:24:12:832 PDT] 00000081 servlet I com.ibm.ws.webcontainer.servlet.ServletWrapper init SRVE0242I: [PageBuilder2_Theme] [/PageBuilder2] [/themes/html/Default.jsp]: Initialization successful.
[9/29/10 6:24:14:684 PDT] 00000081 servlet I com.ibm.ws.webcontainer.servlet.ServletWrapper init SRVE0242I: [PageBuilder2_Theme] [/PageBuilder2] [/themes/html/PageBuilder2/head.jsp]: Initialization successful.
[9/29/10 6:24:21:426 PDT] 00000081 servlet I com.ibm.ws.webcontainer.servlet.ServletWrapper init SRVE0242I: [PageBuilder2_Theme] [/PageBuilder2] [/themes/html/PageBuilder2/bannerNav.jsp]: Initialization successful.
[9/29/10 6:24:21:581 PDT] 00000081 servlet I com.ibm.ws.webcontainer.servlet.ServletWrapper init SRVE0242I: [PageBuilder2_Theme] [/PageBuilder2] [/themes/html/PageBuilder2/search.jsp]: Initialization successful.
[9/29/10 6:24:21:598 PDT] 00000081 servlet I com.ibm.ws.webcontainer.servlet.ServletWrapper init SRVE0242I: [PageBuilder2_Theme] [/PageBuilder2] [/themes/html/PageBuilder2/bannerCommonActions.jsp]: Initialization successful.
[9/29/10 6:24:22:210 PDT] 00000081 servlet I com.ibm.ws.webcontainer.servlet.ServletWrapper init SRVE0242I: [PageBuilder2_Theme] [/PageBuilder2] [/themes/html/PageBuilder2/status.jsp]: Initialization successful.
[9/29/10 6:24:22:460 PDT] 00000081 servlet I com.ibm.ws.webcontainer.servlet.ServletWrapper init SRVE0242I: [PageBuilder2_Theme] [/PageBuilder2] [/themes/html/PageBuilder2/tabNav.jsp]: Initialization successful.
[9/29/10 6:24:22:501 PDT] 00000081 servlet I com.ibm.ws.webcontainer.servlet.ServletWrapper init SRVE0242I: [PageBuilder2_Theme] [/PageBuilder2] [/themes/html/PageBuilder2/pageToolbar.jsp]: Initialization successful.
[9/29/10 6:24:23:306 PDT] 00000081 servlet I com.ibm.ws.webcontainer.servlet.ServletWrapper init SRVE0242I: [PageBuilder2_Theme] [/PageBuilder2] [/skins/html/UnlayeredContainer-H.jsp]: Initialization successful.
[9/29/10 6:24:23:331 PDT] 00000081 servlet I com.ibm.ws.webcontainer.servlet.ServletWrapper init SRVE0242I: [PageBuilder2_Theme] [/PageBuilder2] [/skins/html/UnlayeredContainer-V.jsp]: Initialization successful.
[9/29/10 6:24:24:628 PDT] 00000081 servlet I com.ibm.ws.webcontainer.servlet.ServletWrapper init SRVE0242I: [PageBuilder2_Theme] [/PageBuilder2] [/themes/html/PageBuilder2/asa.jsp]: Initialization successful.
[9/29/10 6:24:24:759 PDT] 00000081 servlet I com.ibm.ws.webcontainer.servlet.ServletWrapper init SRVE0242I: [PageBuilder2_Theme] [/PageBuilder2] [/themes/html/PageBuilder2/config.jsp]: Initialization successful.
[9/29/10 6:24:24:987 PDT] 00000081 servlet I com.ibm.ws.webcontainer.servlet.ServletWrapper init SRVE0242I: [PageBuilder2_Theme] [/PageBuilder2] [/themes/html/PageBuilder2/configDynamic.jsp]: Initialization successful.


So i went to wps_profile/temp folder, which will have .class file for every .jsp file that gets complied into .java first and then .class file and i could see a PageBuilder2_Theme and many other folders related application that are not there in installedApps




Since the temp folder had a PageBuilder2_Theme folder and it had .class files corresponding to .jsp's used by theme that confirmed that there is a .ear file behind it. So i checked the wp_profile/config/cells/localhost/application folder which is used for storing configuration for every .ear file that is installed on the server and there i could see PageBuilder2_Theme.ear file like this




Once you find the directory corresponding to the application that your looking for in wp_profile/config/cells/localhost/application folder, it becomes easy, you can go to PageBuilder2_theme/deployments/PageBuilder2_Theme folder and there you can find the deployment.xml which has information about where this application is actually installed. This is how the deployment.xml for PageBuilder2_Theme looks like on my machine


<?xml version="1.0" encoding="UTF-8"?>
<appdeployment:Deployment xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI"
xmlns:appdeployment="http://www.ibm.com/websphere/appserver/schemas/5.0/appdeployment.xmi"
xmi:id="Deployment_1282248412893">
<deployedObject xmi:type="appdeployment:ApplicationDeployment" xmi:id="ApplicationDeployment_1282248412894"
deploymentId="0" startingWeight="100" binariesURL="${WPS_HOME}/theme/wp.mashup.cc.theme/installedApps/wp.mashup.cc.theme.ear"
useMetadataFromBinaries="false" enableDistribution="false" createMBeansForResources="true" reloadEnabled="false"
appContextIDForSecurity="href:localhost/PageBuilder2_Theme" zeroEarCopy="true"
filePermission=".*\.dll=755#.*\.so=755#.*\.a=755#.*\.sl=755" allowDispatchRemoteInclude="false" allowServiceRemoteInclude="false"
asyncRequestDispatchType="DISABLED">
<targetMappings xmi:id="DeploymentTargetMapping_1282248412894" enable="true" target="ServerTarget_1282248412894"/>
<classloader xmi:id="Classloader_1282248412894" mode="PARENT_LAST"/>
<modules xmi:type="appdeployment:WebModuleDeployment" xmi:id="WebModuleDeployment_1282248412894" deploymentId="1"
startingWeight="10000" uri="PageBuilder2.war">
<targetMappings xmi:id="DeploymentTargetMapping_1282248412895" target="ServerTarget_1282248412894"/>
<classloader xmi:id="Classloader_1282248412895"/>
</modules>
<properties xmi:id="Property_1282248412894" name="metadata.complete" value="true"/>
</deployedObject>
<deploymentTargets xmi:type="appdeployment:ServerTarget" xmi:id="ServerTarget_1282248412894" name="WebSphere_Portal"
nodeName="localhost"/>
</appdeployment:Deployment>


In this file if you search for binariesUrl you will find the location where this .ear file is actually installed which is ${WPS_HOME}/theme/wp.mashup.cc.theme/installedApps/wp.mashup.cc.theme.ear. So i went to that folder and i could find the source code for PageBuilder2 theme there.

Theme in WPS 7.0

One of the biggest change in the WebSphere Portal Server 7.0 is that it has a new theme called PageBuilder2(CSA2) theme, which has a different architecture that allows you to write theme in .html and use webdav,.. I wanted to learn how this theme works and how different pieces fit together, and these are my notes

Until version 6.1 source code for all the different themes that were shipped with WebSphere portal used to be located in wp_profile/installedApps/localhost/wps.ear/wps.war/themes/html/ directory, so i went to check that directory first and it seems that now that directory is almost empty, this is the default content.



Now it only as Default.jsp and CloseWindow.jsp. If you open the Default.jsp you will notice its much simpler and smaller compared to previous versions and from the comment it looks like this is the fallback minimal version of theme which will get called if your actual theme does not work and it gives you chance to recover.

So i did full export of websphere portal using xmlaccess and searched for <theme> element and i can find 4 theme elements with PageBuilder2 theme set as default theme

<theme action="update" active="true" context-root="/PortalTheme" default="false" defaultskinref="ZK_CGAH47L0085810IAHU76SD20S4"
domain="rel" objectid="ZJ_CGAH47L0085810IAHU76SD20H0" resourceroot="Portal" uniquename="ibm.portal.theme.Portal">
<localedata locale="en">
<title>Portal</title>
</localedata>
<allowed-skin skin="ZK_CGAH47L0085810IAHU76SD20S2" update="set"/>
<allowed-skin skin="ZK_CGAH47L0085810IAHU76SD20S4" update="set"/>
<allowed-skin skin="ZK_CGAH47L0085810IAHU76SD20S6" update="set"/>
<parameter name="com.ibm.portal.theme.hasBaseURL" type="string" update="set"><![CDATA[true]]></parameter>
</theme>

<theme action="update" active="true" context-root="/PageBuilder2" default="true" defaultskinref="ZK_CGAH47L00OES90IAH10FQR3KJ2"
domain="rel" objectid="ZJ_CGAH47L00OES90IAH10FQR3KJ6" resourceroot="PageBuilder2" uniquename="csa2.theme">
<localedata locale="en">
<title>Page Builder</title>
</localedata>
<allowed-skin skin="ZK_CGAH47L0085810IAHU76SD20S5" update="set"/>
<allowed-skin skin="ZK_CGAH47L00OES90IAH10FQR3KJ2" update="set"/>
<parameter name="com.ibm.portal.themetype" type="string" update="set"><![CDATA[CSA2]]></parameter>
<parameter name="theme.capability.dojo" type="string" update="set"><![CDATA[1.4.3]]></parameter>
<parameter name="theme.capability.oneUI" type="string" update="set"><![CDATA[2.1]]></parameter>
<parameter name="com.ibm.portal.layout.template.href" type="string" update="set"><![CDATA[dav:fs-type1/layout-templates/2ColumnEqual/]]></parameter>
<parameter name="theme.capability.mashups.enabler" type="string" update="set"><![CDATA[2.4]]></parameter>
<parameter name="com.ibm.portal.theme.template.ref" type="string" update="set"><![CDATA[dav:fs-type1/themes/PageBuilder2/]]></parameter>
</theme>

<theme action="update" active="true" context-root="/themes" default="false" defaultskinref="ZK_OGFLMKG108IGF0IQCG6O9610O3"
domain="rel" objectid="ZJ_OGFLMKG108IGF0IQCG6O961045" resourceroot="defaultTheme" uniquename="com.ibm.portal.mashup.theme.defaultTheme">
<localedata locale="en">
<title>Breadcrumb - Free Form Layout </title>
<description>Breadcrumb - Free Form Layout</description>
</localedata>
<allowed-skin skin="ZK_OGFLMKG108IGF0IQCG6O9610O1" update="set"/>
<allowed-skin skin="ZK_OGFLMKG108IGF0IQCG6O9610O2" update="set"/>
<allowed-skin skin="ZK_OGFLMKG108IGF0IQCG6O9610O3" update="set"/>
<allowed-skin skin="ZK_OGFLMKG108IGF0IQCG6O9610O4" update="set"/>
<allowed-skin skin="ZK_OGFLMKG108IGF0IQCG6O9610O5" update="set"/>
<allowed-skin skin="ZK_OGFLMKG108IGF0IQCG6O9610O6" update="set"/>
<parameter name="com.ibm.portal.themetype" type="string" update="set"><![CDATA[mashup]]></parameter>
<parameter name="preview-url" type="string" update="set"><![CDATA[preview.png]]></parameter>
<parameter name="com.ibm.portal.themestructure" type="string" update="set"><![CDATA[mashup]]></parameter>
<parameter name="com.ibm.mashups.theme.body.class" type="string" update="set"><![CDATA[mashups]]></parameter>
</theme>
<theme action="update" active="true" context-root="/themes" default="false" defaultskinref="ZK_OGFLMKG108IGF0IQCG6O961041" domain="rel"
objectid="ZJ_OGFLMKG108IGF0IQCG6O961043" resourceroot="defaultThemeColumned" uniquename="com.ibm.portal.mashup.theme.defaultThemeColumned">
<localedata locale="en">
<title>Breadcrumb - Column Layout</title>
<description>Breadcrumb - Column Layout</description>
</localedata>
<allowed-skin skin="ZK_OGFLMKG108IGF0IQCG6O961040" update="set"/>
<allowed-skin skin="ZK_OGFLMKG108IGF0IQCG6O961041" update="set"/>
<allowed-skin skin="ZK_OGFLMKG108IGF0IQCG6O961042" update="set"/>
<allowed-skin skin="ZK_OGFLMKG108IGF0IQCG6O961044" update="set"/>
<allowed-skin skin="ZK_OGFLMKG108IGF0IQCG6O961046" update="set"/>
<allowed-skin skin="ZK_OGFLMKG108IGF0IQCG6O9610O7" update="set"/>
<parameter name="com.ibm.portal.themetype" type="string" update="set"><![CDATA[mashup]]></parameter>
<parameter name="preview-url" type="string" update="set"><![CDATA[preview.png]]></parameter>
<parameter name="com.ibm.portal.themestructure" type="string" update="set"><![CDATA[mashup]]></parameter>
<parameter name="com.ibm.mashups.theme.body.class" type="string" update="set"><![CDATA[mashups]]></parameter>
</theme>


The xmlaccess export of the portal has 4 themes

  1. Portal

  2. PageBuilder

  3. Breadcrumb - Free Form Layout

  4. Breadcrumb - Column Layout



But if you login into WPS admin console and go to Themes and Skins portlet you will notice that it displays only 2 themes one is Portal and other is Page Builder. Also when you try to change theme of your portal page you will see only these two themes there. I guess the themes with themetype equal to mashup cannot be applied to page and it does not show up in the Theme and skin portlet



It looks like the WPS 7.0 makes use of packaging theme in separate ear concept that was introduced in the WPS 6.1. The source code for theme is distributed in 3 separate .ear files. This the mapping for the theme name to the context root.


  1. Portal -> /PortalTheme

  2. Page Builder -> /PageBuilder2

  3. Breadcrumb - Free Form Layout -> /themes

  4. Breadcrumb - Column Layout -> /themes



Also it seems that the source code for the theme is distributed at different locations and all of them are installed inside PortalServer directory which is a read only directory.

  • Portal : ${WPS_HOME}/installer/wp.ear/installableApps/wps_theme.ear

  • Page Builder : ${WPS_HOME}/theme/wp.mashup.cc.theme/installedApps/wp.mashup.cc.theme.ear

  • Breadcrumb - Free Form Layout : ${WPS_HOME}/base/wp.mmi.deploy/installedApps/MashupMaker_Integration.ear/theme.war

  • Breadcrumb - Column Layout : ${WPS_HOME}/base/wp.mmi.deploy/installedApps/MashupMaker_Integration.ear/theme.war

How to configure WebDav connection in Linux

In the Using WebDav to work with theme in WPS 7 entry you can find details about how to configure a WebDav client on Windows. But i use CentOS on my development machine and i wanted to figure out how to connect to the WebDav server on Linux machine.

It turns on the Nautilus file explorer that i use on my Linux box has native support for connecting to WebDav and its more easier to user then the couple of windows based options

In the Nautilus file explorer click on File -< Connect to Server like this


It will open a Connect to server dialog box, where you can provide details for connecting to the WebDav server like this



Once click on Connect it will ask you for the password and once you provide the password it will connect to server and show the webdav folder like normal file system folder. It will also add this webdav connection in the left hand palette like this. Now your free to navigate in the WebDav folder and work with files like any normal file system files



I used wasadmin as connection name and the themes/PageBuilder2 is the WebDav folder

PageBuilder2 theme in WebSphere Portal 7.0

WebSphere Portal 7 provides improved page builder and improved client side rendering and has a new default portal theme, the Page Builder theme. Themes define how your portal site will look. After installation, a default theme is deployed and you can either customize that theme or create your own. The new themes approach introduced in 7 involves less editing of JSPs and allows you to mix iWidgets and portlets on the same portal page and take advantage of both client side and server side rendering mode. WebSphere Portal 7 continues to support other themes, including your custom themes. If you have an existing portal site you can continue to use your existing themes or you can migrate your themes to the new standard.

These are some of the main points about the new Page Builder theme

  • Static pages use plain HTML. This can include placeholders for dynamic content, such as portlets or iWidgets. You can create and edit static pages by using an HTML editor tool of your choice.

  • The Page Builder theme allows you to render and edit static pages that which include portlets and iWidgets. The theme allows you for each page to configure whether that page is rendered in client side aggregation mode, or in server side aggregation mode. Users with editor rights on the page can toggle pages between client side and server side mode. The Page Builder theme consists of a plain HTML file. You can customize it by using a HTML editor tool of your choice. The portal provides several include files that you can use to add the logic for starting and editing the page.

  • You can use portlets and iWidgets to add application logic to a static page. JSR168 and 286 define the standard for portlets, and the iWidget specification 2.0 defines iWidgets. Both portlets and iWidgets are self-contained pieces of application logic that you can develop, deploy, and use in a flexible manner. You need to distinguish between the types of code and its execution:

    1. Portlets are written as Java code. They are designed to be executed in a portlet container on the server side. If they are rendered by client side execution instead, the portal translates them into iWidgets markup that can be executed in the browser.

    2. iWidgets are written as Javascript logic. They are designed to be executed in the browser on the client side. For server side execution the portal wraps iWidgets into portlets.



Lotus OneUi

The WebSphere Portal 7.0 theme makes use of Lotus OneUi for look and feel. The Lotus OneUi enables a common look and feel and a common code base for Lotus web applications. The goal is to remove arbitrary differences between products thereby improving ease-of-use and making it easier to customize products when deployed in an enterprise.



These are the advantages of using Lotus One ui

  • vision issues - it is developed to work well in screen readers, for adjusting text sizes, and to work in high contrast mode.

  • keyboard accessibility - where we have hover effects, we also provide focus effects or equivalent facilitation.

  • The code base is themeable. Customers can easily modify colors and background images using industry standard CSS techniques.

  • Products ship CSS and images used for theming separate from other CSS so it is easier to find the files that apply the theme.

  • IBM's product user interfaces are usually localized to multiple languages. We keep our components fluid so they can handle varying-sized text strings.

  • The code is tested in right-to-left languages. Making our UI work correctly in right-to-left languages sometimes influences how we code our HTML components (browser support of bi-directionality can be buggy).

  • The code base is tested for stability, accessibility, and bi-directionality in multiple browsers. Rendering of the UI across browsers is not always pixel-perfect, but the goal is for it to be as identical as is possible.