+

Search Tips   |   Advanced Search

Aggregator patterns and samples


This section provides common aggregator patterns and samples that we might want to adopt to implement our own aggregator.


JavaScript module pattern template

We can use the following JavaScript module pattern as a general template:

/**
 * Check if the aggregator module is already defined.
 */
if (typeof(ibm_analytics_MyAggregator) === "undefined") 
{

    /**
     * Function to construct the aggregator
     */

    ibm_analytics_MyAggregator = function(/* Arguments needed internally */) 
    {
      /**
      * The aggregator instance    */
      var aggregator = {};

      // define the internal variables
      var a = ...;
      var b = ...;
      // ...
      /**

   * Public function which parses the given DOM nodes to detect    
   * the microformats the aggregator is interested in.
   */
  aggregator.parse = function(/*DOMNode[]*/ nodes, /*Function?*/ callback) 
  {
    // check if a specific part of the DOM should be parsed
    if (nodes && nodes.length > 0) {
      /*
       * Page element notification
       */
      // invoke the internal parsing code here       // 
      ...
    } else {
      /*
       * Page notification
       */
      // invoke the internal parsing code here       // 
      ...
    }
    // invoke the callback (if any)
    if (callback) {
      callback();
    }
  };

  /**
   * Public function to submit the collected data to the  * analytics service.
   */
  aggregator.submit = function() {
    // send the collected data off to the external analytics service     
    // use the preferred technique here (tracking image, XHR etc.)
    // ...
  };
     // define the internal functions   
     var parseNode = function(/*DOMNode*/ node) {
    // ...
  };

  // ...

  // return the aggregator
  return aggregator;
   };

};
By using this pattern, the aggregator module exports two functions:

  1. The parse() function is responsible for handling the DOM notificatione sent by the SiteAnalyticsMediator. It complies with the function signaturdefined by the Active Site Analytics Mediator SPI as discussed in the topic about The Active Site Analytics Mediator SPI. Use this function to parse the DOM to find the analytics-specific microformato that interest you. Typically, the parse function stores the found microformats in an internal bucket, for example a JSON objects that is transmitted to the external analytics service later on. In the JavaScript module pattern template we can also see how the aggregator can distinguish between page notifications and page element notifications (a page element can either be a portlet or an Ajax component).

  2. The submit() function is responsible for sending the collected data to the external analytics service. Use the preferred technique to initiate an HTTP request which carries the data to the analytics service. For performance reasons, communicate the data asynchronously, for example by a tracking image or an asynchronous XmlHTTPRequest.
Note that the registration aspect and the logis that triggers the data transmission are not part of the aggregator module. These aspects need to be handled outside of the aggregator module.


Registering with the Site Analytics Mediator

Register your parse() function with the Site Analytics Mediator immediately after the definition of the aggregator module:

// instantiate and initialize the aggregator
var ibm_analytics_aggregator = new ibm_analytics_MyAggregator(/* arguments as needed...*/);
// register the parse function of the aggregator with the mediator
com.ibm.portal.analytics.SiteAnalyticsMediator.register(function() {
  ibm_analytics_aggregator.parse.apply(ibm_analytics_aggregator, arguments);
});


Submitting the analytics data

We can submit the data in various ways. We can do this internally using the aggregator, for example upon receiving a notification or based on the internal state of the aggregator, or we can trigger it from outside based on an external event. Remember that this decision can depend on the business model of the external analytics service provider. For more details, refer to topic about Guidelines for implementing an aggregator.

To trigger the data submission based on an external event, we can either use the DOM beforeunload event of the browser or a time based solution that sends the data periodically. We can also combine the two approaches.

To exploit the DOM beforeunload event of the browser, subscribe to the beforeunload event using the submit() function of the aggregator as shown by the following sample:

// instantiate and initialize the aggregator
var ibm_analytics_aggregator = new ibm_analytics_MyAggregator(/* arguments...*/);

// register the parse function of the aggregator with the mediator
com.ibm.portal.analytics.SiteAnalyticsMediator.register(function() 
{ 
    ibm_analytics_aggregator.parse.apply(ibm_analytics_aggregator, arguments); });
    // callback function to submit the collected data to the external analytics service 
    var ibm_analytics_MyAggregator_submit = function() 
    {
        ibm_analytics_aggregator.submit.apply(ibm_analytics_aggregator, arguments);
    }
    // register the callback functions 
    if (window.addEventListener) 
    {
      // W3C
      window.addEventListener("beforeunload", ibm_analytics_MyAggregator_submit, false);
    } else if (window.attachEvent) 
    {
      // Microsoft
      window.attachEvent("onbeforeunload", ibm_analytics_MyAggregator_submit);
}
If we use mainly client side aggregation rendering for the portal pages, full page refreshes and therefore DOM unload events do not occur very often. In this case and with this approach, the aggregator collects data for a long time without sending the collected data to the external analytics service. To avoid this behavior, we can combine the unload approach with a time based approach.

For example, we can submit the collected data periodically, in addition to sending it off upon receiving a beforeunload event. To implement the periodic data submission, use the setInterval() JavaScript AP that all major browsers provide. In this case you register the submit() function as the interval handler within the onload handler. The following code sample uses a time interval of 30 seconds. This means that the data is submitted every 30 seconds at the latest if no beforeunload event is received before that.

// instantiate and initialize the aggregator
var ibm_analytics_aggregator = new ibm_analytics_MyAggregator(/* arguments...*/);

// register the parse function of the aggregator with the mediator
com.ibm.portal.analytics.SiteAnalyticsMediator.register(function() {
  ibm_analytics_aggregator.parse.apply(ibm_analytics_aggregator, arguments);
});

// callback function to initialize and register the aggregator
var ibm_analytics_MyAggregator_init = function() {
  // register the interval handler   setInterval(ibm_analytics_MyAggregator_submit, 30000);
};

// callback function to submit the collected data to the external analytics service 
var ibm_analytics_MyAggregator_submit = function() {
  ibm_analytics_aggregator.submit.apply(ibm_analytics_aggregator, arguments);
}

// register the callback functions if (window.addEventListener) {
  // W3C
  window.addEventListener("load", ibm_analytics_MyAggregator_init, false);
  window.addEventListener("beforeunload", ibm_analytics_MyAggregator_submit, false);
} else if (window.attachEvent) {
  // Microsoft
  window.attachEvent("onload", ibm_analytics_MyAggregator_init);
  window.attachEvent("onbeforeunload", ibm_analytics_MyAggregator_submit);
}
If you have Ajax applications on the portal sites that change markup dynamically using JavaScript, you need to notify the SiteAnalyitcsMediator framework manually. We can do this by calling the notify() function that the SiteAnalyticsMediator object provides:
// determine the root nodes of the DOM subtreethat have changed 
var nodes = ...;   
com.ibm.portal.analytics.SiteAnalyticsMediator.notify(nodes, callback);


Aggregator samples

WebSphere Portal provides several sample aggregators. They are located in the PORTAL_HOME/doc/js-samples directory of the portal installation. Although the provided sample code does not require any special JavaScript library, we might want to use the JavaScript framework of the choice. This allows us to reduce the size and complexity of the aggregator implementations and might support you in achieving a good performance. To explain the concepto that are discussed in the previous topics, the sample aggregators are simplified with regards to the data that is evaluated. We can install each of the provided sample aggregators on WebSphere Portal as described in the topic about Add an Active Site Analytics aggregator to a portal page. WebSphere Portal provides the following sample aggregators:


Parent: Write an aggregator for Active Site Analytics
Related:
Add an Active Site Analytics aggregator to a portal page
Related reference:
The Active Site Analytics Mediator SPI
Guidelines for implementing an aggregator
How to identify and resolve problems with the aggregator
Supported aggregator tags