Tuesday, June 26, 2012

Pagebuilder2 theme and skin setup


  1. Download WebDav client - http://www.jscape.com/products/file-transfer-clients/anyclient and setup following url
http://localhost:10039/wps/mycontenthandler/dav/themelist/
http://localhost:10039/wps/mycontenthandler/dav/skinlist/
http://localhost:10039/wps/mycontenthandler/dav/fs-type1/
  1. Connect webdav to http://localhost:10039/wps/mycontenthandler/dav/themelist/
  2. Copy the existing theme pagebuilder2 'csa2.theme' folder to local drive
  3. Rename the csa2.theme folder to folder say csa2.Mytech, the csa2.Mytech will be used as uniqueName for theme
  4. Open the C:\Temp\csa2.Mytech\metadata\localized_en.properties file in the Notepad and change the value of title property
    #
#Fri Feb 24 21:49:19 IST 2012
description=Mytech PageBuilder2 Theme
title=MytechTheme

  1. Now use the WebDav client to upload the csa2.Mytech folder onto WebDav store at /themelist url
  2. Connect webdav to http://localhost:10039/wps/mycontenthandler/dav/skinlist/
  3. Copy the existing skin 'csa2.standard' folder to local drive
  4. Rename the csa2.standard folder to folder say csa2.MyTechSkin, the csa2.MyTechSkin will be used as uniqueName for skin
  5. Open the C:\temp\csa2.MyTechSkin\metadata\localized_en.properties file in the Notepad and change the value of title property
#
#Wed Mar 14 11:26:40 IST 2012
description=MyTech Skin
title=MyTechSkin

  1. Now use the WebDav client to upload the csa2.MyTechSkin folder onto WebDav store at / skinlist url
  2. Now you should able to see the new theme (MytechTheme) new skin (MyTechSkin) in the themes and skins admin portlet. But dynamic resources are still pointing to pageBuilder2 theme.
Note - If you don't see your theme and skin name here then that means the name is cached somewhere you can either restart the server or click on Add New Theme button and create new theme from there to see your theme name.
To customize theme or skin, need to edit the theme or skin files in WebDAV. To perform administrative customization (title, description, metadata) continue to use the /themelist or /skinlist entry point. If you want to customize the templates and static resources, use the /fs-type1/ entry point.
  1. Create war file based on the pagebuilder.war (location is \IBM\WebSphere\PortalServer\theme\wp.mashup.cc.theme\installedApps\wp.mashup.cc.theme.ear\PageBuilder2.war  )
a)      Create a new dynamic project 2.4 named 'MytechTheme'
b)      Copy the contents of the original PageBuilder2 theme from the directory PortalServer/theme/wp.mashup.cc.theme/installedApps/wp.mashup.cc.theme.ear/PageBuilder2.war into a new WAR directory.
c)       Change the name of the PageBuilder2 directory (in ./themes/html/) to a name MytechTheme
d)      Remove the plugin.xml file from the WEB-INF directory but do not remove the decorations.xml file or the tld directory.
e)      Change the display-name in the web.xml file to a name MytechTheme
f)       Change the attribute in the ibm-web-bnd.xmi and the ibm-web-ext.xmi files to match the above name.
g)      Package this directory into a new WAR file and deploy the war file to WebSphere Application Server with your own contextroot (/Mytechtheme) while installing, make sure to start the application after installation.
Note - there will be numerous compilation error on jsps just ignore them and deploy, it will get resolve automatically.
  1. Follow the steps below to connect the theme with context root of installed WAR file
a.       Export the existing themes and skins using the attached xmlaccess script 'ExportAllSkin_Theme.xml '. Use following command ' xmlaccess -url http://localhost:10039/wps/config -in ExportAllSkin_Theme.xml -out ExportSkinTheme.xml '
                                                               i.      Find the new theme and skin created in above steps and change the active='true', context-root and resourceroot attributes to match new WAR file. Add a uniquename and defaultskinref to theme. Find the modified XMLAccess in attachment 'MytechSkin_Theme.xml '.
                                                             ii.      Ensure that the default attribute is set to false.
                                                            iii.      Remove all the other tags from the xml file and import the modified file using xmlaccess.
b.      Change all the dynamic-content spots in csa2.Mytech\theme.html and csa2.Mytech\nls\theme_en.html to point to the dynamic resources in your new WAR file.
                                                               i.      <link rel="dynamic-content" href="dyn-cs:id:head@tl:oid:csa2.theme"> replace with following   <link rel="dynamic-content" href="res:/Mytechtheme/themes/html/MytechTheme/head.jsp">
                                                             ii.      Do the same for the remaining jsp's using following path.
                res:/Mytechtheme/themes/html/MytechTheme/bannerNav.jsp
                res:/Mytechtheme/themes/html/MytechTheme/search.jsp
                res:/Mytechtheme/themes/html/MytechTheme/bannerCommonActions.jsp
                res:/Mytechtheme/themes/html/MytechTheme/status.jsp
                res:/Mytechtheme/themes/html/MytechTheme/tabNav.jsp
                res:/Mytechtheme/themes/html/MytechTheme/pageToolbar.jsp
                res:/Mytechtheme/themes/html/MytechTheme/asa.jsp
                res:/Mytechtheme/themes/html/MytechTheme/config.jsp
c.       Now use the WebDav client to upload the csa2.Mytech folder onto WebDav store at / fs-type1 url
  1. Assign MytechTheme theme to page (page properties-->select this theme)

Troubleshooting
Problem:  The context-root of your new web application can't be found
Solution: Make sure you started the new enterprise application.  Also, if you are accessing the portal via the Web server then make sure you re-generated the plugin file and distributed it to the web servers.  Also, make sure you mapped the WAR module to both your Portal server and your web server.

Problem: Your xmlacces import changed the base PageBuilder2 theme
Solution: Import the XML file from the export of all themes. This should restore all themes to their original state.

Problem: Updating the theme war after initial deployment causes errors (typically with com.ibm.wps.resolver.data.exceptions.URIProcessingIOException: EJCBD0021E)
Solution: Try changing the cache.expiration for themes and skins to 30 seconds on the WP Config Service resource environment provider (stop and restart portal). For example:

filestore.cache.expiration.0.re=themes/.*
filestore.cache.expiration.0.seconds=30

filestore.cache.expiration.0.re=skins/.*
filestore.cache.expiration.0.seconds=30

Sample XML Access for ExportAllSkin_Theme - https://www.box.com/s/948cb6bb4956ad1a4018
and for registering pagebuilder2 theme and skin -  https://www.box.com/s/4a768707faa3d1aaf1c7

Send an e-mail from Web Content Manager


Refer this link in case of your smtp server is running on default port 25 and authentication doesn't requre connection over ssl - http://www-01.ibm.com/support/docview.wss?uid=swg21314850

Since, configuration of Web Content Manager (WCMConfigService.properties) was not working due to  several issues including unavailable config attributes to set for extra parameter like starttls and custom smtp port.
So, I have used websphere inbuilt mail provider feature. I wrote servlet to lookup mail provider jndi and processed e-mail setup information within the servlet.

1)    Mail Provider Configuration

1)      Login to Websphere application server console
2)      Goto Resources > Mail > Mail Providers
3)      Click on 'built-in mail provider'
4)      Click on 'Mail sessions'
5)      Click on 'New' button
6)      Enter following details and save apply the changes, in this case I have configured my gmail account to receive user's feedback
                Name : feedback
                JNDI : mail/feedback
                Outgoing Mail properties
                                Server : smtp.gmail.com
                                Protocol : smtp
                                User:  <smtp_user>@gmail.com
                                Password: <password>
                                Verify Password : <password>
                                Return e-mail address : <smtp_user>@gmail.com
7)      Once saved, Click on 'feedback' entry and add following Custom property entries
                mail.smtp.port  : 587
                mail.smtp.starttls.enable  : true
                mail.smtp.auth : true (Note - this is only required in case of smtp requires authentication otherwise ignore this entry)
8)      Add smtp ssl certificate to application server trust store (required only if smtp is secured)
a)      Login to WebSphere Application server console.
b)      Go to Security > SSL certificate and key management.
c)       Click on ' Key stores and certificates'> 'NodeDefaultTrustStore' > ' Signer certificates'.
d)      Click on "retrieve from port".
e)      Provide following details and click on 'Retrieve signer information' button.
Host : smtp.gmail.com
Port : 465
Alias : smtp.gmail.com
f)       Click on 'Ok' and Save.

Note - If  smtp requires authentication then we  also need to provide an entry for smtp password in servlet 'SendMail'  init configuration parameter named 'smtp.password'.

2)    SendMail servlet to read mail provider settings

This servlet reads mail contents from request parameters along with on which portal page servlet should redirect after the processing the email. There are two additional parameters urile_success, urile_failure which servlet uses to show mail send or failure acknowledgement back to the user.
Parameter s 'urile_success' and 'urile_failure' contain path of wcm contents.
This servlet looks up for mail provider jndi 'mail/feedback' which was created in the first step.
If the smtp requires credentials to send  mail, it reads init parameter name ' smtp.password' from the deployment descriptor (web.xml)  for this  servlet.
This servlet is mapped with url-pattern /SendMail, which is resided within the theme project context root '/mytechtheme '.
So to access this servlet the URL will be : http://portal.mytech.com:10039/mytechtheme/SendMail

3)    Create an HTML form (wcm html component) to be used as an e-mail form

1)      Reference to the sendmail servlet is specified in the form's post action. This html form includes a hidden fields which helps servlet in redirection to a portal page. After the e-mail  is successfully submitted or if it fails, the form will be  redirected to a portal page.
Important Hidden Parameters are  :
                To : Receiver of the feedback email
                Redirect : Portal page friendly url
                urile_success :  WCM content path to show after the successfully delivering mail
                urile_failure : WCM content path to show in case mail delivery fails

<form name="myform" action="/mytechtheme/SendMail" method="post">
<table width="100%" cellspacing="0" cellpadding="2" border="0">
              <tbody><tr>
                <td width="50%"><h1>Contact Details</h1></td>
              </tr>
               <tr>
                <td style="height:5px"></td>
               </tr>
               <tr>
                 <td>Company Name <b class="redtxt">*</b></td>
               </tr>
               <tr>
                 <td><label>
                   <input type="text" class="input width200px" id="companyname" name="companyname">
                   </label>
                 </td>
               </tr>
               <tr>
                 <td>Email Address <b class="redtxt">*</b></td>
               </tr>
               <tr>
                 <td><input type="text" class="input width200px" id="fromemail" name="from"></td>
               </tr>
               <tr>
                 <td>Mobile Number</td>
               </tr>
               <tr>
                 <td><input type="text" class="input width200px" id="mobile" name="mobile"></td>
               </tr>
               <tr>
                 <td>Comments</td>
               </tr>
               <tr>
                 <td><label>
                   <textarea class="input width200px" rows="3" cols="20" id="contents" name="contents"></textarea>
                 </label></td>
               </tr>
               <tr>
                 <td class="note">All <span class="redtxt">*</span> fields are mandatory </td>
               </tr>
               <tr>
                 <td align="center"><label>
                   <!-- input type="image" src="media/images/btn.gif" name="button" id="button" value="Submit" onclick="submitForm()" / -->
                   <input type="submit" class="brownbtn" value="submit">
                 </label></td>
               </tr>
               <tr>
                <td>&nbsp;</td>
               </tr>
            </tbody></table>
<input type="hidden" name="to" value="shashi.rj@gmail.com"/>
<input type="hidden" name="subject" value="Contact Details"/>
<input type="hidden" name="redirect" value="[Component name="mytechtechnical/urlcomposer"]/mytech/contactus"/>
<input type="hidden" name="urile_success" value="wcm:path:/mytechContent/Internet/Contact Us/Contact Details Success"/>
<input type="hidden" name="urile_failure" value="wcm:path:/mytechContent/Internet/Contact Us/Contact Details Failure"/>
</form>
2)      Create AT name it 'AT_ContactDetails' and add component reference name it 'Com_Ref' to hold above create HTML Form 'Contact Form'
3)      Create a PT name it 'PT_ContactDetails' with following markup
[Element context="current" type="content" key="Com_Ref"]
4)      Now that the pieces are in place for the e-mail form, all we have to do is create the content and site area to hold them. First, create a new site area in your mytechContent library. Name it "Contact Us", and map the presentation and authoring template to the site area that you created.

Create Content named 'Contact Details' using AT 'AT_ContactDetails'. Select 'Contact Form' for com_ref element. There after save and publish this content.

5)      Configure the WCM Content Preview portlet to access the wcm content (Contact Details)
6)      Send e-mail and verify it works as expected.

 Servlet mapping in theme web.xml - 

<servlet>
        <description>
        </description>
        <display-name>SendMail</display-name>
        <servlet-name>SendMail</servlet-name>
        <servlet-class>com.mytech.mail.SendMail</servlet-class>
        <init-param>
            <description>
            </description>
            <param-name>smtp.password</param-name>
            <param-value></param-value>
        </init-param>
    </servlet>
    <servlet-mapping>
        <servlet-name>SendMail</servlet-name>
        <url-pattern>/SendMail</url-pattern>
    </servlet-mapping>

Servlet Source Code - https://www.box.com/s/dda990511fd603df1cf3

WCM search and Integrating with portal search


1.       Creating the WCM search collection
        1) Login to Portal Administration
        2) Goto Search Administration > Manage Search
        3) Click on 'Search Collections' > New Collections and provide following information
                        Location of collection : MytechCollection
                        Name of collection : MytechCollection
                        Description of Collection : MytechCollection
        4) Once saved, click on MytechCollection
        5) Create following Content Sources (MytechContent, BlogContents)
        6) Click on 'New Content Source' and provide following details to create MytechContent content sources
a.       Content Source Type : WCMSITE
b.      Content Source Name : MytechContent
c.       Collect documents linked from this URL : http://portal.Mytech.com:10039/seedlist/myserver?SeedlistId=MytechContent/Internet&Source=com.ibm.workplace.wcm.plugins.seedlist.retriever.WCMRetrieverFactory&Action=GetDocuments
      Note - Replace portal.Mytech.com with your portal server host name and MytechContent/Internet with your wcm sitearea
d.      Levels of links to follow: Unlimited
e.      Number of documents to collect: Unlimited
f.        Force Complete Crawl: true
g.       Stop collecting after (min):60
h.      Stop fetching a document after (sec): 20
i.         Links expire after (days): Unlimited
j.        Remove broken links after (days): 10
k.       Click on Security tab and enter portal admin credentials
                User Name : wpsadmin
                Password : wpsadmin
                Host Name : portal.Mytech.com
                Click on 'Create' button
                Click on Save button
                Note - Provide actual portal host and wpsadmin credentails
l.         Once saved, click on 'Start Crawler' button next to created content source entry
7) Search anonymously - to allow anonymous users to access the portal search collections, you need to Add Anonymous user to your Search Collection
Assign Anonymous Permission to MytechCollection
a)      Login to portal administration
b)      Goto Access > Resource Permissions
c)       Click on PSE Sources
d)      Click on 'Assign Access' button next to MytechCollection entry
e)      Edit User Role
f)       Add ' Anonymous Portal User' and ' All Authenticated Portal Users'
g)      Apply and done

2.       Rendering WCM search component results
WCM search component can also be used to display WCM search results.
There are several reasons you may decide to do this instead of using search center out of box portlet, some reasons:
o   Only WCM results will be displayed, meaning any non WCM assets in the search collection will be filtered out when using WCM search component.
o   Full control over the HTML display of the results.
o   Integration within a WCM site being rendered from the servlet.

To accomplish this, we have to create a piece of content that will hold both the search form and the results of the search. When a search is submitted the form will submit to the page for the results, which the form is also deployed to.

1)      Creating the Authoring Template
First, an authoring template for the content is necessary. Create an authoring template named "AT_Search", and use manage elements to add the following 3 elements:
query_form - a Component Reference
search_results - a Component Reference
text - a Text Componentck
2)      Creating the presentation template
Next we need to set up the presentation template to display the elements. Create a new presentation template named "PT_Search", and in the HTML put the following:
<p>[Element context="current" type="content" key="text"]</p>
<p>[Element context="current" type="content" key="query_form"]</p>
<p>[Element context="current" type="content" key="search_results"]</p>
3)      Creating the WCM search form
Now, we need to create the HTML component that will hold the html for the search form. Create a new HTML component named "HTML - Adv Search form", and enter the following HTML:

<form action='[PathCmpnt type="servlet"]/MytechContent/Internet/Search/Results' method="post" onSubmit="this.search_query.value=addFilter(this.query.value)">
<table>
<tr>
        <td>Search : </td>
        <td>
                        <input type="text" name="query" />
                        <input type="submit" value="Search" />
        </td>
</tr>
</table>
<input type=hidden name="search_query"/>
</form>

What the code does is setting up the form to submit to the MytechContent/Internet/Search/Results content (which we will create later), and puts the search_query in the form. The search_query is what gets processed by the WCM Search component as the search. We also limit results to exclude content that is using a specific authoring template, you would append this to the end of the search_query field. This means that when the search is performed, we limit results based on the content's authoring template.

Constructing search_query can easily be done using Javascript that executes on the form submit.
<script language="Javascript">
function addFilter(queryIn){
return queryIn + ' -AuthoringTemplate::"AT_Banner" -AuthoringTemplate::"AT_Search"';
}
</script>

4)      Creating the WCM search component
Next, we need the WCM search component to be created in order to display the search results. Create a new search component named "Search-Search Results". In the search options, select the MytechCollection for the Search collection: field. Also, use 10 for the results per page, as we will use a page navigation to page through the search results.

In the header field, enter the following:
[Component name="Mytechtechnical/search-result-navigation"]
<table>

In the results field, enter the following:
<tr>
        <td>
                        [AttributeResource attributeName="titleLink" separator=","]
                Date: [AttributeResource attributeName="date" format="MM/dd/yyyy" separator=","]
                        Relevance: ([AttributeResource attributeName="relevance" format="##.#" separator=","])
                        <br>
                        [AttributeResource attributeName="summary" separator=","]
        </td>
</tr>
For the footer:
</table>

For the Separator:
<tr>
        <td bgcolor="#FFFAA" colspand="2" />
</tr>

For No result design:
<div> No result found to display.</div>

5)      Creating the paging component
For the results to be paged, we create a simple paging component. Create a new 'page navigation' element named "Search-result-navigation". Use the following as a guide for the paging design for shuffle, paging, jump to page, and page size values to use.

Use the following as the guide for the value of the design elements of the paging component:


6)      Creating the necessary content and site framework
Now that the pieces are in place for the search components, all we have to do is create the content and site area to hold them. First, create a new site area in your MytechContent library. Name it "Search", and map the presentation and authoring template to the site area that you created.

Save and close the site area.

Secondly, create a new piece of content. Select the AT_Search authoring template, name the content "Results", For the Query Form item, select the HTML - Adv Search form component. For the Search Results, select the Search - Search Results component. In the text field, enter " Please select your search text and click the search button ":


Choose a workflow for your content, save and publish the content. As a last step, go back to the Search site area, and set this new content as the default content for the site area.

7)      Performing the search within the WCM search component
a) The easiest way to see the search in action is to preview the Results content. Click on the preview button, and the content will be displayed.
b) Create a portal page 'Search' and enter value 'wcmsearch' for friendly url. Click on 'Add Web Content Mapping' button and map your main sitearea as Web Content Folder.
Once page is created, click on edit page layout button and add ' Web Content Viewer (JSR 286)' portlet into this page. Configure 'Web Content Viewer (JSR 286)' portlet to wcm content 'Results'  from the edit shared settings option.

3.       Integrate WCM search component results with theme search box

Need to configure theme's themeSearchBox with WCM search component results.
Open the search.jsp of pagebuilder theme and modify ScopeSearchWidget as follows :
<div id="themeSearchBox" dojoType="ibm.portal.search.Enhanced.widgets.ScopeSearchWidget" displayScopes="false" submitUrl="?1dmy&urile=wcm%3apath%3a/MytechContent/Internet/Search/Results" resourceBundle="<portal-fmt:out><searchmenu:resourceBundle bundleName="com.ibm.lotus.search.taglib.ScopeSearchWidget"/></portal-fmt:out>" sourceContentNode="<searchmenu:currentContentNode/>" searchFeedUrl="'<searchmenu:generateSearchFeedUrl/>'" timeStamp="<searchmenu:scopesLastUpdateTime/>"></div>

Following javascript function is added to create search_query hidden input filed dynamically on submit of the themeSearchBox form. This filed store and forward user entered search query to WCM search component.

<script language="Javascript">
dojo.addOnLoad(function(){
        dojo.connect(dojo.byId("themeSearchBox"), "onsubmit", function(event){
                        search_query=dojo.doc.createElement("input");
                        dojo.attr(search_query, "name","search_query");
                        dojo.attr(search_query, "type","hidden");
                        dojo.attr(search_query, "value",addFilter(this.query.value));
                        this.appendChild(search_query);
        });
});
</script>