Introduction

There are cases when Anonymous Users should be able to update WCM content, or more specifically parts of content.

For this example, assume a “Comments” section on a piece of content. The idea is that anonymous users can view the content, and use an html form to add their personal comments about the piece of content. The example here is that the content pertains to a product, but this could be anything.

The content when rendered will have a place for a form so that end users can add to the existing comments section:


Important WCM Content pieces

There are several ways that this can be done, including using a JSP component on the content itself, so that the form submits to itself. For simplicity, however, I have separated the content from the JSP that processes the request.

There are 2 separate content concepts being used:

1)The content thats being updated

2)A helper content object that processes the JSP thats used to update the content.

For the helper content object, I did the following:

1)Create a WCM Authoring template that has one JSP component, named JSPComp

2)Create a WCM Presentation Template with the following tag
<Element context=”current” type=”content” key=”JSPComp”/>

3)Create a site area that maps the authoring template to the presentation template

4)Create a piece of content that holds the necessary JSP. Populated the JSP component with the following path:
/jsp/html/updateReviewWork.jsp
The JSP code for updateReviewWork.jsp is detailed below. In for this example, the content I created exists at the following path:
/mycointernetdesign/APITools/APIToolsSiteArea/updateReviewWork.jsp
Where mycointernetdesign is the library, APITools/APIToolsSiteArea the site/site area path, and updateReviewWork.jsp is the name of the content

In the content thats being updated, in order to provide the functionality, I did the following:

1)Edited the Authoring Template for the content, and added a JSP component named JSPComp. In the Authoring Template directly, populated this with the path /jsp/html/updateProductReviews.jsp. The code for the updateProductReviews.jsp JSP will be given later.

2)Applied the authoring template to all the content

3)Updated the presentation template with an <Element contect=”current” type=”Content” key=”JSPComp”/<br>

4)The end result is that when the content is rendered, the JSP component jsp will be rendered as well.

Code for updateProductReviews.jsp

The updateProductReviews.jsp is very simple. All it does is create an HTML form to capture user input. The only reason a JSP is even used is to retrieve the path to the current content, which we can do using the WCM API

<%@ page import="com.ibm.workplace.wcm.api.*" %>

<%@ page import="com.ibm.workplace.wcm.api.exceptions.*" %>

<%@ page import="java.util.*" %>

<%@ page import="java.io.*" %>

<%

// need to get the current path from the rendering context maybe

RenderingContext renderingContext = (RenderingContext)pageContext.getRequest().getAttribute(Workspace.WCM_RENDERINGCONTEXT_KEY);

String path = renderingContext.getPath();

%>

<head>

</head<title</title<body>

Enter your review:<br>

<form method="post" action="?WCM_GLOBAL_CONTEXT=/mycointernetdesign/APITools/APIToolsSiteArea/updateReviewWork.jsp&path=<%=path%>">

<table>

<tr<td>Name: <input type="textbox" name="newReviewUser"/</td</tr>

<tr<td<textarea id="newReview" name="newReview" rows="5" cols="10" style="width: 100%">

</textarea>

</tr</td</table>

<input type="submit" name="save" value="Submit" />

</form>

</div>

</body>

Everything is pretty straightforward, the trick is here:

<%

// need to get the current path from the rendering context maybe

RenderingContext renderingContext = (RenderingContext)pageContext.getRequest().getAttribute(Workspace.WCM_RENDERINGCONTEXT_KEY);

String path = renderingContext.getPath();

%>

This code retrieves the path to the specific content thats being rendered.

This code:

<form method="post" action="?WCM_GLOBAL_CONTEXT=/mycointernetdesign/APITools/APIToolsSiteArea/updateReviewWork.jsp&path=<%=path%>">

Is basically creating the form action so that the local rendering portlet on the page will be updated to point to the updateReviewWork.jsp content, which is holding a JSP. That JSP is looking for a path parameter to retrieve the sepcific content it needs to update. That path parameter will be pointing to the content that is right now being rendered.

Code for updateReviewWork.jsp

The code for processing the request is just as follows:

<%@ page import="com.ibm.workplace.wcm.api.*" %>

<%@ page import="com.ibm.workplace.wcm.api.exceptions.*" %>

<%@ page import="java.util.*" %>

<%@ page import="java.io.*" %>

<%@ page import="java.lang.*" %>

<%@ page import="javax.servlet.*" %>

<%@ page import="java.security.*" %>

<%@ taglib uri="/WEB-INF/tld/wcm.tld" prefix="wcm"%>

<wcm:initworkspace user="<%= request.getUserPrincipal() %>" />

<%

/*

* This JSP will retrieve the content passed in on the path

* parameter.

* It will then append the value passed in to the HTML component

*/

/* get the path parameter */

String path2 = request.getParameter("path");

// redirect

Principal thisUser = request.getUserPrincipal();

if(thisUser != null) {

%>

<META http-equiv="refresh" content="0;URL= </head>

<%

}

else {

%>

<META http-equiv="refresh" content="0;URL= </head>

<%

}

try {

/* variables */

DocumentIdIterator contentIdIterator = null;

DocumentId contentId = null;

Content currentContent = null;

//Workspace ws = (Workspace) pageContext.getAttribute(Workspace.WCM_WORKSPACE_KEY);

Workspace ws = WCM_API.getRepository().getSystemWorkspace();

/* get the HTML passed */

String newReview = request.getParameter("newReview");

String newReviewUser = request.getParameter("newReviewUser");

/* get the 1st element of the path to get the library name */

String pathFull = request.getParameter("path");

String path = pathFull.substring(1);

int delimEntry = path.indexOf("/");

String libName = path.substring(0,delimEntry);

/* set the library */

ws.setCurrentDocumentLibrary(ws.getDocumentLibrary(libName));

/*

* find content by path

*/

contentIdIterator = ws.findContentByPath(path);

while(contentIdIterator.hasNext()) {

contentId = (DocumentId)contentIdIterator.next();

System.out.println("found content "+contentId.toString());

currentContent = (Content)ws.getById(contentId);

}

/* if the content is not null, get the file component */

if(currentContent != null) {

//out.println(currentContent.getName()+"<br>");

/* now get the current component, append the passed HTML to it and update */

if(newReview != null & !newReview.equals("")) {

HTMLComponent currentReview = (HTMLComponent)currentContent.getComponent("Product Reviews");

String currentReviewValue = currentReview.getHTML();

if(newReviewUser!=null & !newReviewUser.equals("")) {

newReview = newReviewUser +" says...<br>"+ newReview;

}

currentReviewValue+=("<br>"+newReview);

currentReview.setHTML(currentReviewValue);

currentContent.setComponent("Product Reviews",currentReview);

//out.println("saving "+currentContent.getName());

String errors[] = ws.save(currentContent);

for(int x=0;x<errors.length;x++) {

//out.println("error "+errors[x]+"<br>");

}

}

}

}

catch (Exception e)

{

e.printStackTrace();

%>

<%=e.toString()%>

<%

}

%>

At a high level, what happens is:

1)Path is retrieved from the request object

2)System workspace is created

3)Content by the path is retrieved.

4)The component to update is retrieved from the content, and the newly passed comment information is appended to the current value

5)The component is pushed back on the content, and the content is saved.

Note, the meta-equiv code essentially redirects the request back to the content that was being rendered. In my example, thats on a specific WP page, but thats not important.