ShowTable of Contents
Introduction
Starting in IBM® WebSphere® Portal version 7, it's possible to allow users to rate and tag items, which includes IBM Web Content Manager (WCM) items. The product documentation topic, "
Adding the inline rating widget to your portal content" provides the steps to enable rating for items within WebSphere Portal.
To leverage the information about rating the WCM items, we provide a custom rendering plugin to display the average rating for a WCM content item. This can be used, for example, within a menu design so you can see what the rating is for a piece of content item.
Creating custom rendering plugin assets
This article was written using IBM Rational® Application Developer (RAD) v8, but it is not necessary to use the same Integrated Development Environment (IDE) to create the custom rendering plugin. If you are using a different IDE, you will know the steps to accomplish the same in the IDE of your choice.
Creating the Web Project
- In RAD, select File --- New --- Other, and then select Dynamic Web Project.
- Click Next, and name the project RatingRenderingPlugin (see figure 1).
- Select WebSphere Portal v7.0 stub as the target runtime, and ensure the Add project to an EAR checkbox is selected.
- Enter RatingRenderingPluginEAR for the name of the EAR project; click Finish.
Figure 1. Dynamic Web Project window

Creating the Package
Now that the project has been created, we will create the package for the custom class:
- Right-click on src directory within the RatingRenderingPlugin, and select New --- Package.
- Enter com.ibm.sample.rendering.plugins.rating and click Finish.
Creating the Class
To do this:
- Right-click on the package that you just created, and select New --- Class.
- In the window that displays (see figure 2), enter RatingRenderingPlugin as the class name.
- In the Interfaces section select com.ibm.workplace.wcm.api.plugin.rendering.RenderingPlugin, and then click Finish.
Figure 2. Java Class window
4. Now enter in the code for the class, copying the code in listing 1 and replacing the contents of the RatingRenderingPlugin class you just created.
Listing 1. Code for the class
package com.ibm.sample.rendering.plugins.rating;
import java.io.Writer;
import java.net.URI;
import java.text.DecimalFormat;
import java.util.Locale;
import com.ibm.portal.ListModel;
import com.ibm.workplace.wcm.api.plugin.rendering.RenderingPlugin;
import com.ibm.workplace.wcm.api.plugin.rendering.RenderingPluginException;
import com.ibm.workplace.wcm.api.plugin.rendering.RenderingPluginModel;
import java.util.*;
import javax.naming.*;
import com.ibm.portal.um.*;
import com.ibm.portal.cp.Constants;
import com.ibm.portal.cp.rating.PortletRatingModelProvider;
import com.ibm.portal.cp.rating.Rating;
import com.ibm.portal.cp.rating.RatingLocator;
import com.ibm.portal.cp.rating.RatingModel;
import com.ibm.portal.cp.rating.RatingModelLocator;
import com.ibm.portal.cp.resources.*;
import com.ibm.portal.cp.tagging.*;
import com.ibm.portal.model.*;
import com.ibm.portal.portletmodel.PortletModel;
import java.util.Locale;
import java.util.logging.Level;
import java.util.logging.Logger;
import com.ibm.portal.portlet.service.PortletServiceHome;
import com.ibm.portal.portlet.service.model.PortletModelProvider;
import javax.portlet.*;
import javax.servlet.ServletRequest;
import com.ibm.portal.ObjectID;
import com.ibm.portal.portletmodel.PortletWindow;
import com.ibm.portal.identification.Identification;
import com.ibm.workplace.wcm.api.exceptions.DocumentIdCreationException;
public class RatingRenderingPlugin implements RenderingPlugin {
private static String plugin_title = "Render Rating Plugin";
private static String plugin_description = "pass URI to render the average rating";
private static String plugin_name = "RenderRatingPlugin";
private static final Logger s_log = Logger
.getLogger(RatingRenderingPlugin.class.getName());
public boolean isShownInAuthoringUI() {
return true;
}
public String getDescription(Locale arg0) {
return plugin_description;
}
public ListModel<Locale> getLocales() {
return null;
}
public String getTitle(Locale arg0) {
return plugin_title;
}
public String getName() {
return plugin_name;
}
public boolean render(RenderingPluginModel rpm)
throws RenderingPluginException {
String uriValue = rpm.getPluginParameters().get("uri").get(0);
if (uriValue != null && !uriValue.equals("")) {
try {
if(s_log.isLoggable(Level.FINEST)) {
s_log.log(Level.FINEST, "retrieving rating for uri"+uriValue);
}
URI theUri = null;
theUri = new URI(uriValue);
ServletRequest request = rpm.getRequest();
final InitialContext context = new InitialContext();
PortletServiceHome psh = (PortletServiceHome) context
.lookup(PortletResourceModelProvider.JNDI_NAME);
PortletRatingModelProvider ratingModelProvider = (PortletRatingModelProvider) psh
.getPortletService(PortletRatingModelProvider.class);
final RatingModel<Rating> rm = ratingModelProvider
.getRatingModel((PortletRequest) request
.getAttribute("javax.portlet.request"),
(PortletResponse) request
.getAttribute("javax.portlet.response"));
final RatingLocator<Rating> rLoc = (RatingLocator<Rating>) rm
.getLocator();
// TODO: add some ordering params as needed
CountableIterablePagedListModel results = rLoc
.findByResourceURI(theUri,
Constants.DEFAULT_ORDERMETRIC,
Constants.DEFAULT_ORDER);
// iterate the results get average
int count = results.size();
int total = 0;
Iterator resultsIterator = results.iterator();
Rating holdingRating = null;
while (resultsIterator.hasNext()) {
holdingRating = (Rating) resultsIterator.next();
total = total + holdingRating.getRating();
}
if(total > 0) {
long averageRating = total / count;
Writer theWriter = rpm.getWriter();
DecimalFormat dec = new DecimalFormat("###.#");
theWriter.write(dec.format(averageRating));
if(s_log.isLoggable(Level.FINEST)) {
s_log.log(Level.FINEST, "total > 0: "+total);
s_log.log(Level.FINEST, "writing: "+dec.format(averageRating));
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
else {
if(s_log.isLoggable(Level.FINEST)) {
s_log.log(Level.FINEST, "no value passed for uri");
}
}
return false;
}
}
Now, the code is relatively straightforward; however, there are a couple of things to note:
- The render method is the method that is invoked when the tag is being processed by WCM. This is where you write to the browser, using the Writer object you retrieve from the RenderingPluginModel.
- The PortletRatingModelProvider is the mechanism through which we retrieve the rating for individual items. To retrieve this item, we first retrieve the PortletServiceHome :
ServletRequest request = rpm.getRequest();
final InitialContext context = new InitialContext();
PortletServiceHome psh = (PortletServiceHome) context.lookup(PortletResourceModelProvider.JNDI_NAME);
5. Next, we retrieve the PortletRatingModelProvider object, using the request object to pull the PortletRequest and PortletResponse objects:
PortletRatingModelProvider ratingModelProvider = (PortletRatingModelProvider) psh.getPortletService(PortletRatingModelProvider.class);
final RatingModel<Rating> rm = ratingModelProvider.getRatingModel((PortletRequest) request.getAttribute("javax.portlet.request"),
(PortletResponse) request.getAttribute("javax.portlet.response"));
final RatingLocator<Rating> rLoc = (RatingLocator<Rating>) rm.getLocator();
6. Finally, we retrieve the ratings for the individual object we're trying to retrieve, based on the value for theUri which has been retrieved from what was passed into the tag:
CountableIterablePagedListModel results = rLoc.findByResourceURI(theUri,Constants.DEFAULT_ORDERMETRIC,Constants.DEFAULT_ORDER);
The rest of the code is just iterating the results and generating the average by dividing the total ratings by the number of ratings.
Creating the plugin.xml
In the RatingRenderingPlugin Web project, in the WebContent/WEB-INF directory, create a plugin.xml file with the following contents:
Listing 2. Contents for plugin.xml file
<?xml version="1.0" encoding="UTF-8"?>
<plugin
id="ratingrendering.plugin"
name="WCM Rating Rendering Plugin"
version="1.0.1"
provider-name="WCM">
<extension point="com.ibm.workplace.wcm.api.RenderingPlugin" id="WCMRatingRenderingPlugin">
<provider class="com.ibm.sample.rendering.plugins.rating.RatingRenderingPlugin"/>
</extension>
</plugin>
Deploying the custom rendering plugin
To deploy the custom application, we need to export it from RAD and then install it into the WebSphere Portal Application Server.
Export the custom application
1. In RAD, right-click the RatingRenderingPlugin project, select Export and, in the wizard, select EAR file (see figure 3).
Figure 3. Select file to export window
2. In the next window (see figure 4), name the file RatingRenderingPluginEAR, select a location to save the file, and leave the defaults as shown in the figure.
Figure 4. EAR Export window

Installing the custom rendering plugin application
In order for the custom rendering plugin to be available to WCM, it must be installed in the WebSphere Application Server:
- Log in to the WebSphere Application Server administrative console.
- Select Applications --- New Application (see figure 5).
Figure 5. New Application
3. Then select New Enterprise Application (see figure 6).
Figure 6. New Enterprise Application
4. Select Local File System, and select the RatingRenderingPluginEAR.ear; click Next.
5. Select Fast Path, then click Next (see figure 7).
Figure 7. Preparing for the application installatino
6. In Step 1 in the Install New Application window (see figure 8), leave all the default values, and click Next. In Step 2, you must map the application to the WebSphere_Portal server. By default, it's mapped to server1.
7. Select your application by clicking the check box, select your server from the list in the Clusters and section, and click Apply and then Next.
Figure 8. Install New Application window
8. On Step 3, Summary, review the values and click Finish. When it's complete, click the Save link (see figure 9).
Figure 9. Click the Save link |
9. Now, ensure the application is started by selecting Applications --- Application Types --- WebSphere enterprise applications (see figure 10).
Figure 10.
10. Filter to find the Rating application: Filter by name R* by clicking the Filter button, entering R* for the Name, and then clicking Go (see figure 11).
Figure 11. Enterprise Applications window
11. Select the application, and click the Start button; the application should now be available.
Referencing the custom rendering plugin
All that remains now is to reference the average rating. In this example, I will be referencing from a presentation template (see listing 3).
Listing 3. Code for referencing
<div id="inlineWidgets">
<div dojoType="com.ibm.widgets.InlineRating"
resourceID="[Property context="current" type="content" format="uri" field="id"]"
resourceTitle="[Property context="current" type="content" field="title"]"
tagScope="all|community|personal|personal_public|personal_private|community_personal_public">
</div>
</div>
<script type="text/javascript">
dojo.addOnLoad(function()
{
dojo.forEach( ["inlineWidgets"], dojo.parser.parse,
dojo.parser);
});
</script>
The average rating: [Plugin:RenderRatingPlugin uri="[Property context='current' type='content' format='uri' field='id']"]
Note that, if you are referencing from a menu or navigator, you would instead use context="autofill". The important piece to note is the Plugin:RenderRatingPlugin, which says we are referencing the custom plugin class that we have created.
Also, the uri="" is what we are passing to the underlying resolve method. From the custom code, you can see where we pull in this value:
String uriValue = rpm.getPluginParameters().get("uri").get(0);
That's the mechanism you will use to pass values into your custom rendering plugins; in this case, this is how we pull the rating from the service for the content.
Conclusion
In this article, we discussed Custom Rendering Plugins, and how to create your own. Also, we showed how it would be possible to not only rate WCM content items, but also create a mechanism for retrieving the average rating for a WCM content item. Finally, we discussed how to merge the two concepts, and create a Custom Rendering Plugin that will display the average rating for a WCM Content item. You can use this information to generate your own Custom Rendering Plugins.
Resources
developerWorks IBM Web Content Manager product page:
http://www.ibm.com/developerworks/lotus/products/webcontentmanager/
developerWorks IBM WebSphere Portal product page:
http://www.ibm.com/developerworks/websphere/zones/portal/
About the author
Christopher Knight is a Software Engineer based at IBM's Durham, NC, facility, where he specializes in working with the WebSphere Portal family of products. He has been working with WCM and PZN for many years. You can reach him at
cmknight@us.ibm.com.