Category Archives: Programming Notes

Removing Extra Space Underneath An Image

You have already applied normalize.css but there is still additional white space underneath an image. This is because the browsers by default will recognize the images as an inline-element, hence additional “line-height” is apply.

For example, key in the following html:


<div style='border:1px solid red;'>
 <img src='marvel.jpg'/>
</div>

Noticed that extra space (line-height)?

Solution:

  1. Either add in “display:block” to the image
    <div style='border:1px solid red;'>
     <img src='marvel.jpg' style='display:block;'/>
    </div>
    
  2. Or add in “line-height:0” to the containing dom
    <div style='line-height:0;border:1px solid red;'>
     <img src='marvel.jpg'/>
    </div>
    

Notes on Regular Expression

  1. What is the difference between “*” and “+”?
    “*” will match the character zero or more times whereas “+” will match one or more times. For example, “\d*” regular expression will return the following results for:

    • 2b – will match “2b”
    • 3ab – will match “b” (since digit character is optional)

    Now consider “\d+” regular expression:

    • 2b – will still match “2b”
    • 3ab – will not return any match as “+” required one or more times matches.
  2. <continue…>

Javascript: How to Calculate Number of Working Days?

Date.workingDaysFrom(fromDate) calculates the number of working days between 2 Date objects (excluding weekends; Sat and Sun). The method will return “-1” if the fromDate is an invalid Date object or is later than the compared Date.

Do take note that this method does not take public holidays into consideration and each date is consider as a full day.

Date.prototype.workingDaysFrom=function(fromDate){
 // ensure that the argument is a valid and past date
 if(!fromDate||isNaN(fromDate)||this<fromDate){return -1;}

 // clone date to avoid messing up original date and time
 var frD=new Date(fromDate.getTime()),
     toD=new Date(this.getTime()),
     numOfWorkingDays=1;

 // reset time portion
 frD.setHours(0,0,0,0);
 toD.setHours(0,0,0,0);

 while(frD<toD){
  frD.setDate(frD.getDate()+1);
  var day=frD.getDay();
  if(day!=0&&day!=6){numOfWorkingDays++;}
 }
 return numOfWorkingDays;
};

 

Examples

Comparing 8-Jul-2015 (Wed) to 13-Jul-2015 (Mon)

var startDate = new Date("8/8/2015");
var endDate = new Date("13/8/2015");
endDate.workingDaysFrom(startDate); // returns 4

Comparing same date, 8-Jul-2015 (Wed)

var startDate = new Date("8/8/2015");
var endDate = new Date("8/8/2015");
endDate.workingDaysFrom(startDate); // returns 1

 

How to Generate Facebook Access Token for Public Page Feed?

Most clients would prefer a customized Facebook feed (especially those supporting multiple social media) , hence this bring us to this question:

“What is the easiest method to generate a Facebook access token just to retrieve their public page feed?”

A simple step is to create an “empty” Facebook application and use its access token (note that most likely the UI is going to change but the idea is there):

  1. Go to https://developers.facebook.com/apps/
  2. Go to “Add a New App” (My Apps > Add a New App).
  3. Select “WWW” (or any) and click on “Skip and Create App ID”.
  4. Give the application a suitable name and namespace for future reference.
  5. Grats! You have generated your own access token! For secret key, remember to click on the “Show” button.
  6. To verify, key in the following url and you should be able to see the public page feed:
    https://graph.facebook.com/v2.3/<page id>/posts?access_token=<App ID – as shown in above image>|<App Secert>

WebSphere: How to Access Portal Theme Tags in JSP?

Add “<%@ taglib uri=”/WEB-INF/tld/portal.tld” prefix=”portal” %>” in order to access the portal theme tags like “<portal-logic/>” and “<portal-navigation/>“.

To call the tag function, simply call <portal:<function name>/>. For example in portal theme, we would call:


<portal-logic:if loggedIn="yes">...</portal-logic:if>

to


<portal:if loggedIn="yes">...</portal:if>

WebSphere Portal is Throwing “Could not load ‘dojo.nls.dojo_en'” error

We have logged a PMR with IBM recently about the browser is complaining that it could not load ‘dojo.nls.dojo_en’.

could not load dojo.nls.dojo_en

And IBM official response is to apply Deferred with Dojo (“profiles/profile_deferred.json”) theme profile directly to the page and this resolves the issue for me.

How to apply “Deferred with Dojo” profile:

  1. At the front-end, turn on the “Edit Mode“.
  2. Click on Menu (below Edit Mode) > Edit Page Properties.
  3. Click on the Advanced tab and select “Deferred with Dojo” Profile.
  4. Click on the “Save” button.

 

Note: A simple method (which I like) is to add in “resourceaggregation.profile” page property and set “profiles/profile_dojo_deferred.json” as its value.

 

WebSphere Portal: Using WCM_API for Selected Virtual Portal

I was writing a live-feed migration portlet (AJAX) for my client when I realized that calling Workspace in Servlet is actually pointing to the base portal (which somehow makes sense). Hence I checked WCM API for updates and that was where I found Repository.generateVPContextFromHostname and Repository.executeInVP methods. The methods look promising but I have no idea how to call it until I found Philip Cheshire’s blog. Credits goes to him!

Do note that objects taken out from executeInVP method will not be able to access their repository and all actions will be performed as if the item belonged to the base portal workspace. There is one instance where I wrote a VirtualPortalScopedAction object to return only the Workspace and that is how I realized that the Workspace is “referencing” back to the default base repository.

Below illustrate a simple example on how to retrieve Authoring Template’s DocumentId from a specific Virtual Portal

In Our Servlet:


@WebServlet("/ProcessCircular")
public class ProcessCircular extends HttpServlet {
 public ProcessCircular() {
  super();
  try {
   Repository repository = WCM_API.getRepository();
   VirtualPortalContext vpc = repository.generateVPContextFromHostname(MigrationScriptPortlet.VIRUTAL_PORTAL_HOSTNAME);

   // retrieve AT document id
   VPScopedActionAT vpsAT = new VPScopedActionAT();
   repository.executeInVP(vpc, vpsAT);
   DocumentId atId = vpsAT.docId; // this is the part where we take object out from executeInVP
  } catch (WCMException e) {
   // ...
  }
 }
}

 

Then we proceed to create VPScopedActionAT that implements VirtualPortalScopedAction:

public class VPScopedActionAT implements VirtualPortalScopedAction {
 public DocumentId docId;

 @Override
 public void run() throws WCMException {
  Repository repository = WCM_API.getRepository();
  Workspace ws = repository.getSystemWorkspace();
  ws.setCurrentDocumentLibrary(ws.getDocumentLibrary(MigrationScriptPortlet.CONTENT_LIB));
  DocumentLibrary docLib = ws.getDocumentLibrary("Corporate");

  DocumentIdIterator atIter = ws.findByName(DocumentTypes.AuthoringTemplate, MigrationScriptPortlet.CIRCULAR_AT);
  if (atIter.hasNext()) {
   docId = atIter.next();
  }
  repository.endWorkspace();
 }
}

Where is WebSphere Portal Jars?

Below is the jars file location for WebSphere Portal 8.5 SPI.

ilwwcm-api.jar 
Reside at <PortalServer>/wcm/prereq.wcm/wcm/shared/app/ilwwcm-api.jar
It is responsible for the following classes:

  • com.ibm.workplace.wcm.api.*

wp.model.api.jar 
Reside at <PortalServer>/base/wp.model.api/shared/app/wp.model.api.jar
It is responsible for the following classes:

  • com.ibm.portal.state.accessors.pagemode.*

wp.resolver.friendly.api.jar
Reside at <PortalServer>/base/wp.resolver/wp.resolver.friendly.api/shared/app/wp.resolver.friendly.api.jar
It is responsible for the following classes:

  • com.ibm.portal.resolver.friendly.*

wp.services.api.jar
Reside at <PortalServer>/base/wp.services.api/shared/app/wp.services.api.jar
It is responsible for the following classes:

  • com.ibm.portal.services.project.*

Just drop us a comment if you need to find out the jar location of any WebSphere Portal classes.