Skip to main content link. Accesskey S
  • Log In
  • Help
  • IBM Logo
  • WebSphere Portal Family wiki
  • All Wikis
  • All Forums
  • Home
  • Product Documentation
  • Community Articles
  • Learning Center
  • IBM Redbooks
Community Articles Product Documentation Learning Center IBM Redbooks This category IBM Redbooks: Building a Sample Website Using IBM Web Content Manager 7.0 IBM Redbooks: Building and Implementing a Social Portal IBM Redbooks: Developing Exceptional Multi-Channel Web Experiences V7: IBM Web Content Manager Product Documentation V7: IBM WebSphere Portal Enable for z/OS Product Documentation V7: IBM WebSphere Portal Express Product Documentation V7: WebSphere Portal Product Documentation V8: IBM Web Content Manager Product Documentation V8: IBM WebSphere Portal Express Product Documentation V8: IBM WebSphere Portal Product Documentation (includes z/OS) Custom Search Scope...
Search
  • New Article
  • Share Show Menu▼
  • Subscribe Show Menu▼

About the Original Author

Richard Gorzela
Contribution Summary:
  • Articles authored: 1
  • Articles edited: 0
  • Comments Posted: 0

Recent articles by this author

Implementing IBM Lotus Web Content Management bookmark portlets on multiple pages

Implementing IBM® Lotus® Web Content Management bookmark portlets is, in itself, a straightforward process. However, this article describes an implementation whereby the portlets can be on many pages, which means it is important to design bookmark portlets that render efficiently. ...

Community articleImplementing IBM Lotus Web Content Management bookmark portlets on multiple pages

Added by Richard Gorzela | Edited by IBM contributor Leslie Gallo on March 2, 2010 | Version 9
expanded Abstract
collapsed Abstract
No abstract provided.
Tags: WCM, bookmark, portlets
ShowTable of Contents
HideTable of Contents
    • 0.1 Summary
    • 0.2 Contents
  • 1  Introduction
  • 2 Persistence
    • 2.1 Portlet preferences
    • 2.2 Custom database
    • 2.3 Taxonomy element
    • 2.4 Web Content Management site areas
    • 2.5 Property extension database
  • 3 In memory storage
  • 4 Updating bookmarks
    • 4.1 Delete action
    • 4.2 Save action
    • 4.3 Alternative using the PUMA REST API
  • 5 Rendering detailed listing portlets
  • 6 Conclusion
  • 7 Resources
  • 8 About the author

Summary


Implementing IBM® Lotus® Web Content Management bookmark portlets is, in
itself, a straightforward process. However, this article describes an implementation whereby
the portlets can be on many pages, which means it is important to design bookmark portlets
that render efficiently.
 

Contents


1 Introduction
2 Persistence
2.1 Portlet preferences
2.2 Custom database
2.3 Taxonomy element
2.4 Web Content Management site areas
2.5 Property extension database
3 In-memory storage
3.1 Rendering the bookmark portlets
4 Updating bookmarks
4.1 Delete action
4.2 Save action
4.3 Alternative using the PUMA REST API
5 Rendering detailed listing portlets
6 Conclusion
7 Resources


 Introduction


This document discusses a design approach for supporting Lotus Web Content Management (hereafter called “Web Content Management”) bookmarks portlets that was derived from customer requirements. To get the most from this article, you should have knowledge of IBM WebSphere® Portal, Web Content Management, and writing custom portlets.

Consider a simplified version of a bookmarks portlet, My Favorites, which provides a list of favorite articles for a specific user (see figure 1). The articles are stored in Web Content Management, and clicking on one of the items navigates the user to the detailed rendering of the article.

Figure 1. Bookmarks portlet



There are other variations of this list, for example, a list of graphics or charts, or a list of categories. In the case of categories, clicking on one of the items navigates the user to a list of recent articles for the category.

In these kinds of portlets, if there are many items in the list, you may also have the option of clicking the View All link to get a detailed list of the bookmarked items. You can also delete items from this list, indicated by the 'X' by each item.

So far this is standard fare. But what if one of the requirements from a customer were that these portlets are to be rendered on most pages? In that case, it would be important to carefully consider rendering performance.

The approach described here was designed to meet the specific requirements of portlets that could be placed on most pages and deliver information specific to the user. We describe not only this customer-derived approach but also some alternatives that can be applicable to other applications with similar requirements.

We'll cover the following design aspects in the remainder of this document:
  • Persistence– how to store the bookmark data.
  • In-memory storage– how not to always go back to the persistent store.
  • Rendering book marks– how to retrieve and render the bookmarks.
  • Updating bookmarks– how to add and remove bookmarks.
  • Rendering detailed bookmark listings – how to not only retrieve and render the bookmarks, but also to include detailed information about the content.

Persistence


One of the important decisions to make is how to store the bookmarks. This is key because it can impact performance significantly. The information that needs to be stored for each bookmark is as follows:

My Favorites
  • Display title
  • Web Content Management content name and path (to pass as WCM_GLOBAL_CONTEXT value)
  • Web Content Management Document ID (for verification)
  • Alternatively, a link to a thumbnail image

A favorite categories portlet would require the category name to be stored rather than content name and path.

Table 1 summarizes the persistence approaches for bookmark data along with their pros and cons, followed by more detailed descriptions of each. The rest of this article assumes the Property extension database approach, listed last.

Table 1. Summary of persistence approache
Persistence approach
Pros
Cons
Portlet preferences
  • Known paradigm for bookmarks,
  • Possible re-use of existing bookmark portlet source
  • Cannot render the bookmarks on multiple pages
  • Custom development
Custom database
Flexibility
Custom development
Web Content Management taxonomy element
Ease of development
May not have the necessary flexibility,depending on requirements
Web Content Management site areas
Ease of development
Possibly performance
Property extension database
  • Performance
  • Flexibility
  • Built-in mechanism to optionally load values into memory on login
Custom development


Portlet preferences


Portlet preferences is a natural approach to consider for this portlet. For one thing, there already exists an out-of-the-box bookmark portlet that uses this approach, and at first glance it makes a lot of sense since the preferences can be stored per user.

However, a down side to this approach for our requirements is that the portlet preferences are stored per page, and we want the same list to render on all pages that the portlets are on. There are methods to address this issue.

For example, it is possible to modify the portlet palette (“flyout” on the right in the theme) to render portlets, and to have the palette open by default. Since the palette is an i-frame to a portal page, it looks to the user like it is part of the page. And from a portlet preferences point of view, it is the same portal page no matter where the user navigates in the site with the modified theme.

Since it is the same portal page, the portlet preferences will show the same list to the user on all pages to which they navigate. The steps to modify the portlet palette toachieve this are not currently documented, and it is not a straightforward process since there is a tight coupling between the portlets on the palette and the theme.

Another down side to this approach is that the detailed listing portlets also need to know the bookmarks. There are ways retrieve the preferences from another portlet, but it is not a typically portlet paradigm.

Custom database


A custom database can certainly be used to implement the bookmarks, and it offers the most flexibility; however, the down side is that it probably requires the most development work since a persistence API layer is needed. Also, custom deployment needs to be addressed for creating the tables.

A related approach is to build a custom WebSphere Portal personalization (PZN) resource collection to the database tables. The advantage is that you can use some out-of-the-box capabilities such as applying PZN rules and IBM Rational Application Development for WebSphere Software (RAD) wizard tooling.

Performance would need to be verified, however, because this would be a “highly personalized” use of PZN rules, and not a typical a use of PZN engine. In other words, the information rendered would be specific to the user and rendered on many pages.

In either approach, cleanup of user data would need to be addressed as users are deleted from the system over time.

Taxonomy element


The Web Content Management taxonomy element may apply to the general concept of My Favorite Categories, and this may be a good option for some users for that particular portlet. However, some of the requirements we needed to address for our customer made the application of the taxonomy element not straightforward or comprehensive.

Web Content Management site areas


You can use Web Content Management content items to store the user bookmarks; for example, you could have a site area per user in a special library. The site area could contain content links to the bookmarks articles and charts (though this approach would not work for My Favorite Categories).

The advantage of this approach is that development time should be much faster since you could take advantage of components such as menus and navigators.

The down side is that performance may not be as good as other approaches since the information rendered is specific to each user on many pages. This is a different use case from the typical ones for which Web Content Management and its caching is intended.

As with the custom database option, cleanup of user data would need to be addressed as users are deleted from the system.

Property extension database


The approach assumed in this article is to use the WebSphere Portal property extension database (look-aside). Property extensions allow attributes to be associated with users and groups without the need to modify the LDAP. For further information, refer to the WebSphere Portal Information Center topic, “Configuring a property extension database on Linux.”

At the beginning of this section we listed the specific data that needs to be stored. You might have thought we could just store the Web Content Management document ID, and retrieve everything else from there.

The concern with that approach, however, is that it would require Web Content Management lookups of information to create the links, a potentially slow step that would be repeated in a similar way for each portlet on each page. This can hinder performance since these bookmarks are specific to the user.

We decided to store the minimum we needed to render the links, as well as storing the document ID for verification purposes.

One of our assumptions is that content is not deleted or expired, so we don't need to be concerned about broken references to content. If that assumption is not for you, then you will need to handle the case of broken references to content. Even with this assumption, though, display titles can still change, so some mechanism must be in place to periodically update the display titles. This can be done, for example, via:
  • a custom log-in method, or
  • checking/refreshing once during a user session and marking that the check has been completed on a session attribute, or
  • a background task

The periodic checks and refreshes may be slow at first, but subsequent renderings should be much faster.

All data types are multi-valued variable-length string properties. The three fields of data for each bookmark (for example, display title, document ID, and path) can be stored as separate properties, but that can make sorting difficult. An alternative is to have one multi-valued field for each bookmark, in which the property value is delimited appropriately.

As users are deleted from the LDAP, the property extension database would also need to be periodically cleaned up.

In memory storage


Since these portlets are rendered on most pages, the associated data will ideally be stored in memory for fast access. Since the WebSphere Portal property extension database has been chosen as the approach, WebSphere Portal User Management can be used for this purpose.

The Puma Store Service contains the configuration settings for Portal User Management. For more information, refer to the Information Center topic, “Portal configuration services.”

The following property configures both the Portal User Management and the PUMA SPI:

store.puma_default.user.base.attributes =

Defines the attribute subset that portal loads during direct user lookups, for example at Login. Attributes that are not defined in this list are loaded by a separate request to the backend user store.



We used this property to indicate that the properties needed for the custom portlets are loaded at login.

===Rendering the bookmark portlets
The bookmark portlets are built as custom JSR 286 portlets (recall figure 1).The portlets use the PUMA Java SPI to retrieve the bookmark data for the logged-in user. The display title and path/name data are retrieved from the property extension database. Using this data the portlets construct and render the appropriate links to the portal pages that render the Web Content Management content details pages.

For more information on using the PUMA Java SPI, see the WebSphere Portal wiki article,
“Developing with the PUMA SPI.”

Listing 1 shows a code snippet demonstrating how to retrieve extension properties using the PUMA Java SPI:

Listing 1. Code to retrieve extension properties

try {
com.ibm.portal.um.PumaProfile pp
= pumaHome.getProfile(request);

com.ibm.portal.um.User currentUser = pp.getCurrentUser();

pp.reload(pp.getCurrentUser());

ArrayList userAttrs = new ArrayList();
userAttrs.add("MyBookmark");

Map userAttrMap = pp.getAttributes(currentUser, userAttrs);

if (userAttrMap != null)
{
java.util.List attrValues
= (java.util.List) userAttrMap.get("MyBookmark");

if (attrValues != null) {

for (Iterator attrValuesItr = attrValues.iterator();
attrValuesItr.hasNext();)
{

render link....

}
}
...

Updating bookmarks


As mentioned above, the “X”'s next to items in the My Favorites portlets specified in the wire frames indicate a UI element that allows an item to be deleted from the user customization data (recall figure 1).

Adding bookmarks for articles is initiated from different portlets. That is, links on article detail pages will initiate the add bookmark requests from a number of Web Content Management rendering portlets. When a bookmark is added, the side portlets must refresh to show the updated list (see figure 2).

Figure 2. Article detail portlet


Delete action


The delete action can be supported by dynamically submitting a form via JavaScript. This action updates the appropriate property extensions via the PUMA Java SPI, removing the corresponding content location, name, and display information.

The page is then refreshed in a traditional server-side manner; that is, by calling the PUMA Java SPI to render the list view.

Listing 2 shows methods that demonstrate removing property extension values with the PUMA Java API:

Listing 2. Removing property extension values
public void removeValue
(ActionRequest request, String AttributeName, String attributeVal)
throws PortletException, java.io.IOException {
try {
List attrValues = new ArrayList();
attrValues.addAll(getMultivalueStringField
(request, AttributeName));
attrValues.remove(attributeVal);
setMultivalueStringField(request, AttributeName,
attrValues);
} catch (PumaAttributeException e) {
throw new PortletException(e);
} catch (PumaModelException e) {
throw new PortletException(e);
} catch (PumaException e) {
throw new PortletException(e);
}
}

private List getMultivalueStringField
(PortletRequest request, String attrName)
throws PumaAttributeException, PumaModelException, PumaException {
PumaProfile profile = pumaHome.getProfile(request);
List attributes = new ArrayList(1);
attributes.add(attrName);

Map userAttribs
= profile.getAttributes
(profile.getCurrentUser(), attributes);

List list =
(List) userAttribs.get(attrName);
return list;
}

private void setMultivalueStringField
(ActionRequest request, String attrName, List attrValues)
throws PumaAttributeException, PumaModelException, PumaException {
PumaProfile profile = pumaHome.getProfile(request);
PumaController controller = pumaHome.getController(request);

Map 
attribMap =
new HashMap ();
attribMap.put(attrName, attrValues);

controller.setAttributes
(profile.getCurrentUser(), attribMap);

}


Here is an example of using JavaScript to dynamically submit a form:

function submitDeleteFavPreferences(bookmarkVal) {
document.setUserPreferenceForm.BookmarkText.value = bookmarkVal;
document.setUserPreferenceFormAction.value = "Delete";
document.setUserPreferenceForm.submit();
}

Client-side approach
Alternatively, the delete action can be implemented as a service with the resource service method of the corresponding portlet. This allows for a dynamic update of the page in a Web 2.0 style with AJAX calls while still using the PUMA Java SPI.

The is the serveResource method profile of the JSR 286 portlet:

public void serveResource(ResourceRequest request, ResourceResponse response) throws PortletException, java.io.IOException

Since this method takes a ResourceRequest parameter and not a ActionRequest, different PUMA methods would be used to update the user property values:

(com.ibm.portal.um.PumaHome)
ctx.lookup(com.ibm.portal.um.PumaHome.JNDI_NAME);

With WebSphere Portal 6.1, the bookmarks can also be updated by calling the PUMA REST API via JavaScript to update the property extension database. See the topic, “Remote PUMA SPI REST Service” in the Information Center for more details. (Section 4.3 below contains an example of calling the PUMA REST API.)

Save action


The save action is initiated from other portlets, most of which are usually Web Content Management local rendering portlets. For example, from a detailed article or chart page, the user can click a button or link to save a bookmark to that article or chart.

The side portlet showing the bookmarks must then be updated, so some form of portlet communication is needed. There are a number of different ways to achieve this (click-to-action live text, events, session sharing, public render parameters, shared JavaScript, and so forth), but since the initiating portlet is an out-of-the-box Web Content Management rendering portlet, the approaches are somewhat limited.

A significant “hook” that the Web Content Management rendering portlet provides is that Web Content Management allows JSP components that can have Java code, HTML, and JavaScript. The approach described here takes advantage of this hook.

Click-to-action live text
Click-to-action (C2A) live text provides loose coupling between portlets that need to communicate, and is also quite flexible with respect to the types of communicating portlets.

The action can be initiated from a Web Content Management rendering portlet (legacy or standard with WebSphere Portal 6.1.5), legacy portlet, standard portlet, themes, or skins. All that is required is a LiveText C2A microformat (see listing 3).

Listing 3. Example of LiveText HTML

[namespace]

[value]


[header_context_menu]



This snippet of HTML can be placed in a Web Content Management JavaServer Pages (JSP) component. For more information on live text, refer to the InfoCenter topic, “Live text for click-to-action.”

The targeted portlet can be any kind of portlet (using HTML forms), a JSR-186 portlet (using cooperative portlet actions), or a JSR-286 portlet (using portlet events). For any kind of portlet you can use an HTML form such as that shown in listing 4.

Listing 4. Example HTML form
e">
[namespace]
an>

[action]

Alternative using the PUMA REST API


An alternative approach is to have the Web Content Management JSP component call the PUMA REST APIs via Asynchronous JavaScript with XML (AJAX) calls. Note, however that the side portlets, or the entire page, would still need to be refreshed to show the updated list.

Listing 5 shows a code snippet showing how JavaScript can be used to call the PUMA REST API to update property extension values.

Listing 5. Using JavaScript to call a PUMA REST API
function addBookmark(bookmarkVal) {

var xmlBody =
" 2009-11-16T15:18:27.747Z "
+" "
+" "
+" "
+" " + bookmarkVal + " "
+"
"
+"
"
+"
"
+" ";
executeBookmarkPostAjaxRequest
("ContentDetailResults",
"/wps/um/secure/currentuser/profile?update=merge",
updateBookmarCallback,
"" + xmlBody);

}

Rendering detailed listing portlets


Sometimes customers require a corresponding detailed listing portlet for My Favorites and My Favorite Categories (these are the portlets to which a user navigates after clicking the View All link in a bookmark portlet.) The View All link takes the user to a detailed listing portlet (sometimes referred to as an index page).

The bookmarks are listed as in the bookmarks portlet, but some additional information for each portlet may also be given, for example, the first one or two lines of the content.

These detailed listing portlets are custom JSR 286 portlets that make PUMA Java SPI calls to look up the user's bookmarks (via document IDs) stored in the property extension database. (See the previous sections for sample Java code to retrieve property extension attributes).

From there the portlet can use the Web Content Management API to find the detailed information for the content to render. For more information on using the Web Content Management API, refer to the InfoCenter topic, “The IBM Lotus Web Content Management API,” and the WebSphere Portal wiki article, “Web Content Management API Best Practices.”

To consolidate the commonality between these detailed listing portlets and the side portlets, we can use the same portlet with a configuration option. The configuration portlet data can be used to specify whether to render listing details or summary information for each portlet copy.

Unfortunately, since Web Content Management menus cannot be used in this case, paging must be addressed programmatically, if the list of bookmarks is to be long.

Conclusion


This article has described an approach for implementing Lotus Web Content Management bookmark portlets whereby the portlets can be on multiple pages. We discussed how to design such portlets, and some alternative approaches, so that they render efficiently. To achieve efficiency with this approach we looked in particular at persistence, in-memory storage, user interactions, and rendering.

Resources


developerWorks Lotus Web Content Management product page:
http://www.ibm.com/developerworks/lotus/products/webcontentmanagement/?S_TACT=105AGX13&S_CMP=LP

developerWorks Lotus Web Content Management forum:
http://www.ibm.com/developerworks/forums/forum.jspa?forumID=452&cat=41&S_TACT=105AGX13&S_CMP=LP

WebSphere Portal and Lotus Web Content Management product documentation:
http://www.ibm.com/developerworks/websphere/zones/portal/proddoc.html?S_TACT=105AGX13&S_CMP=LP


About the author


Richard Gorzela is a Certified IT Specialist with IBM Software Services for Lotus (ISSL), where
he specializes in helping customers be successful with WebSphere Portal, Lotus Web Content
Management, and related assets and products. Prior to joining ISSL, Richard was a member
of the Workplace Portal Lotus and Collaboration product development team.
expanded Attachments (1)
collapsed Attachments (1)
File TypeSizeFile NameCreated On
application/pdf 261 KB WCMBookmarkPortlets.pdf 3/8/10 1:53 PM
expanded Versions (14)
collapsed Versions (14)
Version Comparison     
VersionDateChanged by              Summary of changes
14Mar 8, 2010 6:24:44 PMLeslie Gallo  IBM contributor
13Mar 8, 2010 5:39:01 PMLeslie Gallo  IBM contributor
12Mar 8, 2010 5:27:50 PMLeslie Gallo  IBM contributor
11Mar 8, 2010 2:45:21 PMLeslie Gallo  IBM contributor
10Mar 8, 2010 2:05:40 PMLeslie Gallo  IBM contributor
This version (9)Mar 2, 2010 1:36:44 PMLeslie Gallo  IBM contributor
8Mar 2, 2010 12:57:09 PMLeslie Gallo  IBM contributor
7Mar 2, 2010 12:54:59 PMLeslie Gallo  IBM contributor
6Feb 22, 2010 4:23:14 PMJohn Munnell  IBM contributor
5Feb 22, 2010 4:12:32 PMJohn Munnell  IBM contributor
4Feb 22, 2010 1:07:03 PMJohn Munnell  IBM contributor
3Feb 22, 2010 1:06:06 PMJohn Munnell  IBM contributor
2Feb 22, 2010 1:02:27 PMJohn Munnell  IBM contributor
1Feb 18, 2010 3:39:38 PMRichard Gorzela  IBM contributor
Copy and paste this wiki markup to link to this article from another article in this wiki.
Go ElsewhereStay ConnectedHelpAbout
  • IBM Collaboration Solutions wikis
  • IBM developerWorks
  • IBM Software support
  • Twitter LinkIBMSocialBizUX on Twitter
  • FacebookIBMSocialBizUX on Facebook
  • ForumsLotus product forums
  • BlogsIBM Social Business UX blog
  • Community LinkIBM Collaboration Solutions
  • Wiki Help
  • Forgot user name/password
  • Wiki design feedback
  • Content feedback
  • About the wiki
  • About IBM
  • Privacy
  • Accessibility
  • IBM Terms of use
  • Wiki terms of use