ShowTable of Contents
Introduction
This article explains, step by step, how to implement a clean-navigation, stateless URL in IBM® WebSphere® Portal-based IBM Web Content ManagerTM (WCM) delivery. This article will be beneficial for customers who want to migrate from WCM servlet-based delivery to Portal-based WCM delivery with the clean URL in mind or who are already on Portal-based WCM delivery and need a clean URL.
Below is a URL showing WCM content “postpaid” in Portal using web-content-viewer portlet.
It is suffixed with long navigational-state-encoded URL and is neither user friendly nor Search Engine Optimization (SEO) friendly.
After our code implementation the above URL will appear as follows:
Implementing the clean URL feature
Implementing clean URL feature for Portal pages having WCM rendering portlets is divided into three parts:
(1) Preparing your Portal for the clean URL.
(2) Implementing the plug-in for the clean URL, in pages that have just WCM rendering portlets on them.
(3) Creating managed pages and WCM artifacts.
Part 1: Preparing Portal for a clean URL
To configure stateless, friendly URLs without state information for your Portal, use the following steps:
1. In the Portal WP Configuration Service, set the custom property friendly.redirect.enabled value to “false”. To do this, edit the Resource Environment Provider (REP) WPConfigService in the WebSphere Integrated Solutions Console. If the property is not listed there, add it, and set it to false (see figure 1).
Figure 1. Set friendly.redirect.enabled property to false
2. In the theme that you want to configure for short stateless URLs, set the com.ibm.portal.theme.hasBaseURL parameter to “true.” You can update the theme parameter by using the XML configuration interface.
Enabling base URLs reduces redirects and URL generation computations, the benefits of which are seen on the default themes shipped with Portal 6.1.5, Portal 7, and Portal 8.0, as well as themes derived from those. To enable Base URLs in themes:
a) Create a file named redirectoff.xml with the contents shown in listing 1:
Listing 1. Contents for redirectoff.xml file
<?xml version="1.0" encoding="UTF-8"?>
<request build="wpnext_372_01" type="update" version="7.0.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="PortalConfig_7.0.0.xsd">
<portal action="locate">
<theme action="update" uniquename="ibm.portal.80Theme"> <parameter name="com.ibm.portal.theme.hasBaseURL" type="string" update="set">true</parameter> </theme>
</portal>
</request>
b) From the command prompt, use the XMLAccess tool to import the following .xml file:
Microsoft® Windows®: xmlaccess.bat -in redirectOff.xml -user <portal adminID> -password <portal admin password> -url http://<hostname>:10039/wps/config.
UNIX®: ./xmlaccess.sh -in redirectOff.xml -user <portal adminID> -password <portal admin password> -url http://<hostname>:10039/wps/config
3. Theme related changes so that generated URLs in the theme do not include the navigational state. In the default Portal 8.0 theme, you can do this by modifying the navigation.jsp file. You must update two copies of this file, one each in the following two directory locations:
PortalServer_root\theme\wp.theme.themes\default80\installedApps\DefaultTheme80.ear\DefaultTheme80.war\themes\html\dynamicSpots
PortalServer_root\theme\wp.theme.modules\webapp\installedApps\ThemeModules.ear\ThemeModules.war\themes\html\dynamicSpots
By default, the JSP files include the code snippet in listing 2.
Listing 2. JSP files' code snippet
<li class="wpthemeNavListItem wpthemeLeft<c:if test="${wp.selectionModel [node] != null}">
wpthemeSelected</c:if>">
<a href="?uri=nm:oid:${nodeID}" class="wpthemeLeft<c:if test="${childrenStatus.count == 1}">
wpthemeFirst</c:if>" <c:if test="${primeNode}">data-nm-level="${level+1}"
data-nm-primed="<portal-fmt:out><portal-core:navigationNodePriming navigationNode="${nodeID}"
metaData="${navHiddenMetadata}" considerChildren="false" includeRoles="true" />
</portal-fmt:out>"</c:if>>
<span lang="${node.title.xmlLocale}" dir="${node.title.direction}">
<c:choose><c:when test="${node.projectID != null}">(<c:out value="${node.title}"/>)
</c:when><c:otherwise><c:out value="${node.title}"/></c:otherwise></c:choose>
<c:if test="${selectedNodeID == nodeID}">
<span class="wpthemeAccess"> <portal-fmt:text key="currently_selected" bundle="nls8.Theme"/>
</span></c:if>
</span></a>
<portal-dynamicui:closePage node="${node}">
<a class="wpthemeClose wpthemeLeft" href="<%closePageURL.write(out);%>">
<img alt="X"
src="${themeConfig ['resources.modules.ibm.contextRoot']}/themes/html/NavigationClose.gif">
</a>
</portal-dynamicui:closePage>
To generate stateless URLs, replace the middle section of this code snippet in the navigation.jsp files with the update shown in listing 3.
Listing 3. Updated code
<li class="wpthemeNavListItem wpthemeLeft<c:if test="${wp.selectionModel [node] != null}">
wpthemeSelected</c:if>">
<portal-navigation:urlGeneration contentNode="${nodeID}" keepNavigationalState="false">
<a href="<%wpsURL.write(out);%>"
class="wpthemeLeft<c:if test="${childrenStatus.count == 1}">
wpthemeFirst"</c:if>" <c:if test="${primeNode}">data-nm-level="${level+1}"
data-nm-primed="<portal-fmt:out><portal-core:navigationNodePriming
navigationNode="${nodeID}" metaData="${navHiddenMetadata}"
considerChildren="false" includeRoles="true" />
</portal-fmt:out>"</c:if>>
<span lang="${node.title.xmlLocale}" dir="${node.title.direction}">
<c:choose><c:when test="${node.projectID != null}">(<c:out value="${node.title}"/>)
</c:when><c:otherwise><c:out value="${node.title}"/></c:otherwise>
</c:choose><c:if test="${selectedNodeID == nodeID}">
<span class="wpthemeAccess"> <portal-fmt:text key="currently_selected" bundle="nls8.Theme"/>
</span></c:if>
</span></a>
</portal-navigation:urlGeneration>
<portal-dynamicui:closePage node="${node}">
<a class="wpthemeClose wpthemeLeft" href="<%closePageURL.write(out);%>">
<img alt="X"
src="${themeConfig ['resources.modules.ibm.contextRoot']}/themes/html/NavigationClose.gif">
</a>
</portal-dynamicui:closePage>
At this point, a friendly URL for Portal starts appearing for you. Click on the Application link on the theme:
Note, however, the URLs for pages containing a WCM rendering portlet still contain navigational state information. Part 2 below addresses generating friendly URLs for pages containing web-content-viewer portlets.
Part 2: Implementing the plugin for the clean URL
This section covers developing a plugin for implementing a clean URL for Portal pages having a web-content-viewer portlet:
1. Open IBM Rational Application Developer (RAD) 8 and create a new Web Project, using File --- New --- Web Project (see figure 2).
Figure 2. Create new RAD Web Project
2. Name the Project “WCMFrndlyURL” (see figure 3).
Figure 3. New Web Project window
3. Create the artifacts in the newly created Web Project, as shown in figure 4.
Figure 4. Create artifacts
(a) Create interface: com.ibm.workplace.wcm.api.samples
(b) Create two JavaTM classes:
● FriendlyUrlGenerationFilterFactory (For more information refer to the product documentation topic, “
Filter factory class.”) The source code for this class is in the attached FriendlyUrlGenerationFilterFactory.txt file. Put this code in the RAD FriendlyUrlGenerationFilterFactory.java file.
● FriendlyUrlGenerationFilter (For more information refer to the product documentation topic, “
Filter class.”) The source code for this class is in the attached FriendlyUrlGenerationFilter.txt file. Put this code in the RAD FriendlyUrlGenerationFilter.java file.
(c) Create a plugin.xml into the WEB-INF folder, using the code in listing 4.
Listing 4. Code to create plugin.xml
<?xml version="1.0" encoding="UTF-8"?>
<plugin id="com.example.content.url" name="Sample content URL generation filter" version="1.0.0" provider-name="IBM">
<extension
point="com.ibm.workplace.wcm.api.ContentUrlGenerationFilter"
id="SampleContentUrlGenerationFilter">
<factory class="com.ibm.workplace.wcm.api.samples.FriendlyUrlGenerationFilterFactory" weight="1"/>
</extension>
</plugin>
Now you are ready with the base artifact to implement code for the WCM friendly URL.
4. Generate the .war file of this project and deploy it in the IBM WebSphere Application Server.
5. Give the context path of this application and then start the application.
Part 3: Creating managed pages and WCM artifacts
To do this:
- Create a Site Area, Authoring Portlet (AT), Presentation Template (PT), and default content for this Site Area.
- Create a Managed Page and give it a friendly name.
- Change newly created Managed Page content association, mapping it to the Site Area created in Step 1.
- Add a web-content-viewer portlet to this page and configure this portlet with the content of newly created Site Area.
- Access the newly created page and check the URL in the browser; it displays as a clean URL.
Conclusion
You should now be able to implement the clean URL feature in WebSphere Portal-based WCM delivery.
Tell us what you think
Please visit this link to take a one-question survey about this article:
Resources
WebSphere Portal product documentation topics:
• Using friendly URLs without state information
• Friendly URL for web content example• Friendly URLs and web content viewers• Example 2: Generate a friendly URL for web contentAbout the author
Amit Pareek is a Staff Software Engineer with IBM Lotus Lab Services, based at IBM's India Software Labs in Pune. He specializes in Enterprise portal and content management solutions, Web 2.0 technology, and Enterprise Collaboration platforms including WebSphere Portal, Web Content Manager, and IBM Lotus Quickr. You can reach him at
ampareek@in.ibm.com.