Create New Skin in Portal

Creating a Skin that supports Client-Side Aggregation

Skins in client-side aggregation are different from traditional Portal skins in that all the rendering is performed on the client. A CSA skin consists of two parts: a javascript controller and a renderer. Typically, the renderer is an XSL which is applied to the XML returned from the Portal REST services.

Controller


The controller is responsible for responding to all user interactions. It must define the following functions (at the very least):

  • instance
  • destroy
  • renderSkin
  • updateSkin
  • getActiveDiv

Refer to the attached CSASkinCodeExamples.pdf for a controller example.

Renderer


The most common selection for the renderer will be an XSL transformation. Both the provided samples use XSL transformations to create the markup for the skin. These are packaged with the theme and registered in the theme's bootstrap function. The markup produced by the renderer will be inserted into the page's markup and should be designed with that knowledge in mind. Essentially, the markup produced by the renderer needs to be self contained.

Refer to the attached CSASkinCodeExamples.pdf for examples of XSL and XML instances.

Packaging a skin that supports client-side aggregation
The CSA skins are packaged differently from traditional server side skins. The packaging is very flexible; it is up to the theme to set all the correct paths. Usually, the XSL (renderer) is packaged with the theme (in the PortalWeb2 theme, all the xsl files are in the xsl subdirectory), but can be packaged anywhere that is url addressable. The js controller can also be packaged anywhere that is url addressable. All skins must be registered both in Themes & Skins portlet, but also in the boostrap function in the CSA-enabled theme (PortalWeb2 is the sample CSA-enabled theme).

The function signature to register a skin is:

addSkin:
function ( /*Skin*/ skinTemplate, /*Boolean*/isDefault ) {
// summary: Registers a new skin for use in rendering the page.
// description: Adds the skinTemplate to the Page object for use
// in rendering. The Page object stores an associative array
// of skin templates, and a reference to the default skin to
// use if one is not specified for the portlet. There is one
// tempate object for each 'skin', but a factory method:
// skinTemplate.instance(fullPortletId) is used to create an
// actual skin for a specific portlet.
// skinTemplate: com.ibm.portal.aggregation.Skin - the skin template object.
// isDefault: Boolean - whether the skin should be registered as the default for the theme.

}


In head_extras.jspf, the skins are registered by the following lines in the bootstrap function:
portalAggregator.page.addSkin(new com.ibm.portal.aggregation.IbmSkin("IBM",skinResourceRoot2Id["IBM"],""),true);
portalAggregator.page.addSkin(new com.ibm.portal.aggregation.Skin("NoSkin",skinResourceRoot2Id["NoSkin"],""),false);
portalAggregator.page.addSkin(new com.ibm.portal.aggregation.Skin("ThinSkin",skinResourceRoot2Id["ThinSkin"],""),false);

To add a new skin, simply replace the values with the values appropriate to the new skin. For example, to add a new skin called “FunSkin” that is packaged in the xsl subdirectory of the PortalWeb2 theme:

portalAggregator.page.addSkin(new FunSkin("FunSkin",skinResourceRoot2Id["FunSkin"],""),false);

Lifecycle of a skin that supports client-side aggregation
The IBM and NoSkin CSA skins are provided as samples. The basic lifecycle of a skin behaves as follows:

1. The page layout is retrieved and processed. All portlets on the page are extracted from the layout xml.
2. The assigned skin is read and a new instance of the skin controller class is created by calling the instance function.
3. The skin is rendered by calling renderSkin. This happens once per lifecycle and basically just renders the initial skin markup.
4. getActiveDiv is called and the portlet markup is inserted in to the active div returned by the skin controller.
5. When the user navigates away from the page with the current portlet and skin, destroy is called.

0 comments: