Jasig Spring 2010 Tab Tags


Published on

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

Published in: Technology
  • Be the first to comment

  • Be the first to like this

No Downloads
Total views
On SlideShare
From Embeds
Number of Embeds
Embeds 0
No embeds

No notes for slide
  • need to have a method of organizing A LOT of content for a diverse set of users without alienating any of the many content providers
  • worked out really well for student portal… able to have a lot of content by default without it being overwhelming
  • technology advances provide for a an alternative to multiple levels of navigation, but there are scaling issues to consider
  • from the beginning this approach was very appealing
  • we feel it may benefit others as well, and jeff is going to share some details on how to take it for a test drive
  • I am logged in as the demo user.
  • Identify our nomenclature tab -> page -> portlet. Though our pages are really uportal tabs.
  • This allows for portlets that our best viewed full screen to have their own tab. My user has 18 tabs that contain content.
  • show demo on local machine.
  • This will produce the effect as in the previous slide, where the tab named "Developement" is a  sub-tab or sub-page of the tabTag container "Demo"
  • This will get you there, but it probably isn't enough. That is when a user adds a tab, it won't be tagged correctly.  or a users open tab won't persist when navigation between tabTags.
  • note, this is leveraging existing functionality in uPortal that is available to add and track custom structure attributes.
  • notice the tabTag folder attribute. If we added this to the fragment layout.
  • Need to add snapshot of incoming theme xml and show tabTagList
  • Screenshot from navigation.xsl
  • urls get large – passing through more sturct and theme params – we will see.
  • For example, if a user wants to add a new tab to the group of tabs that are within the admin tabTag group, the add tab functionality needs to add this page to the correct group.
  • selector finds value of the activeTabTag… mention that bold text is new or changed…
  • currently, we use the import/export utility to add new tabs (with tab tags)
  • show image
  • Jasig Spring 2010 Tab Tags

    1. 1. Implementing Multi-Level Navigation in uPortal JASIG Spring 2010 Conference
    2. 2. Basic Problem… <ul><li>Sizable Multi-Campus implementation with hundreds of portlet publications </li></ul><ul><li>Governance is very distributed, and there is a lot of content that the committees want provided by default </li></ul><ul><li>How do we organize this information in a usable way? </li></ul>
    3. 3. Lesson Learned <ul><li>In uPortal 2, we implemented a subtab structure to support this </li></ul><ul><li>This required a lot of custom code </li></ul><ul><li>This was a structural change that made our uPortal 3 upgrade much more difficult </li></ul><ul><li>The import/export scripts had to be changed and augmented to account for the new level of hierarchy in the layout </li></ul>
    4. 4. Things to Consider <ul><li>Tab Carousels </li></ul><ul><ul><li>suffer from an out of sight out of mind dilemma </li></ul></ul><ul><ul><li>still have a usability issue, when tab numbers are high… how many tabs will a user scroll through? </li></ul></ul><ul><li>Click counts </li></ul><ul><ul><li>how do we get people to what the need quickly? </li></ul></ul>
    5. 5. Revelation <ul><li>One of the things our users like is the ability to find things at a glance and drill down for more detail </li></ul><ul><li>We needed a new approach that would provide the same functionality without the upgrade and maintenance headaches </li></ul><ul><li>Jeff conceptualized tabTags… </li></ul>
    6. 6. The tabTag Approach <ul><li>Does not change the structure of the layout XML </li></ul><ul><li>Uses out-of-box uPortal “structure attribute” functionality to track tags associated with at tab </li></ul><ul><li>Is implemented via an optional new theme </li></ul>
    7. 7. The tabTag Approach <ul><li>Requires minimal code enhancements (to remember the selected tab) </li></ul><ul><li>Has no code changes that break the out-of-box uPortal theme </li></ul><ul><li>Quickly became a clear choice to meet our needs </li></ul>
    8. 8. Currently, uPortal only has single level navigation at the tab level . I am logged in as the staff user on the default uPortal32 install.
    9. 11. So how do we produce multi-level navigation? In this screenshot the Admin “tab container” is a navigational construct which contains three tabs: Development, Testing, Admin Tools
    10. 12. The tabTag idea <ul><ul><li>What if we could give each tab a label, and then filter by that label? </li></ul></ul><ul><ul><li>Essentially, assign a non-hierarchical   type of metadata to a tab, or &quot;tag&quot; the &quot;tab&quot;. </li></ul></ul><ul><ul><li>Analogous to labeling emails in gmail or tagging bookmarks in delicious. </li></ul></ul><ul><ul><li>These &quot;tabTags&quot; can be used to identify like tabs, and organize them accordingly during the rendering pipeline. </li></ul></ul>
    11. 13. How does one “tag” a tab? The power of the folder structure attribute <ul><li>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. </li></ul><tab unremovable=&quot;N&quot; immutable=&quot;N&quot; hidden=&quot;N&quot; name=” Development &quot;>        <structure-attribute type=&quot;folder&quot;>            <name> tabTag </name>            <value> Admin </value>        </structure-attribute>
    12. 14. Multi-Level Navigation Implementation Overview <ul><ul><li>Small footprint - non-invasive </li></ul></ul><ul><ul><li>Implementated in the rendering pipeline </li></ul></ul><ul><ul><li>UP_LAYOUT_STRUCT table remains unchanged </li></ul></ul><ul><ul><li>All UI components, ( css, javascript ), remain compatible </li></ul></ul>So how do we implement this... In a nutshell, we are leveraging the power of the default uPortal distribution with minimal customizations.
    13. 15. List of files need to implement tabTag functionality at its most basic level. <ul><ul><li>DLM_Tabs_and_columns-1.structure </li></ul></ul><ul><ul><li>columns.xsl ( structure transform ) </li></ul></ul><ul><ul><li>navigation.xsl ( theme transform ) </li></ul></ul><ul><ul><li>fragment layout files -- add tabTag folder structure attribute to these. </li></ul></ul>However, at this basic level, “add a tab” customization does not work properly. In addition, persistent navigation at a subtab level is not possible. We will address these enhancement later in this talk.
    14. 16. DLM_Tabs_and_columns-1.structure <ul><li><parameter> </li></ul><ul><li><name> tabTag </name> </li></ul><ul><li><default-value> UNTAGGED </default-value> </li></ul><ul><li><description> Value of tabTag to apply set on a tab </description> </li></ul><ul><li><type> 2 </type> </li></ul><ul><li></parameter> </li></ul>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.
    15. 17. Modified Structure and Theme Transforms <ul><li>columnsTabTag </li></ul><ul><ul><li>columns.xsl </li></ul></ul><ul><li>universalityTabTag </li></ul><ul><ul><li>navigation.xsl </li></ul></ul>
    16. 18. columns.xsl <ul><li>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. </li></ul><ul><li>2. A few new params are being passed through – the most important being the activeTabTag </li></ul><ul><li>3. This is where all the tabTag folder attributes are sorted for display, and the tabs with a tabTag = activeTabTag is selected. </li></ul>This file is the most extensively modified. There are three important changes to take note of:
    17. 19. Incoming XML to structure <folder ID=&quot;u10l1s4&quot; dlm:fragment=&quot;6&quot; dlm:precedence=&quot;40.0&quot; hidden=&quot;false&quot; immutable=&quot;false&quot; locale=&quot;en_US&quot; name=&quot;Development&quot; type=&quot;regular&quot; unremovable=&quot;false&quot; externalId=&quot;&quot; width=&quot;100%&quot; tabTag=&quot;Admin&quot; activeChildId=&quot;doNotPersist&quot; xmlns:dlm=&quot;http://www.uportal.org/layout/dlm&quot;> This is the <folder> element for the Development tab. Every folder that represents a tab will have the tabTag attribute.
    18. 20. How are these tabTags sorted in columns.xsl <ul><li><!-- #### CUSTOM-TABTAG ####  </li></ul><ul><li><tabTagList> </li></ul><ul><li><xsl:attribute name=&quot;activeTabTag&quot;> </li></ul><ul><li><xsl:value-of select=&quot;$TAB_TAG&quot;/> </li></ul><ul><li></xsl:attribute> </li></ul><ul><li><xsl:for-each select=&quot;/layout/folder/folder[generate-id() = generate-id(key('tabTagKey',@tabTag)[1])]&quot;> </li></ul><ul><li><tabTagListItem> </li></ul><ul><li><xsl:value-of select=&quot;@tabTag&quot;/> </li></ul><ul><li></tabTagListItem> </li></ul><ul><li></xsl:for-each> </li></ul><ul><li></tabTagList> </li></ul><ul><li><!-- #### END-CUSTOM-TABTAG #### --> </li></ul>This code produces a <tabTagList> sent to the theme.
    19. 21. Incoming XML to theme <ul><li><tabTagList activeTabTag=&quot;Admin” > </li></ul><ul><li><tabTagListItem> Welcome </tabTagListItem> </li></ul><ul><li><tabTagListItem> Staff </tabTagListItem> </li></ul><ul><li><tabTagListItem> Admin </tabTagListItem> </li></ul><ul><li></tabTagList> </li></ul>This is then transformed by navigation.xsl in the theme.
    20. 22. navigation.xsl <ul><li><tabTagList> is transformed into the navigational display. </li></ul><ul><li>All URLs are modifed to pass through new params such as activeTabID and activeTabTag </li></ul><ul><li>These URLs include tabTag, Tab, Portlet, and portlet flyout urls. </li></ul><ul><li>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. </li></ul>
    21. 24. tabTag Enhancements <ul><li>Add Tab functionality </li></ul><ul><ul><li>DLM_XHTML-1.theme </li></ul></ul><ul><ul><li>ajax-preferences-jquery.js </li></ul></ul><ul><ul><li>UpdatePreferencesServlet.java </li></ul></ul><ul><li>Navigation Persistence </li></ul><ul><ul><li>DLM_Tabs_and_columns-1.structure </li></ul></ul><ul><ul><li>RDBMDistributedLayoutStore.java </li></ul></ul><ul><li>Theme Housekeeping (set global vars for readable URLs) </li></ul><ul><ul><li>universality.xsl </li></ul></ul>
    22. 25. Implement “Add Tab” functionality in multi-level navigation <ul><ul><li>DLM_XHTML-1.theme </li></ul></ul><ul><ul><li>ajax-preferences-jquery.js </li></ul></ul><ul><ul><li>UpdatePreferencesServlet.java </li></ul></ul>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:
    23. 26. DLM_XHTML-1.theme <ul><li><parameter> </li></ul><ul><li><name> newTabTag </name> </li></ul><ul><li><value> Welcome </value> </li></ul><ul><li><description> Add new tabTag to new tab </description> </li></ul><ul><li><type> 1 </type> </li></ul><ul><li></parameter> </li></ul>This inserts a new row into UP_SS_THEME_PARM Need to add new theme param:
    24. 27. ajax-preferences-jquery.js <ul><li>// Tab editing persistence functions </li></ul><ul><li>var addTab = function() { </li></ul><ul><li>var newTagTabVal = $(&quot;#activeTabTag&quot;).text(); </li></ul><ul><li>$.post(settings.preferencesUrl, {action: 'addTab', newTabTag: newTagTabVal }, </li></ul><ul><li>function(xml) { </li></ul><ul><li>if ($(&quot;success&quot;, xml).text() == 'false') { handleServerError(xml); return false; } </li></ul><ul><li>window.location = settings.portalUrl + </li></ul><ul><li>&quot;?uP_root=root&uP_sparam=activeTab&activeTab=&quot; + </li></ul><ul><li> ($(&quot;#portalNavigationList > li&quot;).length + 1) + </li></ul><ul><li>&quot;&uP_sparam=prevTabTag&prevTabTag=&quot; + newTagTabVal; </li></ul><ul><li>}); </li></ul><ul><li>}; </li></ul>The addTab function needs to modified to include the newly added theme param newTabTag.
    25. 28. updatePreferencesServlet.java This servlet gets the the newTabTag value sent by ajax-preferences and persists and binds it as the folder structure attribute for the newly added tab.
    26. 29. Navigation Persistence <ul><li>This is not strictly necessary, but it is a nice usability enhancement. </li></ul><ul><li>Essentially, this functionality keeps track of the currently viewed tab under a specific tabTag as a user navigates across tabTags. </li></ul><ul><li>Files involved are: </li></ul><ul><ul><li>DLM_Tabs_and_columns-1.structure </li></ul></ul><ul><ul><li>RDBMDistributedLayoutStore.java </li></ul></ul>
    27. 30. DLM_Tabs_and_columns-1.structure <ul><li><parameter> </li></ul><ul><li><name> activeChildId </name> </li></ul><ul><li><default-value> doNotPersist </default-value> </li></ul><ul><li><description> activeTabId of activeTabTag </description> </li></ul><ul><li><type> 2 </type> </li></ul><ul><li></parameter> </li></ul>Once again, add a new parameter to the structure entity file This will add a row to the UP_SS_STRUCT_PAR
    28. 31. RDBMDistributedLayoutStore.java <ul><li>/* </li></ul><ul><li>* Persist folder attributes defined in the stylesheet </li></ul><ul><li>* description only if the user value is non null and </li></ul><ul><li>* there is no default or the user value </li></ul><ul><li>* differs from the default. </li></ul><ul><li>* </li></ul><ul><li>* CUSTOM-TABTAG - if default value of attribute is &quot;doNotPersist&quot;, </li></ul><ul><li>* do not persist this attribute to the database. This was customized </li></ul><ul><li>* so that activeChildId will not be persisted between sessions. </li></ul><ul><li>* See UP_SS_STRUCT_PAR to view default value for a type 2 attribute. </li></ul><ul><li>*/ </li></ul>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.
    29. 32. Done.... build and deploy
    30. 33. Add tabTag param to fragment-layout files. For example... <tab unremovable=&quot;N&quot; immutable=&quot;N&quot; hidden=&quot;N&quot; name=” Development &quot;>        <structure-attribute type=&quot;folder&quot;>            <name> tabTag </name>            <value> Admin </value>        </structure-attribute> ... and import
    31. 34. yeah... multi-level navigation
    32. 35. Next Steps and Ideas… <ul><li>Work toward including tabTag theme in future version of uP3.x </li></ul><ul><li>Create Admin settings options </li></ul><ul><ul><li>support setting tabTag outside of fragment import process </li></ul></ul><ul><ul><li>this will better support existing implementations that want to migrate to this theme </li></ul></ul><ul><li>Create more theme options </li></ul><ul><ul><li>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 </li></ul></ul><ul><ul><li>portletTag filter theme… a list of portlets that users can label/tag which results in the creation of tabs for each label </li></ul></ul><ul><ul><li>one of these might be a nice mobile theme option </li></ul></ul>
    33. 36. Contacts: Tim Carroll [email_address] Jeff Dimpsey [email_address]