Google Analytics: uP v4.0.0 - 4.0.3

Currently this documentation is only suited for the following versions of uPortal: 4.0.0 - 4.0.3. Click on the 'Tools' link (upper right corner) to download attached files.

Documentation courtesy of Bill Brown, Web Application Developer, from The University of Chicago

Google Analytics page and event tracking can be setup in uPortal. The example below uses the analytics tracking API (http://code.google.com/apis/analytics/docs/tracking/home.html),
a java filter and a uPortal IParameterProcessor to achieve session based tracking of portal events for users of a uPortal instance.

The example can be adapted for your institutions requirements by swaping in different user attributes.

Step 1: Replace File

  • Replace ../uportal-war/src/main/java/org/jasig/portal/rendering/xslt/PreferencesTransformerConfigurationSource.java with the attached PreferencesTransformerConfigurationSource.java file below.

This enhanced version makes the class concrete and implements the j2EE Filter interface. The file is used as a base class for beans used in the rendering pipeline process configured in renderingPipelineContext.xml. No additional configuration in renderingPipelineContext.xml is necessary.

Step 2: Import Stylesheet Descriptor File

If you have already done the database setup for your portal instance the data-import will overwrite what is in the database. The DLMXHTML.stylesheet-descriptor.xml  file is part of the required data that needs to be imported for uPortal 4 to work and it is found here in the release: uportal-war/src/main/data/required_entities/stylesheet-descriptor 

  • Using the data-import tool, re-import the attached stylesheet descriptor file, DLMXHTML.stylesheet-descriptor.xml (attached below). 

ant data-import -Dfile=/path/to/DLMXHTML.stylesheet-descriptor.xml 

The file adds/registers the extra custom parameters to the system so they can be modified within the rendering pipeline process. They are declared in /uportal-war/src/main/resources/layout/theme/universality/universality.xsl as <xsl : param name="xyz"/> and used in page.xsl as variables to populate some of the analytics data describe below and also to conditionally render some of the javascript.

Step 3: Configure web.xml

  • Configure the filter in web.xml with the following information:
uportal-war/src/main/webapp/WEB-INF/web.xml
<filter>
     <filter-name>UocCustomizations</filter-name>
     <filter-class>org.jasig.portal.rendering.xslt.PreferencesTransformerConfigurationSource</filter-class> 
</filter>  

<filter-mapping> 
      <filter-name>UocCustomizations</filter-name> 
      <url-pattern>/uocCustomizations</url-pattern> 
</filter-mapping>   

 

Step 4: Add Parameters

  1. Open universality.xsl for editing located at ../uportal-war/src/main/resources/layout/theme/universality/universality.xsl
  2. At the top of the file where the other parameters of the page are set including the standard “USER_ID” we add the following three parameters:
  <xsl:param name="affiliations"/>
  <xsl:param name="serverEnv"/>
  <xsl:param name="sessionDataRan"/>

affiliations is a user attribute we use to recognize the logged in user’s affiliation to the institution and has values such as “Student”, “Faculty” or “Staff” or a combination of more than one of these. You'll see in the java file that this is an example of a multi valued person attribute. This is a good place to substitute what you want to track for your institution.

serverEnv is a variable we are using to track which server environment we are tracking data for in Google analytics.

For example we use development, staging and production environments. We have a Google analytics account for each environment for a total of three distinct environments.

sessionDataRan is a variable used in the xsl to control when to output once-per-session javascript in the page. This is key to tracking some of the data we are interested in within the Google analytics.

Step 5: Add Google Analytics code

  1. Add the two following code snippets to /uportal-war/src/main/resources/layout/theme/universality/page.xsl

This section sets up asynchronous google analytics tracking. The following GA javascript snippets are needed at the beginning and bottom of the page.xsl file respectively.
It makes use of the “serverEnv” to create a tracker for one of the three the server environments (development, staging and production) running the code.

  • At the top of page.xsl use the following javascript code:
        <script type="text/javascript"> 
           <xsl:choose> 
             <xsl:when test="$serverEnv='my.uchicago.edu'"> 
               var env = "<xsl:value-of select="$serverEnv" />"; 
               var gaAcct = "UA-xxxxxxx-1";
             </xsl:when> 
             <xsl:when test="$serverEnv='mystage.uchicago.edu'"> 
               var env = "<xsl:value-of select="$serverEnv" />"; 
               var gaAcct = "UA-xxxxxxx-4"; 
             </xsl:when> 
             <xsl:otherwise> 
              var env = "<xsl:value-of select="$serverEnv" />"; 
              var gaAcct = "UA-xxxxxxxx-2"; 
             </xsl:otherwise> 
            </xsl:choose> 
                 var _gaq = _gaq || []; 
                 _gaq.push(['_setAccount', gaAcct],['_setDomainName', env],['_trackPageview']); 
    
           (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); 
            })
           (); 
         </script> <!-- end UofC Customization: Add google analytics section. --> 

 

  • At the bottom of page.xsl, just before the closing body tag, you should add this snippet:
<!-- UofC Customization --> 
 <xsl:if test="$sessionDataRan!='yes'"> 
     <script type="text/javascript"> 
        var uocCustomizations = up.jQuery.noConflict(true); 
        uocCustomizations(document).ready(function(){ 
          var affiliations = "<xsl:value-of select="$affiliations" />".split(";"); 
          for ( var i in affiliations ){ 
           _gaq.push(['_trackEvent','Person','<xsl:value-of select="$USER_ID" />',affiliations[i]]); 
          } 
          for ( var i in affiliations ){ 
            _gaq.push(['_trackEvent','Affiliation',affiliations[i],'<xsl:value-of select="$USER_ID" />']); 
          } //ajax call to set the 1 time session variable. 
          uocCustomizations.get('https://<xsl:value-of select="$serverEnv" />/uPortal/uocCustomizations'); 
        }); 
     </script> 
  </xsl:if> 
 </body> 
 </html> 
 

Step 6: Add tracking

Once the tracking api is loaded, we place tracking code on any of the user initiated events we want to track during their session.

For example, in the sections below we are tracking these events: portlet minimize, portlet maximize, portlet removed, change portlet tab, add content, add tab and customize tab layout.

Components.xsl

<a id="contentDialogLink" onclick="_gaq.push(['_trackEvent', 'Portal','ADD CONTENT']);" href="javascript:;"
    						title="{$TOKEN[@name='PREFERENCES_LINK_ADD_CONTENT_LONG_LABEL']}">
    						<span><xsl:value-of select="$TOKEN[@name='PREFERENCES_LINK_ADD_CONTENT_LABEL']"/></span>
    					</a>

...
<a id="layoutDialogLink" onclick="_gaq.push(['_trackEvent', 'Portal','TAB LAYOUT']);" href="javascript:;"
    						title="{$TOKEN[@name='PREFERENCES_LINK_LAYOUT_LONG_LABEL']}">
    						<span><xsl:value-of select="$TOKEN[@name='PREFERENCES_LINK_LAYOUT_LABEL']"/></span>
    					</a>
...
<a id="addTabLink" onclick="_gaq.push(['_trackEvent', 'Portal','ADD TAB']);" href="javascript:;"
                    		title="{$TOKEN[@name='PREFERENCES_LINK_ADD_TAB_LONG_LABEL']}">
                    		    <span><xsl:value-of select="$TOKEN[@name='PREFERENCES_LINK_ADD_TAB_LABEL']"/></span>
                    		</a>

 
Content.xsl

      <xsl:if test="not(@hasHelp='false')"> <!-- Help. -->
      	<a onclick="_gaq.push(['_trackEvent','Portlet', '{$PORTLET_TITLE}-Help']);" href="{$BASE_ACTION_URL}?uP_help_target={@ID}#{@ID}"
          title="{$TOKEN[@name='PORTLET_HELP_LONG_LABEL']}" class="up-portlet-control help">
      	  <span><xsl:value-of select="$TOKEN[@name='PORTLET_HELP_LABEL']"/></span>
        </a>
      </xsl:if>

      <xsl:if test="not(@hasAbout='false')"> <!-- About. -->
      	<a onclick="_gaq.push(['_trackEvent','Portlet', '{$PORTLET_TITLE}-About']);" href="{$BASE_ACTION_URL}?uP_about_target={@ID}#{@ID}"
          title="{$TOKEN[@name='PORTLET_ABOUT_LONG_LABEL']}" class="up-portlet-control about">
      	  <span><xsl:value-of select="$TOKEN[@name='PORTLET_ABOUT_LABEL']"/></span>
        </a>
      </xsl:if>

      <xsl:if test="not(@editable='false')"> <!-- Edit. -->
      	<a onclick="_gaq.push(['_trackEvent','Portlet', '{$PORTLET_TITLE}-Edit']);" href="{$BASE_ACTION_URL}?uP_edit_target={@ID}#{@ID}"
          title="{$TOKEN[@name='PORTLET_EDIT_LONG_LABEL']}" class="up-portlet-control edit">
      	  <span><xsl:value-of select="$TOKEN[@name='PORTLET_EDIT_LABEL']"/></span>
        </a>
      </xsl:if>

      <xsl:if test="@printable='true'"> <!-- Print. -->
      	<a onclick="_gaq.push(['_trackEvent','Portlet', '{$PORTLET_TITLE}-Print']);" href="{$BASE_ACTION_URL}?uP_print_target={@ID}#{@ID}"
          title="{$TOKEN[@name='PORTLET_PRINT_LONG_LABEL']}" class="up-portlet-control print">
      	  <span><xsl:value-of select="$TOKEN[@name='PORTLET_PRINT_LABEL']"/></span>
        </a>
      </xsl:if>

      <xsl:if test="not(//focused) and @minimized='false'"> <!-- Focus. -->
        <!-- UNCOMMENT FOR MINIMIZE CONTROL -->
        <a onclick="_gaq.push(['_trackEvent','Portlet', '{$PORTLET_TITLE}-Minimize']);"
           href="{$BASE_ACTION_URL}?uP_root=root&amp;uP_tcattr=minimized&amp;minimized_channelId={@ID}&amp;minimized_{@ID}_value=true&amp;uP_save=all"
           title="{$TOKEN[@name='PORTLET_MINIMIZE_LONG_LABEL']}" class="up-portlet-control minimize">
          <span><xsl:value-of select="$TOKEN[@name='PORTLET_MINIMIZE_LABEL']"/></span>
        </a>

      	<a onclick="_gaq.push(['_trackEvent','Portlet', '{$PORTLET_TITLE}-Maximize']);" href="{$BASE_ACTION_URL}?uP_root={@ID}"
          title="{$TOKEN[@name='PORTLET_MAXIMIZE_LONG_LABEL']}" class="up-portlet-control focus">
      	  <span><xsl:value-of select="$TOKEN[@name='PORTLET_MAXIMIZE_LABEL']"/></span>
        </a>
      </xsl:if>

      <xsl:if test="@minimized='true'"> <!-- Return from Minimized. -->
        <!-- UNCOMMENT FOR UNMINIMIZE CONTROL -->
        <a onclick="_gaq.push(['_trackEvent','Portlet', '{$PORTLET_TITLE}-UnMinimized']);"
           href="{$BASE_ACTION_URL}?uP_root=root&amp;uP_tcattr=minimized&amp;minimized_channelId={@ID}&amp;minimized_{@ID}_value=false&amp;uP_save=all"
           title="{$TOKEN[@name='PORTLET_RETURN_LONG_LABEL']}" class="up-portlet-control return">
          <span><xsl:value-of select="$TOKEN[@name='PORTLET_RETURN_LABEL']"/></span>
        </a>

      </xsl:if>

      <xsl:if test="not(@dlm:deleteAllowed='false') and not(//focused) and /layout/navigation/tab[@activeTab='true']/@immutable='false'"> <!-- Remove. -->
      	<a onclick="_gaq.push(['_trackEvent','Portlet', '{$PORTLET_TITLE}-Removed']);" id="removePortlet_{@ID}"
           title="{$TOKEN[@name='PORTLET_REMOVE_LONG_LABEL']}" href="{$BASE_ACTION_URL}?uP_remove_target={@ID}"
           class="up-portlet-control remove">
      	  <span><xsl:value-of select="$TOKEN[@name='PORTLET_REMOVE_LABEL']"/></span>
        </a>
      </xsl:if>

      <xsl:if test="//focused"> <!-- Return from Focused. -->
        <a onclick="_gaq.push(['_trackEvent','Portlet', '{$PORTLET_TITLE}-UnMaximize']);" href="{$HOME_ACTION_URL}"
          title="{$TOKEN[@name='PORTLET_RETURN_LONG_LABEL']}" class="up-portlet-control return">
      	  <span><xsl:value-of select="$TOKEN[@name='PORTLET_RETURN_LABEL']"/></span>
        </a>
      </xsl:if>

      <xsl:if test="//focused[@in-user-layout='no'] and upGroup:isChannelDeepMemberOf(//focused/channel/@fname, 'local.1')"> <!-- Add to layout. -->
        <a onclick="_gaq.push(['_trackEvent','Portlet', '{$PORTLET_TITLE}-Add']);" id="focusedContentDialogLink" href="javascript:;"
          title="{$TOKEN[@name='PORTLET_ADD_LONG_LABEL']}" class="up-portlet-control add">
          <span><xsl:value-of select="$TOKEN[@name='PORTLET_ADD_LABEL']"/></span>
        </a>
      </xsl:if>

Navigation.xsl

<xsl:for-each select="tabChannel">
    <li>
       <a onclick="_gaq.push(['_trackEvent', 'Portal','{@name}']);" href="{$BASE_ACTION_URL}?uP_root={@ID}&amp;uP_sparam=activeTab&amp;activeTab={$TAB_POSITION}"
         title="{@name}">  <!-- Navigation item link. -->
         <span><xsl:value-of select="@name"/></span>
       </a>
     </li>
 </xsl:for-each>

Step 7: Rebuild/Redeploy uPortal

After adding all of your tracking code, you should rebuild and redeploy your portal.

Step 8: Restart Tomcat

It will take 24 hours for you tracking code to show up in the portal.

 

The Attachments are NOT compatible with prior versions of uPortal, it is only compatible with the uPortal 4.0.0 - 4.0.3 version.

  File Modified

Java Source PreferencesTransformerConfigurationSource.java

May 15, 2012 by Laura McCord

XML File DLMXHTML.stylesheet-descriptor.xml

May 15, 2012 by Laura McCord

 

Having problems with these instructions?

Please send us feedback at uportal-user@lists.ja-sig.org


 

 

 

Add Feedback content box here.....