+

Search Tips   |   Advanced Search

Aggregator patterns and samples

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


JavaScript module pattern template

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 notifications sent by the SiteAnalyticsMediator. It complies with the function signature defined by the Active Site Analytics Mediator SPI. Use this function to parse the DOM to find the analytics-specific microformats that interest you. Typically, the parse function stores the found microformats in an internal bucket, for example a JSON object, 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 toinitiate 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.

The registration aspect and the logic 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 the 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 submit the data internally using the aggregator. For example, we can submit data upon receiving a notification or based on the internal state of the aggregator. Or we can trigger data submission from outside based on an external event. This decision can depend on the business model of the external analytics service provider. See 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. The time-based solution sends the data periodically. We can also combine the two approaches.

To use 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 client-side aggregation rendering for the portal pages, full page refreshes and therefore DOM unload events do not occur 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 API 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 action means the data is submitted every 30 seconds at the latest if no beforeunload event is received.

// 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 we have Ajax applications on the portal sites that change markup dynamically using JavaScript, we need to notify the SiteAnalyitcsMediator framework manually. We can notify by calling the notify() function provided by the SiteAnalyticsMediator object.

// determine the root nodes of the DOM subtrees that have changed
var nodes = ...;   com.ibm.portal.analytics.SiteAnalyticsMediator.notify(nodes, callback);


Aggregator samples

WebSphere Portal provides several sample aggregators. They are in...

Although the provided sample code does not require any special JavaScript library, we might want to use the JavaScript framework of the choice. With the JavaScript framework, we can reduce the size and complexity of the aggregator implementations. And the JavaScript framework might support you in achieving a good performance. To explain the concepts 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:

    CoremetricsAggregator.js

    This sample aggregator collects the analytics data and sends it to the IBM Digital Analytics (formerly Coremetrics) service.

    It uses a Coremetrics specific JavaScript API to submit the data. We need to configure this API as an aggregator dependency. The target URL is http://libs.coremetrics.com/eluminate.js. Before use the aggregator, we also need to edit the aggregator code to specify the Coremetrics client ID, cookie domain, and data collection domain.

    SampleAggregator.js

    This aggregator is a generic aggregator. It collects all the analytics data and sends it to the URL http://example.org using a tracking image. The collected data is appended to the image URL as a query string. The names of the URL parameters correspond with the microformat names as defined in Supported aggregator tags.


Parent Write an aggregator for Active Site Analytics

Related tasks:
Add an Active Site Analytics aggregator to a portal page
Guidelines for implementing an aggregator
Supported aggregator tags