Marking Up the Sakai ToolBar

March 11, 2008

Most Sakai apps use a toolbar to navigate between the different views
of a tool and also to initiate new actions (create an Announcement, for example).

Eons ago in a more innocent age this seemed perfectly adequate markup to express this toolbar:

 <div clas="navIntraTool">
   <a href="#">A link</a>
   <a href="#">A link</a>
   <a href="#">A link</a>
 </div>

    But it has been getting rather long in the tooth. Certain needs cropped up that made it inadequate: need for “inactive” or “current” items (instead of links), pipe separators, icons associated with a link, css styling needs that went beyond the two box (div + a) canvas, etc. This is the new structure.

    <ul clas="navIntraTool actionToolBar">
     <li class="firstToolBarItem">
      <span>
       <a href="#">A link</a>
      </span>
     </li>
     <li>
      <span class="inactive">A string</span>
     </li>
     <li>
      <span><a href="#">A link</a></span>
     </li>
    </ul>

      This needs a bit of explanation.

      1. Recasting the toolbar as an unordered list makes more sense, sure. The doubled up class name is a transitional method to take style attributes to a more consistent, less organic and crufty naming scheme that reflects function. See the complete list of proposed changes
      2. The spans are there as styling shims, that is perhaps redundant, but somewhat standard. They also serve as a locale for the inactive and current classes.
      3. The first item is classed separately class="firstToolBarItem" as an aid to CSS1 crippled browsers. Imagine that you wanted to do something different to the first item. In a perfect world you would do something like .navIntraTool > li:first-child {color:red} in the css. In this sub-lunar IE6 world your markup needs to flag the first item so that you can address it in the css as .navIntraTool .firstToolBarItem {color:red}

      While at it – what more would the toolbar menu need? In a leap of faith and talking it over with Colin and Eli decided that WAI roles and states might make sense. Since this work is slated for Sakai 2.6, opted for a future version W3C WD, rather than the current one. The benefits (beyond future proofing) are that no namespace declarations are required, is less verbose.

      <ul role="menu" class="navIntraTool actionToolBar">
       <li role="menuitem" class="firstToolBarItem">
        <span>
         <a href="#">A link</a>
        </span>
       <li role="menuitem">
        <span aria-disabled="true" class="inactive">A string</span>
       </li>
       <li role="menuitem">
        <span>
         <a href="#">A link</a>
        </span>
       </li>
      </ul>

        Having decided on this, changing the tools based on the Velocity engine was fairly trivial. Most used a macro in the macro library to render the toolbar. The tricky parts involved figuring out which of the items was the first so that we could add the pesky class, which were disabled, which where a formish input toolbar item (there are a few of those).

        A handful of Velocity based tools had hand coded toolbars – it was just a matter of changing their templates, tedious but simple. A few involved yet more wrangling to decide if given a user and a state a given toolbar item was the first in the series or not.

        Changing the toolbar for the JSF based tools (that made use of the tag!!) was also fairly trivial. Two tags were involved: ToolBar and ToolBarItem (these are the renderers). As much as I complain about Sakai’s JSF, this was pretty sweet.

        Next, the Sakai tools that used JSF but did not use those particular tags. I expected a lot of hand coded markup and inventiveness, as the two Sakai JSF tags were not very flexible. Such as as this hybrid:

        <sakai:tool_bar>
         <h:commandLinkaction="#{ChatTool.processActionSynopticOptions}"
             rendered="#{ChatTool.maintainer}">
          <h:outputText value="#{msgs.manage_tool}" />
         </h:commandLink>
        </sakai:tool_bar>

          This toolbar uses the tag <sakai:tool_bar> to set up the outer container, then a set of JSF commandLinks (instead of the ToolBarItem tag). What to do? With the new tag the outer container as a <ul>, and the commandLinks translated to <a> giving us:

          <ul class="navIntraTool actionToolBar">
           <a href="#">A link</a>
           <a href="#">A link</a>
           <a href="#">A link</a>
          </ul>

            What was needed was a way to insert the list item, first item class, the span shim, a class for the inactive shim. Cringing from the first thing that occurred to me (a tag soup of <f:verbatim>) I noticed that this particular tool uses the excellent MyFaces Tomahawk components. The solution then was:

            <t:htmlTag rendered="#{ChatTool.maintainer}"
             value="ul"styleClass="navIntraTool actionToolBar">
             <t:htmlTag value="li"  styleClass="firstToolBarItem">
              <t:htmlTag value="span">
               <h:commandLinkaction="#{ChatTool.processActionSynopticOptions}">
                <h:outputText value="#{msgs.manage_tool}"/>
               </h:commandLink>
              </t:htmlTag>
             </t:htmlTag>
            </t:htmlTag>

              I love the <t:htmlTag> and want to take it home and keep it as a pet!! Even if it feels slightly funny to use it.

              It occurred to me that I could modify the Sakai JSF tags so they would do the right thing even if the child element were not a ToolBarItem – so that is what I will be doing instead. Any valid (h:outputLink, h:commandButton,h:commandLink) JSF child tag of ToolBar will be wrapped appropriately.

              Note: the new renderers ignore the “separator” attribute. This is no longer needed, of course, as the items are list items and you can plonk any sort of visual separator you could possibly want via CSS. Hand coded JSF markup does not get the ARIA state attributes either (because a commandLink has no notion of “disabled”, for example, that the toolBarItem tag can do stuff with).

              The Gradebook tool, for example does the following:

              <h:commandLink action="#{bean.navigateToOverview}"
                  immediate="true" rendered="#{bean.pageName ne 'overview'
                  && bean.breadcrumbPage ne 'overview'}">
                     <h:outputText value="#{msgs.appmenu_overview}"/>
                     <f:param name="pageName" value="overview" />
              </h:commandLink>
              <h:outputText value="#{msgs.appmenu_overview}" escape="false"
                   rendered="#{bean.pageName eq 'overview' || bean.breadcrumbPage eq
                   'overview'}" styleClass="currentView" />

              That is – it uses an <h:outputText /> if you are “there” – the problem is that this resolves to to a <span>. When this runs via ToolBarItem you get:

              <li>
                <span>
                  <span class="currentView">
                     String
                  </span>
                </span>
              </li>

              With the new tags it is possible to avoid this by having the inactive “you are here” string output via a ToolBarItem with a “disabled=’true'” attribute.

              Other exotic uses of the ToolBar tag are the following. In most cases this seems to involve poking in an h:commandLink with maybe an h:grapicImage child of that, but I will need to test them all. I have not checked this in yet to trunk.

              msgcntr\messageforums-app\src\webapp\jsp\
              discussionForum\message\dfFlatView.jsp(35)

              This seems ok.

              msgcntr\messageforums-app\src\webapp\jsp\
              discussionForum\forumsOnly\dfForums.jsp(23)

              looks standard

              msgcntr\messageforums-app\src\webapp\jsp\
              discussionForum\message\dfViewMessage.jsp(90)

              has a child: <h:panelGrid columns=”2″ width=”100%” summary=”layout”> the solution is to get rid of the panel grid…. (create patch)

              msgcntr\messageforums-app\src\webapp\jsp\
              discussionForum\message\dfViewThread.jsp(24)

              should be ok

              msgcntr\messageforums-app\src\webapp\jsp\
              privateMsg\addAttach.jsp(12)

              ???

              <sakai:tool_bar>
               <sakai:tool_bar_message
                 value="Attachment from a Local File" />
               </sakai:tool_bar>

              looks like this will resolve to an h3 inside a toolbar. Problem, but cannot find where used.

              msgcntr\messageforums-app\src\webapp\jsp\
              privateMsg\pvtMsgHpView.jsp(29)

              another panelGrid and tool_bar mashup – create patch

              osp\presentation\tool\src\webapp\freeForm\
              arrange.jsp(19)

              <sakai:tool_bar>
                <h:selectOneMenu value="#{freeForm.currentPageId}">
                  <f:selectItems value="#{freeForm.pageDropList}" />
                </h:selectOneMenu>
                <h:commandButton value="#{msgs.change_arrange_page}"
                    action="#{freeForm.processChangeCurrentPage}" />
              </sakai:tool_bar>

              not sure where this is used. Most of osp/presentation is spring mvc jsp.

              reports\reports-tool\tool\src\webapp\reports\main.jsp(8)

              <sakai:tool_bar>
                <h:commandLink rendered="#{ReportsTool.maintainer}"
                   action="#{ReportsTool.processPermissions}">
                  <h:outputText value="#{msgs.permissions_link}"/>
                </h:commandLink>
                <h:outputText value="#{'   |   '}" escape="false"
                   rendered="#{ReportsTool.maintainer}"/>
                <h:commandLink rendered="#{ReportsTool.maintainer}"
                   action="#{ReportsTool.processImportDefinition}">
                   <h:outputText value="#{msgs.import_report_def}"/>
                </h:commandLink>
              </sakai:tool_bar>

              Looks ok, create patch.
              syllabus\syllabus-app\src\webapp\syllabus\add_attach.jsp(15)

              <sakai:tool_bar>
                <sakai:tool_bar_message
                  value="#{msgs.title_add_attach_local}" />
              </sakai:tool_bar>

              This will not work, deprecated?

              syllabus\syllabus-app\src\webapp\
              syllabus\main.jsp(33)

              custom <syllabus:syllabus_ifnot> tag needs to be changed with something else, commandLinks with working rendered attributes, for example.

              syllabus\syllabus-app\src\webapp\syllabus\
              multi_delete_confirm.jsp(33)

              nekkid <sakai:tool_bar_item> tags inside a table. Deprecated?

                More later on managing the styling of what is now 2 different markup toolbar blobs on Sakai (old and new). And examples on styling it as well!

                Advertisements