Generating Custom Search SeedList for WCM contents

Scenarios where you need to generate custom XML seedlist (instead of the out of box ATOM search feed) for the third party search engines. Following is one way we can generate custom XML seedlist for all the contents in WCM repository.

Steps
1. Create Menu Component
2. Create JSP Component to access the component outside

Step 1:
Create a Menu Component where settings will be as follows

Search Criteria would
Authoring Template= Select all authoring templates that you use to create content

Header: <custom-metadata>

Design for each menu search result:
<record>
<content-path><PathCmpnt type="noprefixbase"/>/wps/mypoc?urile=wcm:path:<Placeholder tag="sitepath"/></content-path>
<crawlURL><PathCmpnt type="noprefixbase"/>/wps/wcm/connect<Placeholder tag="sitepath"/></crawlURL>
<title><IDCmpnt context="autoFill" type="content" field="title"/></title>
<region><Element context="autoFill" type="content" key="Organization"/></region>
<publish-date><WorkflowCmpnt context="autoFill" type="content" field="publishdate" format="MM/dd/yyyy"/></publish-date>
<keywords><ProfileCmpnt context="autoFill" type="content" field="categories"/></keywords>

</record>

Footer: </custom-metadata>



Step 2:
Write the following code in JSP and place it in External Web Application (use external application for customization for better flexibility)

<%@ page import="com.ibm.workplace.wcm.api.*" %>
<%@ page import="java.util.*" %>
<?xml version="1.0" encoding="UTF-8"?>
<%

String requestedURL= request.getRequestURL().toString();
String contextPath=request.getContextPath();
String baseURL="";
String compName = "MENU-Search-XML";
String html = "";
String libraryName = "";
String sitePath="wcmPath";

libraryName=sitePath.substring(0,sitePath.indexOf("/"));
Workspace workspace = WCM_API.getRepository().getWorkspace(userId, password);
workspace.setCurrentDocumentLibrary(workspace.getDocumentLibrary(libraryName));
DocumentIdIterator docIds=workspace.findByName(DocumentTypes.LibraryComponent,compName);
if (docIds.hasNext()){
    DocumentId did = (DocumentId)docIds.next();
    LibraryComponent libComp = (LibraryComponent)workspace.getById(did);
    RenderingContext rcjsp = (RenderingContext)request.getAttribute(Workspace.WCM_RENDERINGCONTEXT_KEY);
    if(null == rcjsp)rcjsp = workspace.createRenderingContext(request,response,new HashMap(),baseURL,"connect");
    rcjsp.setRenderedContent(sitePath);
    html = workspace.render(rcjsp, libComp);
    out.println(html);
}
%>

Note:
a). If you want expose the component for directly producing the XML seedlist , include following additional information in above menu design

Header Design Component 
<?xml version="1.0" encoding="UTF-8"?>


Use the following link to access your component that produces the seedlist
http://localhost:10041/wps/wcm/myconnect/Library/site/sitearea/?srv=cmpnt&source=library&cmpntname=libraryName/Menu-Search-XML&WCM_Page.ResetAll=TRUE&CACHE=NONE&CONTENTCACHE=NONE&CONNECTORCACHE=NONE

b).  Make sure that your JSP (if you write JSP to produce XML seedlist) will return response MIME type as "text/XML" instead of "text/HTML". Place following line in JSP at top to return MIME type as XML.
<?xml version="1.0" encoding="UTF-8"?>

Lotus WCM Personalization Component Retrieving Results based on current SiteArea - Personalization Componet with current sitearea

Usecase
There are scenarios where same personalization component should behave or display results based on the current SiteArea context.

I have couple of Portal pages with News portlet on it (Web content viewer portlet pointing to different news siteareas), I mean Web Content Viewer portlet on the HR page is pointing to HR news ...etc.

Following is one way you can pass the current sitearea context to personalization component.

1. Create JSP component to retrieve the current rendering sitearea path
2. Create Personalization component that uses the sitearea path
3. Create Presentation Template to refer to JSP component and Personalization Component

Step 1: Create JSP component with following code to retrieve the  current sitearea path

<%@ taglib uri="/WEB-INF/tld/wcm.tld" prefix="wcm" %>
<%@ page import="com.ibm.workplace.wcm.api.*" %>

<!--<wcm:initworkspace user="<%=(java.security.Principal)request.getUserPrincipal()%>">Cannot get Workspace</wcm:initworkspace>-->
<wcm:initworkspace username="wpsadmin" password="wpsadmin" >Cannot get Workspace</wcm:initworkspace>
<%RenderingContext context = (RenderingContext)request.getAttribute(Workspace.WCM_RENDERINGCONTEXT_KEY);
request.setAttribute("sitePath",context.getPath());
%>


Step 2: Create Personalization component and write rule for that component as below

Rule:
Select Web Content
  whose  Location  is  current Request.sitePath  and
  whose  Authoring Template  is  library/AT_News

NOTE: You need to create the dynamic request attribute named "sitePath" while creating this rule.

Header:
<div class="news_links">

Design for each menu search result:
<a href='<Placeholder tag="href"/>'><IDCmpnt context="autoFill" type="content" field="title"/></a>
<br>
<IDCmpnt context="autoFill" type="content" field="description"/>
<br><WorkflowCmpnt context="autoFill" type="content" field="publishdate" format="MMMM dd, yyyy"/> 

Footer:
</div>

Separator:
<hr/>

Step 3: Create Presenation Template with following design code to display the personalization component output.
<component name="library/JSP_testPZNComponent"/>
<component name="library/PERS_testPersComponent"/>

Step 4: Add the WCM content viewer portlets on different pages with different sitearea selected. (have pages with WCM mappings done with different sitearea)

by navigating to different pages ,  PZN rule should read the contents from siteareas configured (or mapped) and displays the corresponding news.

Users with manager access can approve items after applying PM28223 fix

Users with manager access cannot approve items if they do not have approve access


But after applying APAR-PM28223,  this will allow managers to approve items if they have manager access to items even if they do not have approve access explicitly.

Accessing elements of any Content Item from other content presentation templates (or from design elements)

We can access the elements of the other content Items directly using element tag with following options.

<Element context="selected" name="library/site/sitearea/sitearea/contentitem" type="content" key="eleName"/>

Here "name" attribute can be any of below 

a). name="library/contentItem"

If you specify the name as above then it find out the contentItem within the library but you can't use this if you have mulitple content items in library with same name(use below in this case).

b). name="library/site/sitearea/sitearea/contentItem"

If a content item with the same name is used in more than one site, then you must specify name value as above to select the appropriate content item.

c). name="./contentItem"
 
To use the library specified in the URL of the current page , use name value as above. If you specify name="./contentItem", the library name will not appear in your presentation template or element design. The actual path will not be resolved until the item is rendered

Features added or updated for Web Content Integrator (WCI) in 6.1.0.5

Following features are added or updated for Web Content Integrator in 6.1.0.5

1. Added tags to allow inheritance to be enabled or disabled for an item in a feed
2. Reference Elements using their Name and Library instead of GUID (using GUID still supports)
3. Added supportl for handling the content with missing publish Date(empty , invalid)
4. Added support for creating Link Elements (earlier version supported only the upate)
5. Corrected the handling of missing Workflows content (earlier it simply thrown Null pointer but Handled to throw proper exception as this is anyhow a error scenario).


1. Following new tags will enable to allow inheritance to be enabled or disabled for an item in a feed.

Enable user inheritance:
<ibmwcm:access type="user" ibmwcm:inheritance="enabled"/>

Disable user inheritance:
<ibmwcm:access type="user" ibmwcm:inheritance="disabled"/>

Enable contributor inheritance:
<ibmwcm:access type="contributor"
ibmwcm:inheritance="enabled"/>

Disable contributor inheritance:
<ibmwcm:access type="contributor"
ibmwcm:inheritance="disabled"/>

Enable editor inheritance:
<ibmwcm:access type="editor" ibmwcm:inheritance="enabled"/>

Disable editor inheritance:
<ibmwcm:access type="editor" ibmwcm:inheritance="disabled"/>

Enable manager inheritance:
<ibmwcm:access type="manager" ibmwcm:inheritance="enabled"/>

Disable manager inheritance:
<ibmwcm:access type="manager" ibmwcm:inheritance="disabled"/>

2. The WCI, Reference Element is only able to reference components by GUID.
But with most recent update(PM26035) you can also Reference Elements using their Name and Library as below.

Option 1: Component in another Library:
<ibmwcm:element name="Reference-to-component-in-other-library">
<ibmwcm:type>reference</ibmwcm:type>
<ibmwcm:path library="Shared">DefaultHeader</ibmwcm:path>
</ibmwcm:element>

Option 2: Component in the feed library:
<ibmwcm:element name="Reference-to-component-feed-library">
<ibmwcm:type>reference</ibmwcm:type>
<ibmwcm:path>DefaultHeader</ibmwcm:path>
</ibmwcm:element>

Different ways of Handling CSS and JavaScript in WCM

We can handle CSS and JavaScript in WCM in following three different approaches.

Approach 1: Storing the CSS as Style Sheet Component and JavaScript as File Resource Components

Note:  You can upload the JavaScript file into WCM as the File Resource Component and refer that in presentation template as below

<script  language="javascript" src="<Component name="library/test-javascript-cmpnt" format="url"/>" />

Pros:
1. Out of box component

Cons:
1. Authors can't modify the CSS in the authoring interface when they have to make changes.
2. You can not refer the File Resource components(like images) stored in WCM like below

table{  
     background-image: url(<Component name="bckImage" format="url"/>); 
}

3. Need to place CSS and JavaScript on somewhere for future changes(outside of WCM).


Approach 2: Storing CSS and Javascript as HTML Components
Store CSS styles as HTML components and then embedded those components in presentation templates inside of <style> blocks. (Same for the javascript also)

Pros:
1.Authors can modify CSS classes inside the WCM authoring.
2.Additional request to load the CSS files is not required (fewer HTTP requests generates from page)

Cons:

1. Here CSS files are rendering from WCM, Can't take the advantage of browser caching
2. Response size and time may increase as Styles are coming from the JCR.

Approach 3: Storing CSS and Javascript as Content Item under some SiteArea

Steps to implementing CSS as a content item -
a). Create a authoring template with a single Body HTML element,
b). Create a presentation template that just refer Body element (you may not use Ephox RTE element because it includes <P> tags , causing CSS Styles failed )
c). Name ContentItem as *.css ("test.css").
d). You can add the above contentItem from other presentation templates as CSS or Javascript . Make sure to append "?subtype=css" to path of content item while referring in other Presentation templates to force WCM content to be rendered with text/css as MIME type instead of text/html (default MIME type for WCM content is text/html or text/plain).
Ex:
<link rel="StyleSheet" href="/wps/wcm/myconnect/library/Site/SiteArea/test.css?subtype=css" type="text/css"/>



Following are the advantages if you naming the ContentItem as *.css
a)  When site is pre rendered for delivering content, content items stored as *.css will generate files valid CSS file to pre render
b)  Even when content served through the WCM servlet , this allows the browser to cache the CSS file

Pros:
1.Authors can modify CSS classes inside the WCM authoring portlet with normal workflow process
2.Additional request to load the CSS files is not required (fewer HTTP requests generates from page)

Cons
1. Make sure this content item (css) doesn't pick up by some navigators or menu components as it is content item


Note:
a). In Second and Third approach approach , your CSS styles or javascript can refer File Resource Components(like for background images) that stored in WCM repository as components by simply using the Component Tag as below

body{
   background-image: url(<Component name="bckImage" format="url"/>);
}

b). "subtype" query string parameter only applies to the default content renderer and will not work on URLs which is used to invoke the component renderer (i.e. which contain srv=cmpnt in the query string parameter).

c). You may need to add an extension mapping for CSS to WcmConfigService.properties in older versions. Following are steps to do this.

  1. Search for the line "#mapping of mimetypes to extensions" in wcmconfigservices.properties file located under <Portal_root>\wcm\shared\app\config\wcmservices\ directory.
  2. There is an attribute named "mimetype.list=extensiontype.gif". Add ",extensiontype.css" (no spaces, include the dot ( . ) character at the front of the string) at the end of the line.
  3. Add a new line "extensiontype.css=text/css" (no spaces) after the "extensiontype.lzh=application/octet-stream"
  4. Save the file.
  5. Restart WebSphere Portal Server (WPS).

    Enabling traces and Checking logs in websphere portal

    Enabling traces and checking logs and configuration file information:

    1. Access the WebSphere Application Server administrative console using http://hostname:port_number/ibm/console.
    2. Go to Troubleshooting --> Logs and Traces --> Diagnostic Trace, and select the application server for your portal (WebSphere_Portal).
    3. Click Diagnostic Trace --> Change log detail levels (make sure that the Enable Trace checkbox is selected).
    4. Specify the required trace settings as follows:

    Enable the following traces based on requirement

    For issues with personalization in WebSphere Portal ( rules, campaigns, application objects ):
    com.ibm.websphere.personalization.*=all:com.ibm.websphere.query.*=all

    For issues with personalization and security:
    com.ibm.webshere.personalization.=finest:
    com.ibm.icm.ci.query.impl.ResultSetProcessor=finest:
    com.ibm.icm.ci.query.impl.QueryProcessor=finest:com.ibm.wps.services.puma.=finest:
    com.ibm.wps.puma.*=finest

    For issues with personalization and Web Content Management (WCM):
    com.ibm.websphere.personalization.*=all:com.ibm.websphere.query.*=all:
    com.ibm.workplace.wcm.pzn.*=all:com.ibm.workplace.wcm.services.pzn.*=all

    For issues with personalization and JCR:
    com.ibm.websphere.personalization.*=all:com.ibm.websphere.query.*=all:
    com.ibm.icm.*=finest:com.ibm.icm.ci.schema.impl.SchemaService=info

    For issues with personalization authoring performance:
    com.ibm.websphere.personalization.*=all:com.ibm.wps.caf.*=all

    For issues with personalization runtime performance:
    com.ibm.websphere.personalization.*=all

    For issues with personalization publishing:
    com.ibm.websphere.personalization.*=all

    For configuration issues with personalization authoring environment
    (Navigator Portlet, Editor Portlet, and List Portlet):
    com.ibm.websphere.personalization.*=all:com.ibm.wps.caf.*=all

    5. Save your updates.
    6. Restart Portal.
    a) Stop the Portal server.
    b) Archive and delete the contents of the <WP_profile_root>/logs/WebSphere_Portal directory.
    c) Start Portal.
    7. Recreate the reported issue.
    8. To disable tracing, specify the trace string, *=info, and restart Portal.

    In the event that either the Trace.log or systemOut.log wrap, then increase the number of historical trace files to 20 and the number of historical systemOut.log files to 10.

    To increase the number of historical files:
    • Access the WebSphere Server administrative console using http://hostname:port_number/ibm/console.
    • Navigate to Troubleshooting --> Logs and Traces --> WebSphere_Portal>Diagnostic Trace, and update the maximum number of historical files to 20.
    • Navigate to Troubleshooting --> Logs and Traces --> WebSphere_Portal>JVM Logs, and update the maximum number of historical files to 10.
    • Save the changes and restart.

    Temporary tracing through the WebSphere Portal administration portlet:

    Traces can be set for a temporary period by using the Enable Tracing administration portlet or the WebSphere Server administrative console. Use the following steps to set traces using the portlet:

    1. Log into Portal as an administrator.
    2. Go to Administration --> Portal Analysis --> Enable Tracing.
    3. Type the required trace string into the "Append these trace settings" field as follows:
    com.ibm.wps.caf.*=all: com.ibm.websphere.personalization.*=all
    4. Click Add to update the "Current trace settings" field.

    NOTE:
    Restarting Portal will remove traces that were set using the Enable Tracing Administration portlet.

    To disable tracing:


    1. Select the current trace settings and click Remove. In the example above, the current setting is
    com.ibm.wps.caf.*=all: com.ibm.websphere.personalization.*=all=enabled

    2. Type the trace string, *=info, into the "Append these trace settings" field and click Add. This trace string overwrites all settings listed under "Current trace settings" and resets to the default.

    Portal search collections gets corrupted.

    Generally Portal search collections may gets corrupted in following scenarios

    Scenario 1.
    This happens after applying fixpack or ifix.

    Scenario 2.
    This happens after the abnormal shoutdown of the remote search server or the local search server, depending on how you have configured the search service.
    Resolving the problem  
    Scenario 1.
    The index structure of Portal search is not backward compatible between the different product versions. For this reason you need to preserve your search collections before you upgrade your Portal server. To preserve search collections, export the collections prior to upgrade and then import them back using the "Manage Search" admin portlet.
    Scenario 2.
    If, the crawler is running and the remote search server or the local search server(depending on how you have configured the search service) terminates unexpectedly then it is normal to see the search collections disappear or get corrupted. The only way to prevent this is to make sure the servers are shutdown gracefully. For a quick recovery, keep backup copies of all the collections, by exporting them using the "Manage Search" admin portlet. This way you can restore the collections after the failure by importing them back into a new collection.
    You should also delete the faulty collections before creating a new one.


    For IBM® WebSphere® Portal version 6.0 and 6.1
    Faulty Index cleanup portlet is integrated into 6.0.0.x and 6.1 to "Manage Search" admin portlet Go to:
    Manage Search -> Default Portal Search Service

    You will see a link at the bottom "Manage Faulty Collections" only if there are any faulty/corrupted collections

    NOTE: In some cases you may require to delete the collections physically from the hard disk first and then use the faulty collection portlet/functionality to completely remove them from the machine. This may require portal restart

    Handling paragraph (< p >) tags in Ephox Editlive Editor

    By default Ephox editor will insert insert an empty paragraph tag with non-breaking space (&nbsp; or &#160;) in code view when you first load EditLive! without any content in its body or when you pressing "Enter" key in the design view of EditLive!

    Reasons for above default behavior is

    1.  EditLive assumes user will start typing after the initial load and prepares the editor by placing an empty paragraph at the start of the empty document. This provides a place in the document to actually position the caret and allow the user to start entering text. If the user chooses to insert a heading tag instead of a normal paragraph, EditLive! simply replaces the paragraph with the relevant heading.
    2. Most browsers ignore empty paragraph tags, so to ensure the page displays as the user intended, a non-breaking space is inserted into empty paragraphs.
    Note: Recent versions of EditLive have significantly reduced the number of situations when an empty <p> tag will be inserted - including the "empty document case" which now returns the empty string (This is Fixed from EditLive! for LWCM 6+ 3.4.0.9 October 13th, 2009 Includes EditLive! version 7.0.0.270 onwards).

    You can change the default behavior of inserting paragraphs when you press the Enter key , following are the instructions

    1. Open ephox editlive configuration file
    2. find the wysiwygEditor,looks like below

      <wysiwygEditor>
        <!--wysiwygEditor settings-->
      <wysiwygEditor/>

      or 

    <wysiwygEditor brOnEnter="false" disableInlineImageResizing="false"
            disableInlineTableResizing="false" enableTrackChanges="false"
            showDocumentNavigator="false" showTableGridlines="true" tabPlacement="bottom"/>

    3. change the brOnEnter = true


    brOnEnter flag is boolean attribute defines whether a <br> or <p> tag is inserted when the Enter key is pressed. When set to true a <br> is inserted when Enter is pressed, when the Shift + Enter key combination is used a <p> tag is inserted. When set to false this behavior is reversed.Pressing enter when in table fields will always yield a <br> tag, regardless of the value set to brOnEnter.

    The default behavior for EditLive! is to insert a <p> on Enter and a <br> on Shift + Enter. This is the same behavior as when this setting is set to false.(Default Value: false)

    Click Here for other options

    Creating readonly pieces of content in editlive section

    We can create the part of content loaded by Editlive instance as readonly. EditLive! for Java uses the contenteditable HTML attribute to indicate whether an element and its children are editable within EditLive! for Java. If contenteditable is set to false then the content of that element and its child elements becomes read-only.

    The following example demonstrates how to create a read-only section within a document. The paragraph with the text <p>This is <b>read only</b>content.</p> will be read-only.

    <html>
    <body>
    <p>
    This content can be edited
    </p>
    <p contenteditable="false">
    This is <b>read only</b> content.
    </p>
    <p>
    This content is also able to be edited.
    </p>
    </body>
    </html>

    Inheritance for Read-Only Content

    When an element is marked as read-only all its child elements are also created as read-only sections. However, the read-only property can be overwritten for specific child elements. This is achieved by explicitly setting the contenteditable attribute to true for that element. The following example demonstrates how to create a read-only parent element (a paragraph) with an editable child element (a span element).

    <html>
    <body>
    <p>
    This content can be edited
    </p>
    <p contenteditable="false">
    This content is not editable.
    <span>
    This content is contained within
    an editable child element
    </span>
    This content is not editable.
    </p>
    <p>
    This content is also able to be edited.
    </p>
    </body>
    </html>



    Creating non editable Editlive Instance 

    Above section describes to how make the pieces of content inside the editlive as readonly. But if you want to open the whole editlive as read-only (When you don't have controller over the content or when just want to disable all editing options of editlive ) , set the ready only property on the editlive instance as follows

    customEditliveInstance.setReadOnly("true");

    once you set instance as read only , applet get initializes when you click on editable section but most of menu items will be in disable mode and you can delete or edit content inside editlive.

    Calling Javascript file from another JavaScript file

    Best of way to do this is using Document Object Model (DOM) , following simple function can perform this processing for this using DOM

    function includeJavascriptFile(jsFileName,pos) {
    var th = document.getElementsByTagName(pos)[0];
    var s = document.createElement('script');
    s.setAttribute('type','text/javascript');
    s.setAttribute('src',jsname);
    th.appendChild(s);
    }

    This function adds the necessary script tag into the end of the head or body section of the page for you. All that you then need to do from your Javascript in order to add another external javascript into the page is to call that function passing it the name of the file that contains the extra code that you want to include and whether to add it to the end of the head or the end of the body.

    includeJavascriptFile('externalFile1.js','body');
    includeJavascriptFile('externalFile2.js','head');

    Once the script tags have been added to the page you can then call any functions that you want from within that file.

    This method also useful to include the javascript files externally on the web page based on conditions like based on browser version include the different JS files

    Another sample code for the above approach is

    (function() {
        var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
        ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
        var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
      })();



    Following is another way to include the JS


    <script type="text/javascript">
      document.write(unescape("%3Cscript src='" + (document.location.protocol == "https:" ? "https://testhttps" : "http://testhttp") + ".sivavaka.com/testJava.js' %3E%3C/script%3E"));
     </script>
    
    

    JavaScript XML DOM parser - parsing XML using Javascript and set values to HTML elements

    Use following Code to parse the XML string in Javascript


    function generateTextBoxValue(sourceXMLStr){

    var expectedXML;
    if (window.DOMParser){
    var parser=new DOMParser();
    expectedXML=parser.parseFromString(decodeURIComponent(sourceXMLStr),"text/xml");
      //decodeURIComponent is used assuming sourceXMLStr is UTF-8 encoded otherwise call directly
    }else {// Internet Explorer
    expectedXML=new ActiveXObject("Microsoft.XMLDOM");
    expectedXML.async="false";
    expectedXML.loadXML(decodeURIComponent(sourceXMLStr));
    }

    var testModuleList=expectedXML.getElementsByTagName(TEST_XML_MODULE_ELEMENT_NAME);// constant contains testModule XML Element name

    for(var x=1;x<=testModuleList.length;x++){
    document.getElementById(testTextBox).value = testModuleList[x-1].childNodes[0].nodeValue;
    //fill your DOM elements based on your criteria
    }

    }

    Displaying current content path in presenation template

    Couple of ways we can display current content path in presentation template

    Approach 1:  Create a Navigator as below and refer in presentation template

    Create a Navigator Component  :

            Start Type: Current Content
            Selected Start Area:None
            Include Start: true
            Ancestor Level: None
            Descendant Level: None
            Preceding Siblings Level: None
            Next Siblings Level: None
            Show Site: false
            Show Content: true
            Expand current navigator branch one level: false
            Expand navigator to display current site area: false
            Results per page:1
            Start page:1
            Maximum pages to include:1
            Pages to read ahead:1

    And add the following in design section "<Placeholder tag="sitepath"/> ..

    Then include the Navigator component in the Presentation template

            <Component  name="Design/nav_content_path"/>


    Approach 2:

    Another way is create JSP component and code inside the JSP will like below

    RenderingContext renderingContext = (RenderingContext)request.getAttribute(Workspace.WCM_RENDERINGCONTEXT_KEY);

    if ( renderingContext != null ){
    request.setAttribute("sitePath",renderingContext.getPath());
    out.println( renderingContext.getPath());
    }

    Lotus Web Content Management caches (different Dynacache objects used by WCM)

        Web Content Management Cache Instances
        Web Content Management Item caching
        Web Content Management Summary
        Web Content Management Basic Caching
        Advanced and Resources
        Session Cache
        Menu
        Navigator
        Absolute path
        Missed Items
        Library
        Library Parent
        Draft Summary
        User cache


    Lotus Web Content Management Cache Instances


    With IBM WebSphere® Portal V6.1, the Lotus Web Content Management caches are managed through the IBM WebSphere Application Server Administration Console in the following location: Resources > Cache instances > Object cache instances.


    Lotus Web Content Management Item Caching


    services/cache/iwk/strategy – Lotus Web Content Management Item caching
    Default size: 2000, default lifetime: infinite, usage pattern: regular.

    This cache stores internal Lotus Web Content Management items. Any Lotus Web Content Management item read from the database will first check this cache. Lotus Web Content Management items cover Content, Workflow, Workflow Stages, Workflow actions, Taxonomies, Categories, Authoring Templates, Presentation Templates, Sites, Siteareas, and all Library Components. The cache entry will be updated or cleared when its corresponding Lotus Web Content Management Item is updated or deleted.


    Lotus Web Content Management Summary


    services/cache/iwk/objectsummary – Lotus Web Content Management Summary
    Default size: 2000, default lifetime: infinite, usage pattern: regular.

    This cache stores summaries of Lotus Web Content Management Items. The summaries are used to display in lists in the authoring portlet or used internally in the Lotus Web Content Management API to calculate Lotus Web Content Management Item Document IDs used for Iterators. The cache entry will be cleared when a Lotus Web Content Management Item is updated that will affect this summary.


    Lotus Web Content Management Basic Caching


    services/cache/iwk/module
    Default size: 2000, default lifetime: infinite, usage pattern: regular.

    This cache is used for Lotus Web Content Management Basic caching. Refer to the Information Center for instructions on setting up Basic caching. The Basic cache stores the entire response. The key is based only on the URL so all users will see the same response.


    Advanced and Resources


    services/cache/iwk/processing – Advanced and Resources
    Default size: 2000, default lifetime: 1 month (configurable), usage pattern: regular.

    This cache stores the binary MIME for file and image resources in Lotus Web Content Management. The maximum size of resources to store is set in the Lotus Web Content ManagementConfigService.properties file as the property resourceserver.maxCacheObjectSize (in kb). Resources over this size are not cached and are streamed directly to the response. The expiry is set in the same file as: resourceserver.cacheExpiryDate. The cache entry will be cleared when that resource is updated.

    This cache also stores page data if Lotus Web Content Management Advanced caching is enabled. Refer to the Information Center for instructions on enabling Lotus Web Content Management Advanced caching. The processing cache stores advanced caches for the following types:
    • Site: Similar to “Basic” Caching except that “Connect Tags” are processed each time.
    • User: Stores a copy of an item in the cache for each user.
    • Secured: Users that belong to the same groups will access the same cached items.
    • Personalized: Users who have selected the same personalization categories and keywords, and who belong to the same Group, will access the same cached items.
    Note: The session option for Advanced caching is not stored in the processing cache, but in the session cache.

    Session Cache


    services/cache/iwk/session - Session
    Default size: 2000, default lifetime: infinite, usage pattern: regular.

    This cache stores the page data for when session advanced caching is enabled. See the InfoCenter for enabling Lotus Web Content Management Advanced caching.


    Menu


    services/cache/iwk/menu - Menu
    Default size: 2000, default lifetime: infinite, usage pattern: regular.

    This cache stores Lotus Web Content Management Menu entries. An entry comprises of the Content IDs associated with a particular menu. The entries are retrieved and cached without applying security. Whenever a user needs that menu’s results, their specific security will then be applied to the cached results. A dynamic menu, which is one that is affected by the current user’s context (e.g. based on categories in a users profile) will store a separate cache entry for each different context. The cache entry will be cleared when a Lotus Web Content Management Item is updated that will affect this menu.


    Navigator


    services/cache/iwk/nav Navigator
    Default size: 2000, default lifetime: infinite, usage pattern: regular.

    This cache stores parent to child relationships that comprise a Lotus Web Content Management navigator. A complex navigator might have multiple parent to child relationships (e.g. if siblings are included). The navigator entry is made up of the IDs of the parent and children. This cache will be cleared upon any Lotus Web Content Management Item update in the system.


    Absolute Path


    services/cache/iwk/abspath – Absolute path
    Default size: 5000, default lifetime: infinite, usage pattern: regular.

    This cache stores JCR path to ID relationships. The cache entry will be cleared when a Lotus Web Content Management Item is updated that will affect it.


    Missed Items


    services/cache/iwk/missed – Missed Items
    Default size: 5000, default lifetime: infinite, usage pattern: regular.

    This cache stores JCR paths that does not exist. This is used primarily for multi locale solutions to determine if items of other locales exist or not. The cache entry will be cleared when a Lotus Web Content Management Item is updated that will affect it.


    Library


    services/cache/iwk/global - Library
    Default size: 2000, default lifetime: infinite, usage pattern: regular.

    This cache contains a lookup for library ID, name and path to the library object. This is pre-populated up to the cache size at Portal startup.


    Library Parent


    services/cache/iwk/libparent – Library Parent
    Default size: 2000, default lifetime: infinite, usage pattern: regular.

    This cache stores a list of all children library IDs to a given parent ID. Introduced for Quickr to group libraries within a teamspace together.


    Draft Summary


    services/cache/iwk/draftSummary – Draft Summary
    Default size: 2000, default lifetime: infinite, usage pattern: regular.

    This cache stores the identity of the draft summary to the identity of the draft Lotus Web Content Management Item.


    User Cache


    User cache
    Size is fixed to 2000. default is disabled.

    This cache operates using a Least Recently Used algorithm. It is not shared across nodes in the cluster and it does not use dynacache. It does not update when LDAP changes. User cache is disabled by default but you can enable it with the following setting: user.cache.enabled=true in Lotus Web Content ManagementConfigService.properties. When you enable user cache, you must to run a module called MemberCacheManager or restart the server. To enable the module, add the following to Lotus Web Content ManagementConfigService.properties:
    connect.businesslogic.module.template.class=com.presence.connect.wmmcomms< /code>
    connect.businesslogic.module.template.remoteaccess=true
    connect.businesslogic.module.template.autoload=false


    Resources :
    http://www-10.lotus.com/ldd/portalwiki.nsf/dx/Lotus_Web_Content_Management_caches

    useUserAccess (useLiveAccess) method while using WCM API

    By default users running the custom WCM API applications have at least Contributor role on the objects accessed in the Workspace. This can be lowered to User role using useUserAccess method.


    workspace.useUserAccess(true); (in old versions it is useLiveAccess)

    true------user Access
    false-----contributer access
    Note: The Access context used in the API can be set at any time, after the creation of the workspace.

    Call "workspace.useUserAccess(true)" before calling other workspace methods that act on objects for which Contributor role would otherwise be required.


    Scenarios:


    Problem WCM API method workspace.getById() fails for content or library component even though the user is given "User" access.   


    Cause This method requires minimum "Contributor" access on wcm content or library component to get desired results.  


    Resolving the problem In order to resolve this issue , call API method "workspace.useUserAccess(true)" just before calling the workspace.getById() method . Otherwise , the default access context is "Contributor" and hence method workspace.getById() fails for content or library component even though the user is given "User" access. 





    Resources:
    Authorizationexception is thrown while using workspace.getById() method (https://www-304.ibm.com/support/docview.wss?uid=swg21399507)

    WPS Portal and WCM version information

    To find out the what version of the portal and WCM with exact cumilative fixpacks check the following file
    /Websphere/wp_profile/portalserver/log/versionInfo.log

    Another way to find the out the Portal and WCM version is

    /Websphere/wp_profile/bin/WPVersionInfo.bat (.sh)

    Connect Tags (Enable Caching for individual Components in WCM )

    Custom caching can be applied to Web Content Management Components by using connect tags to cache individual components referenced within presentation templates. This is done by replacing a component reference in a presentation template with a connect tag. This enables you to apply custom caching strategies to Web Content Management components to override your server's default caching strategy. You can also use this method to disable the Caching of Web Content Management components.

    When first time presentation template is rendered, the component will be added to the cache. The next time the presentation template is rendered, the component will be displayed from the cache instead of being rendered afresh by the Web Content Management application. Not until it is expired from the cache will the component be rendered again by the Web Content Management application. For this reason, only components that do not require to be freshly rendered every time a page is accessed should be cached.


    Connect tags are used to reference Web content components and apply customized caching to the components.

    Steps
    1. Enable connect tags
    2. Enable process connect tags in presentation templtae
    3. write the following tag


    Step 1: To enable connect tags, you will need to do the following:

    Open the WCMConfigService.properties file in an editor
    was_profile_root/PortalServer/wcm/shared/app/config/wcmservices/


    Configure "connect.businesslogic" to process either unknown hosts, or a selected host:

    connect.businesslogic.hosts.[HOST]=true
    connect.businesslogic.processunknownhosts=false
    
    
    Step 2: Connect tags must be selected in presentation template form for connect tags to be processed.

    The first time the presentation template is rendered, the element will be added to the cache. The next time the presentation template is rendered, the element will be displayed from the cache instead of being rendered afresh by the Web Content Management application.

    Only elements that do not require to be freshly rendered every time a page is accessed should be cached.
    
    
    Step 3:
    
    <connectMOD="ComponentRenderer" SRV="cmpnt" PATH="/Site/SiteArea/Content" SOURCE="library" CMPNTNAME="TestNav" CONTENTCACHE="site" EXPIRES="REL 9000s"> </connect>
    
    
    Parameter Details

    MOD="ComponentRenderer"
    This references the Web Content Management Render Module.

    SRV="cmpnt"
    The Service for this Module is "cmpnt".

    PATH="/Site/SiteArea/Content"
    This sets the context for the element.
    The "sitepath" and "name" placeholders can be used instead of "PATH=" when caching menus or navigators:
    <placeholder tag="sitepath"/>/<placeholder tag="name"/>

    SOURCE="library"
    Source is either "content", "site", "sitearea"
    or "library". In this example it is "library" because the element
    we are caching comes from a component.

    CMPNTNAME="TestNav"
    This is the name of the element to be cached.

    CONTENTCACHE="site"
    This is either "site or "session".

    EXPIRES="REL 9000s"
    The time the component will expire from the
    cache is set here.
    
    
    
    
    
    
    Note:
    We can also use this method to disable caching. In this example the property CONTENTCACHE="none" is used to disable caching of this element.
    
    <connect MOD="ComponentRenderer" SRV="cmpnt" PATH="/Site/SiteArea/Content" SOURCE ="library" CMPNTNAME="TestNav" CONTENTCACHE="none" > </connect>
    
    
    
    Best Practices:
    a). If you are caching a component that is used in more than one presentation template, it is best practice to save the connect tag as a HTML component and then reference that component in each presentation template.

    b). If you have a set of cached components that use the same "Expires" setting, then it is best practice to save the "Expires=" parameter as a HTML component and then reference that component in each connect tag used to cache components.

    If you then need to change the cached component tags, you only need to change it in the HTML component rather than in multiple presentation templates


    Derby DB basic information

    Few Details about the Derby Database

    Standalone Derby Database


    Click Here to download Derby DB(10.1.3.1). No installation is required


    Starting derby DB

    from Lib(C:\db-derby\lib)
    java -jar derbynet.jar start

    from framework/bin(C:\db-derby\frameworks\NetworkServer\bin)
    startNetworkServer.bat

    Few commonly used  SQL statements

    CREATE SCHEMA sivavakablog
    CREATE TABLE sivavakablog.reader
           (READER_ID int NOT NULL,
            REGISTERED_DATE DATE NOT NULL,
            READER_NAME CHAR(30),
            PRIMARY KEY (READER_ID));

    insert into sivavakablog.reader(reader_id,registered_date,reader_name) values (1111,'2010-11-11','reader1');

    update sivavakablog.reader set reader_name='reader2' where reader_id=1111

    drop table sivavakablog.reader

    select * from sivavakablog.reader;

    drop index release.IX3000A

    CREATE INDEX JCR.IX2110B ON JCR.PROT_RES (OWNER_UID ASC, RES_TYPE ASC);


    Ref Complete SQL References:
    http://db.apache.org/derby/manuals/reference/sqlj27.html#HDRSII-SQLJ-31580 (Create Commands)
    http://db.apache.org/derby/papers/JDBCImplementation.html (JDBC related)
    http://db.apache.org/derby/manuals/reference/sqlj28.html  (Drop commands)


    Embed Derby Server (Websphere Portal)

    1. Open command prompt and go to \IBM\WebSphere\AppServer\derby\bin\embedded\
    2. enter systeminfo.bat to see what are the environment variables
    3. If Linux , check the current classpath using below and append as follow,
      1. echo $classpath
    4. If windows, check the current class using below
      1. echo %classpath%
      2. set classpath=%classpath%;
    5. if the JDBC client is not in classpath , set that as below
    6. open the ij.bat
    Also consider that the version of Derby provided with WebSphere Portal has stress and failover limitations that are expected to be resolved in a later release of Derby performance improvements.

    connect 'jdbc:derby://localhost:1527/wpsdb;user=wpsadmin;password=password'

    D:/IBM/WebSphere/AppServer/derby/lib/derby.jar;D:/IBM/WebSphere/AppServer/derby/lib/derbyclient.jar;D:/IBM/WebSphere/AppServer/derby/lib/derbynet.jar;D:/IBM/WebSphere/AppServer/derby/lib/derbytools.jar;

    Trouble shooting Websphere Poral 6.1 default Database Crash ( Derby database)

    Recently we had issue with Websphere Portal Startup when portal crashed because of free disk space issues.

    When we try to access portal URL from browser

    HTTP 404 when accessing the WebSphere Portal URL from a browser , Initialization of one or more services failed

    In SystemOut.log we see that  Derby database connection failed for the first time and after restart of the server we see the Couple of exceptions like

    Embed SQL Exception , 'The conglomerate (7,777) requested does not exist' message

    and like

    SQL Exception , 'The conglomerate (15,424) requested does not exist' message ( When it tries to access the PROT_RES table in JCR schema and WPS_TASK scheduler table in RELEASE database)

    Trouble Shooting Steps we followed

    1. Stop the Portal server if it's still running.
    2. Delete the two lock files, db.lck and dbex.lck, in <wp_profile>/PortalServer/derby/wpsdb.
    3. Delete the "tranlog" for WebSphere_Portal, under <wp_profile>/tranlog/<cell>/<node>/WebSphere_Portal.
    4. Restart the Portal server.
    5. If the Portal server startup still has problems, remove all the files in <wp_profile>/PortalServer/derby/wpsdb/log and then restart the Portal server.
    6. If all of the above fails and you have a backup of the "wpsdb" database, you may attempt to archive the current database in another location outside of the WebSphere directory structure and put the backup in place.
    NOTE: Because of the potential database corruptions documented Its recommend periodic backup of your Derby databases

    Ref:
    http://www-01.ibm.com/support/docview.wss?uid=swg21381003


    But the above steps didn't Solve our problem, Raised PMR but that didn't help .

    We tried to check the above tables (PROT_RES and WPS_TASKSCH) manually by connecting Derby DB but we got the same error like above when we fire Select queries . Realized that both tables corrupt(crashed).

    We restored to wpsDB (we had wpsDB backup and deleted the old one replaced it).
    NOTE: Recommended a periodic backup of your Derby databases

    WCM navigator component customization - Displaying siblings when there is no child siteareas (Linking two navigators)

    Following article shows how to design the navigator for the following scenario

    If SiteArea has child siteareas then display the child SiteAreas and  
    if SiteArea does not have child SiteAreas then display Sibling Siteareas

    Example:

    ParentSitearea1
       |
       --->ChildSiteArea1
       |          |
       |          --->SubChildSiteArea1
       |          |
       |          --->SubChildSiteArea2
       |
       --->ChildSiteArea2
       |
       --->ChildSiteArea3
                 

    Excepted output
    when we click on ChildSiteArea1, display "SubChildSiteArea1 and SubChildSiteArea2"  (child siteareas)
    when we click on ChildSiteArea2, display "ChildSiteArea1 ,ChildSiteArea2 and ChildSiteArea3" (Siblings)
    when we click on SubChildSiteArea1, display "SubChildSiteArea1 and SubChildSiteArea2" (Siblings)


    Steps
    1. Create Navigator component (ChildSiteAreaNavigator) to pull child siteareas when click on parent sitearea. Select following options


    Start Type: Current Site Area
    Selected Start Area: None
    Include Start: false
    Ancestor Level: None
    Descendant Level: 1 Level
    Preceding Siblings Level: None
    Next Siblings Level: None
    Show Site: false
    Show Content: false
    Expand current navigator branch one level: true
    Expand navigator to display current site area: false
    Results per page: 10
    Start page: 1
    Maximum pages to include: 10
    Pages to read ahead: 10
    Distinguish items with no children using the final navigator result design: true


    Header:  <ul>
    Footer:  </ul>
    Separator:
    Navigator result design 1:

    <li class="leftNav"><span ><a href='<Placeholder tag="href"/>' class="navItem" ><Placeholder tag="name"/></a></span>
    </li>

    No result design:
    <Component name="sivavaka_library/SiblingsNavigator"/>





    2. Create another Navigator component (SiblingsNavigator) to pull siblings siteareas when click on sitearea. Select following options


    Start Type:Current Site Area
    Selected Start Area:None
    Include Start:true
    Ancestor Level:None
    Descendant Level:None
    Preceding Siblings Level:All
    Next Siblings Level:All
    Show Site:false
    Show Content:false
    Expand current navigator branch one level:true
    Expand navigator to display current site area:false
    Results per page:10
    Start page:1
    Maximum pages to include:10
    Pages to read ahead:10
    Distinguish items with no children using the final navigator result design:true

    Header:  <ul>
    Footer:  </ul>
    Separator:
    Navigator result design 1:
    <li class="leftNav"><span><a href='<Placeholder tag="href"/>' target="" title="" class="navItem"><Placeholder tag="name"/></a></span>
    </li>

    Basically above two navigator components are connected , you just refer single navigator component to display results as expected

    WCM workflow joint approval (If content need to approve by set of users and all users must approve)

    If you select Joint Approval option ,everyone who has approve access to the document must approve the document to the next stage before the document is moved. Generally, only one approver needs to approve the document to the next stage. If, however, you have activated Joint Approval, then all users with approve access must approve it. The exception to this is, if a group is listed as having approve access, only one group member needs to approve the document before it is moved.

    If you have a single person and a group both defined as having approve access to the document and if you have Joint Approval activated, the single person AND one member of the group must approve the document before it can move to the next stage

    Example:
    Group1 members  ::::::  grp1memeber1, grp1member2, grp1member3
    Group 2 members ::::::  grp2member1, grp2member2, grp2member3
    Individula Approvers :::::: individualApprover1, individualApprover2

    If you add the Group1, Group2 , individualApprover1 and individualApprover2 as Approvers and if you select the "Joint Approval" option. Then
    anyone from Group1 (any one of grp1member1,grp1member2,grp1member3) and
    anyone from Group2 (any one of grp2member1,grp2member2,grp2member3) , individualApprover1 and individualApprover2 has to approve to move document to next stage