ShowTable of Contents
Introduction
We have created a JSP before (see Part 1: Full Control Over Markup In WCM While Using JSPs). For other purposes we want to re-use the functionality offered by the JSP (i.e. the JSP delegates generation of the markup to WCM), but simply show a different component. All this should be possible by simply adding flexibility to a single JSP.
The article starts off with the basics (hello World) and then moves on to extend the code from the previous article.
Pre-requisites
- Advanced working knowledge with WCM
- Ability to read Java code
- Working knowledge of IDE (e.g. Rational Software Architect, Eclipse, etc)
- Ability to build, package and deploy code.
Desire
We want to control the behaviour of JSPs by passing in parameters. Such parameters might drive the selection of content to display, the component to render for each result, or a search condition to apply.
Referring to part 1: Full Control Over Markup In WCM While Using JSPs, we take it a step further by making the JSP respond to parameters that we pass into it.
Adding flexibility to JSPs invoked from WCM
Hello, World!
Let’s start from scratch. In its simplest form, the JSP reads a request parameter and displays its value.
<%@page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<% String name = request.getParameter("name"); // get name
if (name==null) name="World"; // assume default value for name when none provided
%>Hello, <%=name %>!
When the EAR file (see below) is deployed and running on WebSphere Portal, you can invoke the JSP by providing its path in a JSP component in WCM. With the chosen context root of “wcmcustom”, the path to the JSP is:
/wcmcustom;/render/helloWorld.jsp
Preview the JSP component to view its output.
Now, you can influence what name is displayed simply by adding a parameter to the query string in the URL. Simply add the query string parameter name=Moon to the URL.
Additionally, you can set parameters by adding parameters to the JSP path in the JSP component.
/wcmcustom;/render/helloWorld.jsp?name=Stars
Preview the JSP again to view the result.
Note: the parameters provided in the JSP component take precedence over the parameters specified in the query string from the URL.
Adding flexibility to an existing JSP
With the basic principle down, you can now add logic to your own JSPs. In the example provided in the previous article , we can replace the static strings defined in the JSP and expect these to be provided as parameters at the time of invocation of the JSP.
JSP code with static values
<%@page import="com.ibm.workplace.wcm.api.*"%>
<%@page import="java.util.*"%>
<%@page import="java.text.*"%>
<%@page trimDirectiveWhitespaces="true"%>
<%@page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<%@page session="false"%>
<%@taglib uri="/WEB-INF/tld/wcm.tld" prefix="wcm"%>
<wcm:initworkspace />
<%--
- Author(s): Maarten Pol
- Date: 24/09/2014
- Description: JSP to invoke a component from WCM for each result in a list (navigator, menu, search results, etc)
- Version History
- 0.1 - September 24, 2014 - Initial version
--%>
<%
final String COMPONENT_NAME = "Menu - Show Responses";
final String DESIGN_LIBRARY_NAME = "Design Library";
// Get the current content item. Please note that getCurrentResultId requires both <wcm:initworkspace />
// and compute="always" in calling the JSP component in the result design for the component
RenderingContext renderingContext = (RenderingContext) request
.getAttribute(Workspace.WCM_RENDERINGCONTEXT_KEY);
DocumentId currentResultId = renderingContext.getCurrentResultId();
Workspace workspace = renderingContext.getContent().getSourceWorkspace();
Content content = (Content) workspace.getById(currentResultId, true, false);
// Get the component to render
DocumentLibrary libDesign = (DocumentLibrary) workspace.getDocumentLibrary(DESIGN_LIBRARY_NAME);
workspace.setCurrentDocumentLibrary(libDesign); // get design library
DocumentIdIterator docIds = workspace.findByName(DocumentTypes.LibraryComponent, COMPONENT_NAME,
Workspace.WORKFLOWSTATUS_PUBLISHED); // find component by name
if (docIds.hasNext()) {
DocumentId docId = (DocumentId) docIds.next();
LibraryComponent libComp = (LibraryComponent) workspace.getById(docId, true, false);
// Set the rendering context to the current item
DocumentId idSA = content.getDirectParent();
SiteArea sa = (SiteArea) workspace.getById(idSA, true, false);
renderingContext.setRenderedContent(content, sa);
// Render the markup
%><%=workspace.render(renderingContext, libComp)%>
<%
}
%>
In the code above, the final string values for COMPONENT_NAME and DESIGN_LIBRARY_NAME can be read from the request. When no value is provided a default value is assumed.
JSP code with flexibility added
<%@page import="com.ibm.workplace.wcm.api.*"%>
<%@page import="java.util.*"%>
<%@page import="java.text.*"%>
<%@page trimDirectiveWhitespaces="true"%>
<%@page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<%@page session="false"%>
<%@taglib uri="/WEB-INF/tld/wcm.tld" prefix="wcm"%>
<wcm:initworkspace />
<%--
- Author(s): Maarten Pol
- Date: 03/03/2015
- Description: JSP to invoke a component from WCM for each result in a list (navigator, menu, search results, etc)
- Version History
- 0.1 - September 24, 2014 - Initial version
- 0.2 - March 3, 2015 - Added flexibility through request parameters
--%>
<%
String componentName = request.getParameter("component"); // get component name
if (componentName==null) componentName="Menu - Show Responses"; // assume default value for component name when none provided
String designLibraryName = request.getParameter("library"); // get design library name
if (designLibraryName==null) designLibraryName="Design Library"; // assume default value for design library name when none provided
// Get the current content item. Please note that getCurrentResultId requires both <wcm:initworkspace />
// and compute="always" in calling the JSP component in the result design for the component
RenderingContext renderingContext = (RenderingContext) request
.getAttribute(Workspace.WCM_RENDERINGCONTEXT_KEY);
DocumentId currentResultId = renderingContext.getCurrentResultId();
Workspace workspace = renderingContext.getContent().getSourceWorkspace();
Content content = (Content) workspace.getById(currentResultId, true, false);
// Get the component to render
DocumentLibrary libDesign = (DocumentLibrary) workspace.getDocumentLibrary(designLibraryName);
workspace.setCurrentDocumentLibrary(libDesign); // get design library
DocumentIdIterator docIds = workspace.findByName(DocumentTypes.LibraryComponent, componentName,
Workspace.WORKFLOWSTATUS_PUBLISHED); // find component by name
if (docIds.hasNext()) {
DocumentId docId = (DocumentId) docIds.next();
LibraryComponent libComp = (LibraryComponent) workspace.getById(docId, true, false);
// Set the rendering context to the current item
DocumentId idSA = content.getDirectParent();
SiteArea sa = (SiteArea) workspace.getById(idSA, true, false);
renderingContext.setRenderedContent(content, sa);
// Render the markup
%><%=workspace.render(renderingContext, libComp)%>
<%
}
%>
Make sure to provide values for the parameters named component and library in the invoking JSP component.
Once you have deployed or updated the provided EAR file, open the JSP component (see part 1 Full Control Over Markup In WCM While Using JSPs) and add parameters to the JSP path:
Change JSP path from:
/wcmcustom;/render/component.jsp
to
/wcmcustom;/render/component.jsp?component=Menu+-+Show+Responses&library=Design+Library
Note: The values of the parameters cannot contain spaces. Replace spaces with + or %20.
View the Blog Landing page. Since we provided the same values as the static values provided before, the page should look exactly the same. However, when you now wish to display different variations of the same page, you can re-use the JSP, simply by providing different parameters.
Other applications
The example above renders components based on parameters passed in to the JSP. When using JSPs to render content, other possible applications of parameters are:
- pass in the name of an element to use for rendering
- pass in the name of the library to retrieve the content from
- pass in the name of the site area to retrieve content from
- pass in filter values to limit the number of results returned (…&filterByType=blog&…)
- pass in tag values to limit the number of results returned (…&tag=audio,recording,mastering&…)
- pass in settings for search methods (AND/OR) (…&searchOperation=AND&…)
- pass in settings for search results ordering (for anything out of the ordinary)
- etc
In addition to rendering, JSPs can also be used in authoring templates to extend the functionality offered by WCM. These JSPs take parameters just as well. Provide the JSP path in the Custom JSP field in the element properties defined in the default content tab of the authoring template. Add parameters to the JSP path. Take into account that you can invoke different JSPs for editing and authoring (see http://www-01.ibm.com/support/knowledgecenter/SSHRKX_8.5.0/help/panel_help/wcm_dev_custom_jsp.dita?lang=en)

Best practices
Make sure to do the following:
- Decide if you need run-time parameters passed in to the JSP
- Determine if parameters can have one or multiple values
- Check any values passed in for validity
- Decide what to do with empty values (e.g. &tag=,&category=product&…)
- Decide on how to handle errors
- Decide on how to handle large amounts of data
- Provide default values for parameters that are omitted in the request
- Keep your JSPs simple; limit complexity for maintenance purposes
Downloads
Download and deploy the updated EAR file provided with this article to get a head start:
Conclusion
Combine passing in parameters from both the JSP Component in WCM and through the query string in the URL in WebSphere Portal for full flexibility in steering the behaviour of your JSPs.