RTL Sakai

October 10, 2008

Back in Sakai 2.0 I went through an attempt to serve up a Right To Left language Sakai experience. At the time this was just an academic exercise, as there were no language resource bundles for Arabic, Hebrew, Farsi, etc. I just wanted to torture test the framework, frankly. It was amazingly simple to modify the portal framework via the skin to serve up an adequate portal. The tools were a different matter altogether, being so varied, and represented a number of challenges.

Now there is a Arabic translation (in trunk), so I thought I would go through the process again and hope it is useful. The framework has changed substantially also, so it was due. In this post I will outline the steps to turn a LTR portal (the Michigan CTools) into a RTL portal for some hypothetical university where Arabic is the main language. Disclaimer: I took Arabic in college, but it is long forgotten – so I am relying on random boilerplate and on iGoogle’s translator service for example strings. Don’t read too much into it!

In a future post I will go through one or two tools in a similar fashion.

  1. Use trunk. Add ‘ar’ to the locales attribute in sakai.properties, start tomcat.
  2. Login as admin. Create a user, give him a RTL name. In this case I used داود سيلڤَر (with a Latin id if you are not a RTL speaker, I used daud).
  3. We will want داود to mess around with tools as ‘mantain’ to get the full experience so create a site and add him as mantain. I used boilerplate Arabic for site title and description.
  4. Login as ‘daud’
  5. Change your Preferences > Locales to ‘Arabic’
Tada! First impressions – neat! Second impression – I cannot read it, it is too small. We will address that later.

First thing – let’s add a direction attribute to first child of the portal body:

#portalOuterContainer{
	direction: rtl;
}

This gets us started. All HTML elements that inherit this attribute and use it will reverse direction. Now we need to address the elements that are not affected.

Some things will need to be addressed substantially: 1) the orientation of the mast head needs to be fixed so that from RTL: logo, banner, login; 2) site list orientation; 3) the portlet title (Announcements) also needs to be reconfigured as well; 4) finally – the portal content needs to be from RTL: tool links, content.

Reorienting the mast head

We have this mess to contend with:

I have outlined the three components in red. From LTR: #mastLogo, #mastBanner, #mastLogin. They are all floated. We need to reverse the order, so let’s reverse the float:

#mastLogin{
  /*float:right*/ float:left
}
#mastBanner{
  /*float:left*/float:right
}

That is it – really. Am omitting all of the other attributes. Which gives us:

The order of labels and inputs is following the direction attribute of the body. Everything else needs work. Am going to hide #mastLogo because we do not need it. Any graphic element can be poked in as a background of any of the (embarrassingly numerous) other canvases available. I will also add different logos and background colors.

So – new image for banner_inst.gif and reverse the padding orientation on #mastLogin:

#mastLogin{
	float: left;
	text-align: right;
	/*padding-right: 15px;*/padding-left: 15px;
	vertical-align: top;
}

Which leaves us with:

The language bundle seems to be missing the Arabic equivalents for the input labels, but the position basics are in place: logo to the right, login to the left.

Reorienting the site navigation

We are left with:

Swapping the floats (links and select) reflect the importance of the 2 in the RTL context:

#linkNav{
	/*float:right*/ float:left
}
#selectNav{
	/*float:left;*/ float:right
}
So (am hiding the banner_inst.gif image):

Although the the direction:rtl in the body gets us the RTL select, it does not flip the orientation of the inline list that the site links are, a list is a list and has an order. We will need to be more devious…

#siteLinkList li{
	display: inline;
	float:right;
}
Yay – the order of importance reflected in the original LTR is now reflected in the RTL context: My Workspace, sites, other sites. Some minor touches are still needed such as the separators between site links, padding, etc.

Reorienting the content

The site content consists of a container (imaginatively id’d as #container), with two children: #toolMenuWrap (the tool link upper parent) and #content. Again , we have to tinker with the float of one:
#toolMenuWrap {
     border-right:2px solid #FFFFFF;
     color:#000000;
     /*float:left;*/ float:right
     padding:0 0.5em 0 0;
     text-align:right;
     width:9.6em;
}

and the margin of the other

#content{
	padding: 0;
	margin-top: .5em;
	/*margin-left: 11em;*/ margin-right: 11em;
}

and the text-align of the #toolMenu list items:

#toolMenu li{
	margin: 0;
	width: auto;
	padding: 0;
	border: 1px solid #fff;
	/*text-align: left;*/text-align: right;
}

Not bad, although quite a bit of clean up left to do (the presence block, the portlet titles (which are in the portal doc of all things) for example, the footers, etc.) And being ignorant of the actual use and needs, quite a few things I have overlooked as well – do leave comments setting me straight. I will upload the finished skin later. I will also address soon the skinning of the tools (gulp).


Corners of Sakai 3 – Pseudo Hierarchy

August 22, 2008

Suppose you want to relate several Sakai sites together. Some use cases:

  1. a project site membership has a created a series of subsites to take care of committee work
  2. you want to allow users of Fall 2008 course site access to all previous course sites for same course. You can take care of the access issues – but how to make it easier for them to find these other sites?
  3. a department needs to provide a set of documents to all courses in it. The sites of these courses need to appear as “children” of the departmental site.
  4. etc.

What to do? Pseudo-hierarchy might fit the bill. Run up at an airport by Chuck Severance it establishes a user-interface-only relationship between the sites. This takes place in a breadcrumb that displays below the site navigation paraphernalia.

The full details are here: sakai_pseudo_hierarchy.doc.

The rendering bits are in any version of Sakai after 2.4.x. – to customize for your institution – add the following lines (36-53 in Sakai 2.5.x) from the default.css and then change to suit.

/*site hierarchy breadcrumb*/
#siteHierarchy{
        clear:both;
        float:none;
        margin:0;
        list-style: none;
        padding:.5em 0;
}
/*style the standard breadcrumbseparator
   can set display:none if needed because the
   list-style is taking care of it*/
.breadSeparator{
}
#siteHierarchy li{
        display:inline;
}
#siteHierarchy li a, #siteHierarchy li a:visited{
        color:#09c;
}

You can also add your own separator via the language bundle.


Print previews on the cheap

August 22, 2008

1. Put this in the document (as well as a link to the jquery file).

<script type="text/javascript">
  $(document).ready(function(){
    setupLinks();
    setupPrintPreview();
  });
</script>

2. Put this in your external javascript:

function setupLinks(){
  $('a.print-window').click(function(){
     var w = window.open(this.href, 'printwindow', 'width=600,
          height=400,scrollbars=yes,resizable=yes');
     w.focus();
     return false;
  });
}

3. And this

function setupPrintPreview(){
  if (window.name == 'printwindow') {
   // all the settings below would need to be edited
    $('.portletBody *').css({
        color: '#000'
    });
    $('.bookList').show();
    $('.collapse').show();
    $('.expand').hide();
    $('.noPrint').hide();
    $('.portletBody').css({
        padding: '1em',
        fontSize: '.85em'
    });
    // provide a print link
    $("h3").append('a link with an
        'javascript:window.print()' href value);
  }
}

In (1) we are calling a function (2) that bind the onclick event to any link with a class of ‘print-window’ – opening the current document in a named window. In (3) – if a window matches the given name, then massage the elements for the print medium, hide elements that were classed as ‘noPrint’ (formish things, whatever), and add a link with an ‘javascript:window.print()’ href value to the DOM.

The end. Lots of room for improvement, of course – the massaging would be done best by swapping the stylesheets, for example.


Corners of Sakai 2 – Skinning Site Types

June 28, 2008

The ability for an institution to configure their local Sakai instance with site types I think underexploited. Or maybe I do not know what people are doing with it. I show how to serve different look and feel for different site types using the same skin. But first – what is a site type?

Let’s say that your institution does not offer courses, but synergymnasiums, no seminars, but collaboratoriums, no discussion sections but hoedowns, etc. These choices can be presented to the user via configuration changes. But it goes beyond the name:  creation of different site types can be associated with different access level people. Maybe only administrators can create synergymnasiums, for example. Each site type also comes with a set of tools to choose from or forced to accept, and after 2.5.x, even with prebaked content into the bargain, etc. There is more to this that am aware of, but for our purposes here, the only thing that matters is that the site type is emitted as a class in the portal markup, allowing us to do different things to a portal depending on the site type. There are 3 spots where this happens:

In the portal masthead:

<div id="siteNavWrapper" class="workspace">
 <div id="mastHead">
  ....
 </div>
</div>

In the site navigation block:

<div class="siteNavWrap workspace">
 <div id="siteNav">
  ...
 </div>
</div>

and in the top most wrapping block of all site content:

<div id="container" class="workspace" >

This means that you can get at, via contextual selectors, to almost any element in the portal, and do different things to it based on the site type.

At the University of Michigan we have 5 significant site types: workspace, course, project, gradtools, and unspecified. Here is how the first three look like, using the same skin:

The user workspace:

The course site:

The project site:

Since a given user will go from workspace to project (at Michigan any user can create project sites) to course site it was important to make sure they were only subtly different – or different enough to help the user locate herself,  not different to force them to remap things between site types. This was done via color only – the color of the banner text (a background image of one of the children of the .mastHead block), the bottom border of the site navigation, the text of the site title, the text of the current tool, other things. The most radical difference was with the workspace banner text – we found our users needed that extra flag to discern between workspace and worksite.

You can take a look at the portal css of CTools if you would like. All of this is documented as well in the source documentation in the reference.

The remaining site type is the undeterminedSiteType – the default. That is literally the name of the class you need to address, or ignore but provide a css default for to take care of:

Since the default will be triggered when the site type is unspecified, and the only possible cases would be during errors (like Site Unavailable above) or admin type sites – where the stakes are high, the reddish color seemed warranted.

Anyways, this is all short on detail – but the documentation linked to above covers that pretty well.


Corners of Sakai 1 – the access servlet

June 26, 2008

Sakai has some functionality that may be of interest to solve particular problems but is not well known because:

  • it has not been fully tested or
  • was addressing very specific needs or
  • is not well documented or
  • has simply been forgotten

One of these is the Access Servlet. Have you wanted to point your group (define this as you will) to a specific slice of a Resource collection? Without all the Resource management paraphernalia of the Resource Tool? But will all the permissions in full operation? The Access Servlet is there to help.

1 – Choose “Edit Details” of the folder you want to share.

2 – Then click on the “Open” link

3 – The link will open a new window with the contents of the folder – but using the access servlet – looking like this:

All of the “file management” stuff is gone. Also the descriptions are available in the list itself (displayed by default – here toggled closed for the screen shot), which they are not in the OOTB Resources tool. The markup has been been pared down to the bone (an actual list with list items) and the scripting reduced to a nothing. More importantly – all of the access control settings for the whole selected hierarchy are intact – if Folder 2 contents is only available to members of a specific group only members of that specific group will see a link to it. Same obtains for all the other conditional disclosure settings of the folder.

Note and caveat: the functionality is available in Sakai 2.4 onwards, not sure who provided it – but the above screenshots are taken from a trunk build plus 2 patches  available at SAK-13694 and SAK-3804. Please read the comments to both for the caveats and gaps.

An enterprising developer could add an action to a Resource folder to automate this – perhaps adding a tool link targeting the slice to the tool navigation menu. Some institutions, like Oxford seem to be planning to use the access servlet as the main and only public face of the Resources tool it seems, not sure how they are going about that.


A better select one or many

April 7, 2008

“Better” is an exaggeration. It may be that occasionally it is more appropriate.

At issue is presenting a control to the user where she can select one of many, or several of many. When the selection is fairly small (arbitrary at 7 items) – radio and checkbox groups are standard. But when the choice number goes over a certain number, there are various mechanisms to be seen, of which the most common are single select <select /> and multiple select <select /> – the problem is how to fit large number of choices into a cramped area.

This came up in the context of the Sakai Course Evaluation tool, where any number of question types need to be constructed and presented to the user. One of these questions, used in a Cambridge course evaluation, involved a really long list of choices.

Occasionally you might want a control that is a bit friendlier and stylable than a <select />. A colleague alerted me to: http://c82.net/posts.php?id=25

Here is an example from C82:

Nice! The clickable area indicated by the dark green hover is created by the <label /> element, wrapping the <input /> and the text and set to display:block. The height and width of the top container (a <ul />) are fixed and the overflow:auto for the scroll.

There are three possible improvements to the excellent widget.

  1. Having the overflow and height attributes set only if the height goes over a certain number (template or system set) – so scrollbars appear after a certain height, and groups of less than that height size automatically.
  2. Having the “checked” attribute of the input reflected in the style of the parent label
  3. Having a message display of the “you have made x selections” or something like that.

Setting the scroll and height dynamically

The markup looks like this:

<ol class="multchoiceholder">
<li>
<label for="1">
<input value="1" name="1" id="1" type="checkbox">
</label>
</li>
<li>
<label for="2">
<input value="2" name="2" id="2" type="checkbox">
</label>
</li>
(etc)
</ol>

And the CSS is pretty much what the C82 article above is using, except no height is set for the container, allowing it to grow to fit the contents. To get the “intelligence” about the height I added jquery.js to the <head />

<script src="jquery.js" language="JavaScript" type="text/javascript">

And the following at the end of the document:

<script type="text/javascript">
$(".multchoiceholder").each(function(){
if ($(this).height() > 180) {
// if ($(this).children("li").size()  >  9) {
$(this).addClass("oversize")
}
})
</script>

This essentially adds the “oversize” class to the parent container if the parent container contents go over 180 pixels in height. This class, below, sets the height and the overflow that we need. I played around with counting the <li /> child nodes (commented above), but since a given list item could span multiple lines the pixel height seemed best.

ol.oversize{
border: 1px solid #ccc !important;
height: 12em !important;
overflow: auto !important
}

Using/Configuring the Sakai Rich Text Editor

March 22, 2008

The rich text editor in Sakai has a very hard row to hoe. It needs to be:

  1. invoked in the context of 6 view technologies (Velocity, JSF, SPRING/MVC/JSP, XSLT, RSF, Servlets, am sure am forgetting some!)
  2. configured to run plugins (Sakaibrary, Josh Ryan’s Entity Browser, etc.) or not
  3. stand being poked into a number of curious contexts, fulfilling any number of disparate purposes, from helping people write smallish blurbs, blog entries, full blown web pages, the Encyclopedia Galactica, etc.
  4. display in tight spaces, take over the whole screen, stuff in between…
  5. be any rich text editor – the tool invoking it need not know what rich text editor is being invoked – FCK, HTMLArea, TinyMCE, etc.

This is what it looks like at present (FCKEditor used as example below). This is default, when no parameters are specified it resolves to an editor area 600px wide, 400px tall, with the Default ToolbarSet.

default.png

In the Velocity tools the editor is invoked via a daisy chain of macros and templates. Unfortunately the only parameter that makes to the actual editor script is the id of the textarea being replaced. Am addressing that in SAK-13244.

Sakai tools that use Velocity will have the following in a template:

<textarea name="body" class="block" id="body"
  cols="65" rows="30" wrap="virtual">
</textarea>
 #chef_setupformattedtextarea("body")

The #chef_setupformattedtextarea macro lives in VM_chef_library.vm:

#macro (chef_setupformattedtextarea $textarea_id)
  ## setup wysiwyg editor
  #set($editor_path = "vm/editor/$!sakai_editor/sakai_body.vm")
  <!-- $editor_path -->
  #parse("$editor_path")
  <script type="text/javascript" defer="1">
   chef_setupformattedtextarea('$textarea_id');
  </script>
#end

and essentially uses a server variable ($!sakai_editor) to decide on the rich text editor that the installation is using, then calls a text editor specific template (vastly simplified below) that sets up some configuration values:

function chef_setupformattedtextarea(textarea_id){
  var oFCKeditor = new FCKeditor(textarea_id);
  oFCKeditor.BasePath = "#libraryLink("editor/FCKeditor/")";
  <snip />
  oFCKeditor.Width  = "600" ;
  oFCKeditor.Height = "400" ;
  oFCKeditor.Config['CustomConfigurationsPath']
    = "#libraryLink("editor/FCKeditor/config.js")";
  oFCKeditor.ReplaceTextarea() ;
}

The thing to notice is that the only value passed along the chain is the id of the textarea in the template that will be replaced with the editor. What values would be minimally useful other than that? I decided arbitrarily that width, height and editor toolbar options would be the most useful. I wonder if this is true.

So now the calling template has:

#chef_setupformattedtextareaparams("description" "400"
  "600" "Default")

and the macro in VM_chef_library.vm reads:

#macro (chef_setupformattedtextareaparams $textarea_id
 $height $width $ToolBarSetChoice)
 <snip />
 <script type="text/javascript" defer="1">
   chef_setupformattedtextarea('$textarea_id','$height',
    '$width','$ToolBarSetChoice');
 </script>
#end

Note that there is a new macro involved (chef_setupformattedtextareaparams). The old one (chef_setupformattedtextarea) expects one parameter only. Velocity macros cannot deal with missing parameters, so need 2, one macro that expets one parameter (the id of the textarea) and another that expects exactly four.

The template that drops the javascript onto the the template DOM is would use the paramenters if available and provide some defaults if not.

Height and width are pretty self explanatory, toolbar settings are trickier. FCKEditor allows for named bundles of toolbar functionality – out of the box is provides “Default,” “Attachments,” and “Basic.” To these I have added the following: “large”, “medium” and “small” described below. These names were adopted because they are the same as the ones used in the HTMLArea option. Since a given bundle has certain horizontal needs I indicate the width sweetspots for each.

small

365 px wide or more. This essentially is the FCK “Basic” plus some added functionality. The emphasis is on writing text, without too much block formatting (other than lists), and no non-textual elements. Suitable for comments, quick text entries, snippets of all types.

sakai-min.png

medium

410px wide or more. Is like small + links to word processing like functionality (copy, paste, undo, search) as well as embedding,linking and extended formatting options.
sakai-med.png

large

At 410 it will display 5 rows in the toolbar, at 500px will display 4 and at 600 it will display 3. Essentially the FCK “Default” minus some functionality and rearranged somewhat for more width elasticity.

sakai-max.png

largecompressed

Same set of options as large but toolbar will fit in small areas – 380px wide, for example.

The choices above can be seen as arbitrary. I will try to get feedback on them. Ideally the user could swap between choices, but at the very least we can provide some useful defaults.

Next – invoking and configuring the editor in JSF, as well as the problem of multiple parameter types for some options such as the toolbar options in various editors.

JSF invocation

There are 2 tags available. <sakai:inputRichText /> and <sakai:rich_text_area />.

sakai:inputRichText:

presentation parameters: width, height (integers, in pixels), cols, rows (integers – some conversion to actual height and width takes place in the tag), toolbarButtonRows (integers, or string – in the later case it is a named set of buttons sets: “small”, “medium”,”large” and “largecompressed” )

sakai:rich_text_area:

presentation parameters: width, height (integers – in pixels), cols, rows (integers – some conversion to actual height and width takes place in the tag), buttonSet (string – the values are “small”, “medium”,”large” and “largecompressed”)


Setting up a Sakai toolbar and styling it

March 13, 2008

See Previous post: Marking Up the Sakai ToolBar.

Setting up a toolbar will depend on the templating technology. Velocity based tools will be using the #menu macro. JSF tools will be using either the ToolBar and ToolBarItem tags, or just the ToolBar + valid JSF tag children. Hand crafted markup should follow the same pattern:

<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>

Styling this markup offers many possibilities since it is sstandard markup for toolbars and navigation lists. See the absurdly rich Listamatic for options.

The default Sakai (as of today) rendering uses the following CSS:

/*toolbar - turn into a list for 2.6 - default list render here, style in tool.css*/
.navIntraTool li{
     list-style: none;
     display: inline;
     margin:0 !important;
     padding:0 !important;
}
.navIntraTool li span a{
     margin:0 !important;
     padding:0 !important;
}
.navIntraTool li span a img{
     vertical-align: bottom;
}
.navIntraTool li span,
  .navIntraTool li span.current,
  .navIntraTool li span.inactive{
     border-left:1px solid #ccc;
     margin:0;
     padding:0 5px 0 8px
}
/*special style for the first item, namely no border-left*/
.navIntraTool li.firstToolBarItem span{
     border:none;
     margin:0;
     padding: 0 5px 0 8px;
}
/*some toolbars have input type=text, and the next
   item (fieldSibling) is a submit link*/
.navIntraTool li span.formItem,
   .navIntraTool li span.fieldSibling  {
     margin:0;
     border:none;
     padding:0;
}
.navIntraTool li span.fieldSibling {
     padding: 0 5px 0 0;
}

/*style for item that would be a link
   if you were not at the page already*/
.navIntraTool li span.current{
     color:#777;
}
.navIntraTool li span.inactive{
     color:#777;
}

And this is what it looks like in th e Chat tool:

Default Sakai Style

Not much to note, is so simple. The “pipe” is actually the left border of the <span>. The first element does not get one. The end.

For something a bit more different here is the CSS (am just including the selectors that have changed from above).

ul.navIntraTool{
     background:#eee;
     padding: 5px !important
}.navIntraTool li span a, .navIntraTool li span a:visited,
   .navIntraTool li span a, .navIntraTool li span a:hover{
     color:#000;
     margin:0 !important;
     padding:0 !important;
     text-decoration: none !important
}

.navIntraTool li span, .navIntraTool li span.current,
   .navIntraTool li span.inactive,
   .navIntraTool li.firstToolBarItem span{
     border-top:1px solid #aaa;
     border-right:1px solid #333;
     border-bottom:1px solid #333;
     border-left:1px solid #aaa;
     margin:0;
     padding:3px 5px 3px 5px;
     background: #ddd
}
/*style for item that would be a link if you were
    not at the page already, and for inactive links*/

.navIntraTool li span.current, .navIntraTool li span.inactive{
     color:#777;
     border:1px solid #ddd;
     background: transparent;
}

toolbar-redmond.jpg

You can use a background image:

.navIntraTool li span, .navIntraTool li span.current,
    .navIntraTool li span.inactive, .navIntraTool li.firstToolBarItem span{
       border-top:1px solid #aaa;
       border-right:1px solid #333;
       border-bottom:1px solid #333;
       border-left:1px solid #aaa;
       margin:0;
       padding:3px 5px 3px 5px;
       background: #ddd url(default/images/tb-bk1.gif) top left repeat-x
}

toolbar-redmond2.jpg

Etc…… I think the markup now is fairly adaptable style wise. The examples above have just used one of the available canvases – the <span>, a lot more rich possibilities offer themselves if you want to style the four that are available to you (ul > li > span > a)….


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!