Jasig Spring 2010 Tab Tags

36
Implementing Multi-Level Navigation in uPortal JASIG Spring 2010 Conference

description

Hello, here are the slides to the presentation "Implementing Multi-leve Navigation in uPortal"

Transcript of Jasig Spring 2010 Tab Tags

Page 1: Jasig Spring 2010 Tab Tags

Implementing Multi-Level Navigation in uPortal

JASIG Spring 2010 Conference

Page 2: Jasig Spring 2010 Tab Tags

Basic Problem…

• Sizable Multi-Campus implementation with hundreds of portlet publications

• Governance is very distributed, and there is a lot of content that the committees want provided by default

• How do we organize this information in a usable way?

Page 3: Jasig Spring 2010 Tab Tags

Lesson Learned

• In uPortal 2, we implemented a subtab structure to support this

• This required a lot of custom code• This was a structural change that

made our uPortal 3 upgrade much more difficult

• The import/export scripts had to be changed and augmented to account for the new level of hierarchy in the layout

Page 4: Jasig Spring 2010 Tab Tags

Things to Consider

• Tab Carousels– suffer from an out of sight out of mind

dilemma– still have a usability issue, when tab

numbers are high… how many tabs will a user scroll through?

• Click counts– how do we get people to what the need

quickly?

Page 5: Jasig Spring 2010 Tab Tags

Revelation

• One of the things our users like is the ability to find things at a glance and drill down for more detail

• We needed a new approach that would provide the same functionality without the upgrade and maintenance headaches

• Jeff conceptualized tabTags…

Page 6: Jasig Spring 2010 Tab Tags

The tabTag Approach• Does not change the structure of

the layout XML• Uses out-of-box uPortal “structure

attribute” functionality to track tags associated with at tab

• Is implemented via an optional new theme

Page 7: Jasig Spring 2010 Tab Tags

The tabTag Approach

• Requires minimal code enhancements (to remember the selected tab)

• Has no code changes that break the out-of-box uPortal theme

• Quickly became a clear choice to meet our needs

Page 8: Jasig Spring 2010 Tab Tags

Currently, uPortal only has single level navigation at the tab level.

I am logged in as the staff user on the default uPortal32 install.

Page 9: Jasig Spring 2010 Tab Tags
Page 10: Jasig Spring 2010 Tab Tags
Page 11: Jasig Spring 2010 Tab Tags

So how do we produce multi-level navigation?

In this screenshot the Admin “tab container” is a navigational constructwhich contains three tabs: Development, Testing, Admin Tools

Page 12: Jasig Spring 2010 Tab Tags

The tabTag idea

• What if we could give each tab a label, and then filter by that label?

• Essentially, assign a non-hierarchical type of metadata to a tab, or "tag" the "tab".

• Analogous to labeling emails in gmail or tagging bookmarks in delicious.

• These "tabTags" can be used to identify like tabs, and organize them accordingly during the rendering pipeline.

Page 13: Jasig Spring 2010 Tab Tags

How does one “tag” a tab?The power of the folder structure attribute

Once tabTag functionality is implemented, all one needs to do is add the structure attribute as a child of the <tab> element in a .fragment-layout or .layout file.

<tab unremovable="N" immutable="N" hidden="N" name=”Development">      <structure-attribute type="folder">          <name>tabTag</name>          <value>Admin</value>       </structure-attribute>

Page 14: Jasig Spring 2010 Tab Tags

Multi-Level Navigation Implementation Overview

• Small footprint - non-invasive• Implementated in the rendering pipeline• UP_LAYOUT_STRUCT table remains unchanged• All UI components, ( css, javascript ), remain compatible

So how do we implement this...

In a nutshell, we are leveraging the power of the default uPortal distribution with minimal customizations.

Page 15: Jasig Spring 2010 Tab Tags

List of files need to implement tabTag functionality at its most basic level.

• DLM_Tabs_and_columns-1.structure• columns.xsl ( structure transform )• navigation.xsl ( theme transform )• fragment layout files -- add tabTag folder structure attribute

to these.

However, at this basic level, “add a tab” customization does not work properly. In addition, persistent navigation at a subtab level is notpossible. We will address these enhancement later in this talk.

Page 16: Jasig Spring 2010 Tab Tags

DLM_Tabs_and_columns-1.structure

<parameter>

<name>tabTag</name>

<default-value>UNTAGGED</default-value>

<description>Value of tabTag to apply set on a tab</description>

<type>2</type>

</parameter>

Add the following parameter to structure entity file

This will add a row to the UP_SS_STRUCT_PAR. Any tab that is not assigned a tabTag folder structure attribute, will default to the UNTAGGED value.

Page 17: Jasig Spring 2010 Tab Tags

Modified Structure and Theme Transforms

columnsTabTag• columns.xsl

universalityTabTag• navigation.xsl

Page 18: Jasig Spring 2010 Tab Tags

columns.xsl

1. The activeTab param being passed into this transform that is used to determine the activeTabId is NOT the position of the tab, but rather the Tab Id itself.

2. A few new params are being passed through – the most important being the activeTabTag

3. This is where all the tabTag folder attributes are sorted for display, and the tabs with a tabTag = activeTabTag is selected.

This file is the most extensively modified. There are three importantchanges to take note of:

Page 19: Jasig Spring 2010 Tab Tags

Incoming XML to structure

<folder ID="u10l1s4" dlm:fragment="6" dlm:precedence="40.0" hidden="false" immutable="false" locale="en_US" name="Development" type="regular" unremovable="false" externalId="" width="100%" tabTag="Admin" activeChildId="doNotPersist" xmlns:dlm="http://www.uportal.org/layout/dlm">

This is the <folder> element for the Development tab.

Every folder that represents a tab will have the tabTag attribute.

Page 20: Jasig Spring 2010 Tab Tags

How are these tabTags sorted in columns.xsl

<!-- #### CUSTOM-TABTAG #### <tabTagList>

<xsl:attribute name="activeTabTag">

<xsl:value-of select="$TAB_TAG"/>

</xsl:attribute>

<xsl:for-each select="/layout/folder/folder[generate-id() = generate-id(key('tabTagKey',@tabTag)[1])]">

<tabTagListItem>

<xsl:value-of select="@tabTag"/>

</tabTagListItem>

</xsl:for-each>

</tabTagList>

<!-- #### END-CUSTOM-TABTAG #### -->

This code produces a <tabTagList> sent to the theme.

Page 21: Jasig Spring 2010 Tab Tags

Incoming XML to theme

<tabTagList activeTabTag="Admin”>

<tabTagListItem>Welcome</tabTagListItem>

<tabTagListItem>Staff</tabTagListItem>

<tabTagListItem>Admin</tabTagListItem>

</tabTagList>

This is then transformed by navigation.xsl in the theme.

Page 22: Jasig Spring 2010 Tab Tags

navigation.xsl

• <tabTagList> is transformed into the navigational display.• All URLs are modifed to pass through new params such as

activeTabID and activeTabTag• These URLs include tabTag, Tab, Portlet, and portlet flyout

urls.• The tabTag containers cannot be moved, nor can there names

be changed by the user. As of this point, these tags are decided by the implementers.

Page 23: Jasig Spring 2010 Tab Tags
Page 24: Jasig Spring 2010 Tab Tags

tabTag Enhancements

Add Tab functionality• DLM_XHTML-1.theme• ajax-preferences-jquery.js• UpdatePreferencesServlet.java

Navigation Persistence• DLM_Tabs_and_columns-1.structure• RDBMDistributedLayoutStore.java

Theme Housekeeping (set global vars for readable URLs)• universality.xsl

Page 25: Jasig Spring 2010 Tab Tags

Implement “Add Tab” functionality in multi-level navigation

• DLM_XHTML-1.theme• ajax-preferences-jquery.js• UpdatePreferencesServlet.java

When a user adds a tab to their layout, the new tab needs to have the active tabTag value assigned to it as structure folder attribute.

List of files modified:

Page 26: Jasig Spring 2010 Tab Tags

DLM_XHTML-1.theme

<parameter>

<name>newTabTag</name>

<value>Welcome</value>

<description>Add new tabTag to new tab</description>

<type>1</type>

</parameter>

This inserts a new row into UP_SS_THEME_PARM

Need to add new theme param:

Page 27: Jasig Spring 2010 Tab Tags

ajax-preferences-jquery.js

// Tab editing persistence functions

var addTab = function() {

var newTagTabVal = $("#activeTabTag").text();

$.post(settings.preferencesUrl, {action: 'addTab', newTabTag: newTagTabVal},

function(xml) {

if ($("success", xml).text() == 'false') { handleServerError(xml); return false; }

window.location = settings.portalUrl +

"?uP_root=root&uP_sparam=activeTab&activeTab=" +

($("#portalNavigationList > li").length + 1) +

"&uP_sparam=prevTabTag&prevTabTag=" + newTagTabVal;

});

};

The addTab function needs to modified to include the newly added theme param newTabTag.

Page 28: Jasig Spring 2010 Tab Tags

updatePreferencesServlet.java

This servlet gets the the newTabTag value sent by ajax-preferencesand persists and binds it as the folder structure attribute for the newlyadded tab.

Page 29: Jasig Spring 2010 Tab Tags

Navigation Persistence

• This is not strictly necessary, but it is a nice usability enhancement.

• Essentially, this functionality keeps track of the currently viewed tab under a specific tabTag as a user navigates across tabTags.

• Files involved are:• DLM_Tabs_and_columns-1.structure• RDBMDistributedLayoutStore.java

Page 30: Jasig Spring 2010 Tab Tags

DLM_Tabs_and_columns-1.structure

<parameter>

<name>activeChildId</name>

<default-value>doNotPersist</default-value>

<description>activeTabId of activeTabTag</description>

<type>2</type>

</parameter>

Once again, add a new parameter to the structure entity file

This will add a row to the UP_SS_STRUCT_PAR

Page 31: Jasig Spring 2010 Tab Tags

RDBMDistributedLayoutStore.java

/*

* Persist folder attributes defined in the stylesheet

* description only if the user value is non null and

* there is no default or the user value

* differs from the default.

*

* CUSTOM-TABTAG - if default value of attribute is "doNotPersist",

* do not persist this attribute to the database. This was customized

* so that activeChildId will not be persisted between sessions.

* See UP_SS_STRUCT_PAR to view default value for a type 2 attribute.

*/

Not going to show code – it isn’t difficult or complex, but the snippet of code is verbose, so instead I will include the comments.

Page 32: Jasig Spring 2010 Tab Tags

Done.... build and deploy

Page 33: Jasig Spring 2010 Tab Tags

Add tabTag param to fragment-layout files. For example...

<tab unremovable="N" immutable="N" hidden="N" name=”Development">      <structure-attribute type="folder">          <name>tabTag</name>          <value>Admin</value>       </structure-attribute>

... and import

Page 34: Jasig Spring 2010 Tab Tags

yeah... multi-level navigation

Page 35: Jasig Spring 2010 Tab Tags

Next Steps and Ideas…

• Work toward including tabTag theme in future version of uP3.x• Create Admin settings options

• support setting tabTag outside of fragment import process• this will better support existing implementations that want to

migrate to this theme• Create more theme options

• portletTag drop down theme… no tabs or pages... just select a tag in a drop down that results in those portlets showing on a page

• portletTag filter theme… a list of portlets that users can label/tag which results in the creation of tabs for each label

• one of these might be a nice mobile theme option