One More Think About Inline Editing with WLP 10.3.2 Content Templates

In Inline Editing with WLP 10.3.2 Content Templates, I concluded that if something else came up I would blog it. Well, it did, so I will.

The shared library part went nice and smooth. To note the (semi-)obvious, the wlp-template-config.xml changes noted in the post must be done in the consuming application, not the shared application, as the consuming application always over-rides.

The part I forgot about was that you must create a role for editing the content or else only Admins will be able to do the inline editing.  I created an enterprise role named “homePageContentAdmin” for my first test, then granted that role update privelages on the content item. Once I did that, it worked properly.

As another sort-of-obvious note, this requires granting view privelages for anonymous or authenticated roles for other users to view the content.

If you found this interesting, please share.

© Scott S. Nelson

Catching the Un-Catchable

I know it is bad practice to catch java.lang.NoClassDefFoundError.  Today, however, I did need a way to deal with it because I have this annoying habit of wanting everything else to work even when some non-critical piece is broken.

This case was a matter of a third-party security jar that would throw up rather than out when it could not find its properties file. No matter how many catches I had wrapped around the call to the method in the jar, the java.lang.NoClassDefFoundError would bubble up as a big render issue in the JSP.  I am only using this jar to get the user display name, so it isn’t like my application is not secure if I don’t have their name to make them feel special.

After several annoying and pointless approaches, I came up with the following (ugly-but-effective) solution:

try //the Security class relies on this property file but pukes if not found, 
    //so we test for it here
{
   FileInputStream in = new FileInputStream("security.properties");
   in.close();
}
catch(Exception e)
{
   System.out.println("security.properties is missing from classpath");
   return personInfo;
}
//...go use the third-party class that depends on the file having proven it is there

This allowed the application to continue running and not falling apart at the header just because one file was missing. It is one thing to have a bug that is minor, another when that bug becomes something that users pick up the phone about.

If you found this interesting, please share.

© Scott S. Nelson

Inline Editing with WLP 10.3.2 Content Templates

Carrying on from WLP Content Presenter Portlet Simplified, the next goal is to get the in-line editing from the sample application running because most clients think that is a cool feature and don’t understand why it isn’t available by default. Right now I am almost done, and wanted to blog the progress to date, even if the most important part won’t be done until Monday…

There is a really (really, really) brief instruction in the official documentation to do this here.  I’m sure if you have been building content templates for years that document will be enough, just as I’m sure that if that were the case you won’t be reading this (unless to make tsk-tsk noises at my ignorance). The files to import can be taken straight from there, which is:

Display Template (Outer Template) – <WLPORTAL_HOME>samplesapplicationsportalApp contentPresenterSampleWebsamplePresenterTemplates inlineEditExamplePresenterTemplate.jsp
CM Display Template (Inner Template) That Displays the Content – <WLPORTAL_HOME>samplesapplicationsportalAppcontentPresenterSampleWebsampleCMTemplatesinlineEditExampleCMTemplate.jsp
JSP File that Performs Other Work – <WLPORTAL_HOME>samplesapplicationsportalAppcontentPresenterSampleWebsampleCMTemplatessaveNode.jsp

Now, the first time I tried this, I wanted my own paths and renamed everything. It didn’t work. I’m sure I can rename them now, but at this stage the important thing is to get it working, with re-branding to the custom project being secondary.

The next step is to add these to the wlp-template-config.xml. Where the manual tells you to make your own, I find it much easier to simply go to the merged view and copy in the one from the shared install. While this may make a little more work for future WLP upgrading, it is worth it to me to save the time. With the file now in my project, I get the copy from the sample application and added the nodes to my own application that reference the files imported earlier. The relevant parts of the resulting file are…

Under <content-name-space><name>wlp-content-presenter-single</name>:

<content-resource>
   <name>htmlContent</name>
   <default-template-uri>/portlets/wlp-content-publisher/templates/wlp-default/cm/wlp-default-resourceDefault.jsp</default-template-uri>
   <view>
      <name>Show</name>
      <description>This is the detailed node view for simple HTML content in the Avitek Financial Intranet sample.</description>
         <uri>/sampleCMTemplates/simpleShowView.jsp</uri>
   </view>
   <view>
      <name>ShowEdit</name>
      <description>This is the detailed node view with inline editing for simple HTML content in the Avitek Financial Intranet sample.</description>
      <uri>/sampleCMTemplates/inlineEditExampleCMTemplate.jsp</uri>
   </view>
</content-resource>

Under <template-name-space><name>wlp-content-presenter-single</name>:

<view>
   <name>Sample Single Item View with Inline Edit</name>
   <description>This is the sample Content Presenter Display Template view for a single item that provides inline HTML editing.</description>
   <uri>/samplePresenterTemplates/inlineEditExamplePresenterTemplate.jsp</uri>
</view>

Now, for this to work, you have to create a content type of named “htmlContent”. I created this type with no parent and a primary property named “content” of data type binary.

I’m still testing to find out if the content needs to include “.html” as a suffix to the name.  And, yes, you can by-pass much of this “have to” stuff if you re-write everything, but the goal here is to get it deployed and have business users editing content today 🙂

I thought I had it with that, as I could then set the content in an instance of the Content Presenter portlet as a piece of content of the type htmlContent and see the Edit HTML button, but nothing happened on clicking it. Dang! Running it in FireFox (the project was targeted at IE, otherwise I would have started in FireFox), I found the disconcerting message “wlp dojo is not defined”.

Ok, I haven’t used the Dojo tookit yet. I have been building stuff by hand for so long, I just haven’t had the need to use a pre-built JS framework, even one that is as highly praised as Dojo. So I’m not sure if I went about it the best way to get this fixed, but it was the fastest. I searched through the sample directory until I found dojo.js (in Windows, it was located at

[WEBLOGIC_HOME]wlportal_10.3samplesdomainsportalserversportalServertmp_WL_userportalApp4ycmg9beaextdojo-0.4.3-ajax ). I also found that in inlineEditExampleCMTemplate.jsp, the path it was looking for was ${pageContext.request.contextPath}/dojo-0.4.3-ajax/dojo.js.

I tried importing it directly to my project from OPOE, but it must be compressed or the path is too long, so I did a copy/paste to a temp directory and imported it from there.

And, viola! It worked.

Now all that is left is to make the web project into a shared library so that I don’t have to turn off validation is my “real” project. If there is anything out of the ordinary with that process I will blog about it here.  Otherwise, go forth and edit.

If you found this interesting, please share.

© Scott S. Nelson

REST Logout for WLP with JSP 2.0 EL

I used to create the log out URL like this:

String    webAppName    = request.getRequestURI().substring(1);
String    webAppPath    = request.getRequestURL().substring(0, request.getRequestURL().indexOf(webAppName));
String    restLogout    = webAppPath+webAppName.substring(0, webAppName.indexOf(‘/’))+”/bea/wlp/api/logout?invalidate_session=true”;

Then, today I needed to have it in a Bighorn skeleton, so I came up with the following:

<c:set var=”webAppName” value=”${fn:substring(pageContext.request.requestURI, 1, fn:length(pageContext.request.requestURI))}” scope=”application” />
<c:set var=”webAppPath” value=”${fn:substring(pageContext.request.requestURL, 0, fn:indexOf(pageContext.request.requestURL, webAppName))}” scope=”application” />
<c:set var=”restLogout” value=”${webAppPath}${fn:substring(webAppName, 0, fn:indexOf(webAppName, ‘/’))}/bea/wlp/api/logout?invalidate_session=true” scope=”application” />

With the URL in hand, you can now make the logout call:

function portalLogOut(restURL)
{
var xmlhttp    = null;
if (window.XMLHttpRequest)// code for IE7, Firefox, Mozilla, etc.
{
xmlhttp=new XMLHttpRequest();
}
else if (window.ActiveXObject)// code for IE5, IE6
{
xmlhttp=new ActiveXObject(“Microsoft.XMLHTTP”);
}

if(xmlhttp.overrideMimeType)xmlhttp.overrideMimeType(‘text/xml’);
if (xmlhttp!=null)
{
xmlhttp.open(“POST”,restURL,true);
xmlhttp.send(null);
}
}

If you found this interesting, please share.

© Scott S. Nelson