Adding the tool icons to 2.4.x
In Sakai 2.4, the side navigation is just plain text links. in Sakai 2.5 however, they are styled with a groovy icon!
This guide is for Sakai 2.4 and will show you how to turn:
|
|
How to
There are five steps. The essence of it is that the tool links are simply wrapped with a CSS style, and then the stylesheet tells the browser what image to use. You need to modify a few source files, add in the images, then rebuild the components.
| The instructions below are just diffs of the original 2.4.x file with the modified one. If you open the appropriate file you will see where these parts need to be slotted in. |
Step 1: modify the portal (part 1)
Edit: $SAKAI-SRC/portal-impl/impl/src/java/org/sakaiproject/portal/charon/SkinnableCharonPortal.java
Index: portal-impl/impl/src/java/org/sakaiproject/portal/charon/SkinnableCharonPortal.java =================================================================== @@ -1415,6 +1415,10 @@ // check if current user has permission to see page // we will draw page button if it have permission to see at least List pTools = p.getTools(); + ToolConfiguration firstTool = null; + if ( pTools != null && pTools.size() > 0 ) { + firstTool = (ToolConfiguration) pTools.get(0); + } String toolsOnPage = null; boolean current = (page != null && p.getId().equals(page.getId()) && !p @@ -1435,6 +1439,13 @@ m.put("pageRefUrl", pagerefUrl); if (toolsOnPage != null) m.put("toolsOnPage", toolsOnPage); if (includeSummary) siteHelper.summarizePage(m, site, p); + if ( firstTool != null ) { + String menuClass = firstTool.getToolId(); + menuClass = "icon-"+menuClass.replace('.','-'); + m.put("menuClass", menuClass); + } else { + m.put("menuClass", "icon-default-tool" ); + } l.add(m); continue; } @@ -1456,6 +1467,9 @@ m.put("toolTitle", Web.escapeHtml(placement.getTitle())); m.put("jsToolTitle", Web.escapeJavascript(placement.getTitle())); m.put("toolrefUrl", toolrefUrl); + String menuClass = placement.getToolId(); + menuClass = "icon-"+menuClass.replace('.', '-'); + m.put("menuClass", menuClass); l.add(m); } @@ -1465,6 +1479,9 @@ String helpUrl = ServerConfigurationService.getHelpUrl(null); theMap.put("pageNavShowHelp", Boolean.valueOf(showHelp)); theMap.put("pageNavHelpUrl", helpUrl); + theMap.put("helpMenuClass", "icon-sakai-help"); + theMap.put("subsiteClass", "icon-sakai-subsite"); + // theMap.put("pageNavSitContentshead", // Web.escapeHtml(rb.getString("sit_contentshead")));
Step 2: modify the portal (part 2)
Edit: $SAKAI-SRC/portal-impl/impl/src/java/org/sakaiproject/portal/charon/handlers/WorksiteHandler.java
Index: portal-impl/impl/src/java/org/sakaiproject/portal/charon/handlers/WorksiteHandler.java =================================================================== @@ -254,7 +254,11 @@ SitePage p = (SitePage) i.next(); List pTools = p.getTools(); - + ToolConfiguration firstTool = null; + if ( pTools != null && pTools.size() > 0 ) { + firstTool = (ToolConfiguration) pTools.get(0); + } + boolean current = (page != null && p.getId().equals(page.getId()) && !p .isPopUp()); String pagerefUrl = pageUrl + Web.escapeUrl(p.getId()); @@ -277,6 +281,13 @@ m.put("jsPageId", Web.escapeJavascript(p.getId())); m.put("pageRefUrl", pagerefUrl); if (includeSummary) siteHelper.summarizePage(m, site, p); + if ( firstTool != null ) { + String menuClass = firstTool.getToolId(); + menuClass = "icon-"+menuClass.replace('.','-'); + m.put("menuClass", menuClass); + } else { + m.put("menuClass", "icon-default-tool" ); + } l.add(m); continue; } @@ -298,6 +309,9 @@ m.put("toolTitle", Web.escapeHtml(placement.getTitle())); m.put("jsToolTitle", Web.escapeJavascript(placement.getTitle())); m.put("toolrefUrl", toolrefUrl); + String menuClass = placement.getToolId(); + menuClass = "icon-"+menuClass.replace('.', '-'); + m.put("menuClass", menuClass); l.add(m); } @@ -307,7 +321,9 @@ String helpUrl = ServerConfigurationService.getHelpUrl(null); rcontext.put("pageNavShowHelp", Boolean.valueOf(showHelp)); rcontext.put("pageNavHelpUrl", helpUrl); - + rcontext.put("helpMenuClass", "icon-sakai-help"); + rcontext.put("subsiteClass", "icon-sakai-subsite"); + // rcontext.put("pageNavSitContentshead", // Web.escapeHtml(rb.getString("sit_contentshead")));
Step 3: modify the portal (part 3)
Edit: $SAKAI-SRC/portal-render-engine-impl/pack/src/webapp/vm/defaultskin/macros.vm
Index: portal-render-engine-impl/pack/src/webapp/vm/defaultskin/macros.vm =================================================================== @@ -383,25 +383,25 @@ #foreach( $page in $pageNavTools ) #if (${page.current}) <li class="selectedTool"> - <span>${page.pageTitle}</span> + <span class="${page.menuClass}" >${page.pageTitle}</span> </li> #else #if (${page.ispopup}) <li> - <a href="javascript:;" onclick="window.open('${page.pagePopupUrl}${page.pageId}','${page.jsPageTitle}','resizable=yes,toolbar=no,scrollbars=yes, width=800,height=600')"> + <a href="javascript:;" class="${page.menuClass}" onclick="window.open('${page.pagePopupUrl}${page.pageId}','${page.jsPageTitle}','resizable=yes,toolbar=no,scrollbars=yes, width=800,height=600')"> <span>${page.pageTitle}</span> </a> </li> #else <li> - <a href="${page.pageRefUrl}" ><span>${page.pageTitle}</span></a> + <a href="${page.pageRefUrl}" class="${page.menuClass}"><span>${page.pageTitle}</span></a> </li> #end #end #end #if (${pageNavShowHelp}) <li> - <a accesskey="6" href="${pageNavHelpUrl}" target="_blank" + <a class="${helpMenuClass}" accesskey="6" href="${pageNavHelpUrl}" target="_blank" onclick="openWindow('${pageNavHelpUrl}', 'Help', 'resizable=yes,toolbar=no,scrollbars=yes,menubar=yes,width=800,height=600'); return false">
Step 4: put the icons in place
The icons used are the FamFam silk icon set available here http://www.famfamfam.com/lab/icons/silk/
Unzip them directly into $SAKAI-SRC/reference/library/src/webapp/image/silk/
Step 5: modify the stylesheet to add the extra styles
Edit: $SAKAI-SRC/reference/library/src/webapp/skin/default/portal.css
/* PART 9 - Tool Icons */
.icon-osp-evaluation {
background-image: url(../../image/silk/thumb_up.png);
}
.icon-osp-glossary {
background-image: url(../../image/silk/text_list_bullets.png);
}
.icon-osp-matrix {
background-image: url(../../image/silk/table.png);
}
.icon-osp-presentation {
background-image: url(../../image/silk/briefcase.png);
}
.icon-osp-presLayout {
background-image: url(../../image/silk/layout_content.png);
}
.icon-osp-presTemplate {
background-image: url(../../image/silk/application_view_tile.png);
}
.icon-osp-style {
background-image: url(../../image/silk/style.png);
}
.icon-osp-wizard {
background-image: url(../../image/silk/wand.png);
}
.icon-sakai-announcements {
background-image: url(../../image/silk/flag_blue.png);
}
.icon-sakai-chat {
background-image: url(../../image/silk/user_comment.png);
}
.icon-sakai-datapoint {
background-image: url(../../image/silk/chart_line.png);
}
.icon-sakai-discussion {
background-image: url(../../image/silk/comments.png);
}
.icon-sakai-dropbox {
background-image: url(../../image/silk/folder_page.png);
}
.icon-sakai-gmt {
background-image: url(../../image/silk/award_star_gold_3.png);
}
.icon-sakai-help {
background-image: url(../../image/silk/help.png);
}
.icon-sakai-iframe {
background-image: url(../../image/silk/page_world.png);
}
.icon-sakai-iframe-site {
background-image: url(../../image/silk/house.png);
}
.icon-sakai-mailbox {
background-image: url(../../image/silk/email.png);
}
.icon-sakai-messages {
background-image: url(../../image/silk/comment.png );
}
.icon-sakai-metaobj {
background-image: url(../../image/silk/application_form.png);
}
.icon-sakai-membership {
background-image: url(../../image/silk/group.png);
}
.icon-sakai-motd {
background-image: url(../../image/silk/house.png);
}
.icon-sakai-news {
background-image: url(../../image/silk/rss.png);
}
.icon-sakai-podcasts{
background-image: url(../../image/silk/ipod_cast.png );
}
.icon-sakai-postem{
background-image: url(../../image/silk/database_table.png );
}
.icon-sakai-preferences{
background-image: url(../../image/silk/cog.png );
}
.icon-sakai-rutgers-linktool{
background-image: url(../../image/silk/application.png);
}
.icon-sakai-sections{
background-image: url(../../image/silk/group_gear.png );
}
.icon-sakai-singleuser{
background-image: url(../../image/silk/user.png );
}
.icon-sakai-syllabus{
background-image: url(../../image/silk/script.png );
}
.icon-blogger{
background-image: url(../../image/silk/book_edit.png );
}
.icon-sakai-assignment-grades{
background-image: url(../../image/silk/page_edit.png );
}
.icon-sakai-forums{
background-image: url(../../image/silk/comments.png );
}
.icon-sakai-gradebook-tool{
background-image: url(../../image/silk/report.png);
}
.icon-sakai-mailtool {
background-image: url(../../image/silk/email_go.png );
}
.icon-sakai-poll{
background-image: url(../../image/silk/chart_bar.png);
}
.icon-sakai-sitestats {
background-image: url(../../image/silk/chart_bar.png);
}
.icon-sakai-presentation {
background-image: url(../../image/silk/monitor.png);
}
.icon-sakai-profile {
background-image: url(../../image/silk/vcard_edit.png);
}
.icon-sakai-reports {
background-image: url(../../image/silk/report_magnify.png);
}
.icon-sakai-resetpass {
background-image: url(../../image/silk/key.png);
}
.icon-sakai-resources {
background-image: url(../../image/silk/folder.png);
}
.icon-sakai-rwiki {
background-image: url(../../image/silk/page_white_edit.png);
}
.icon-sakai-samigo {
background-image: url(../../image/silk/pencil.png);
}
.icon-sakai-schedule {
background-image: url(../../image/silk/calendar.png);
}
.icon-sakai-search {
background-image: url(../../image/silk/find.png);
}
.icon-sakai-siteinfo {
background-image: url(../../image/silk/application_lightning.png );
}
.icon-sakai-sitesetup {
background-image: url(../../image/silk/application_lightning.png );
}
.icon-sakai-site-roster {
background-image: url(../../image/silk/vcard.png);
}
/*admin tools*/
.icon-sakai-users {
background-image: url(../../image/silk/folder_user.png);
}
.icon-sakai-aliases {
background-image: url(../../image/silk/tag_blue.png);
}
.icon-sakai-sites {
background-image: url(../../image/silk/application_cascade.png);
}
.icon-sakai-realms {
background-image: url(../../image/silk/sitemap_color.png);
}
.icon-sakai-online {
background-image: url(../../image/silk/report_user.png);
}
.icon-sakai-memory {
background-image: url(../../image/silk/server_chart.png);
}
.icon-sakai-archive {
background-image: url(../../image/silk/page_white_compressed.png);
}
.icon-sakai-scheduler {
background-image: url(../../image/silk/clock.png);
}
.icon-sakai-su {
background-image: url(../../image/silk/user_go.png);
}
.icon-sakai-usermembership {
background-image: url(../../image/silk/drive_user.png);
}
You also need to replace the existing PART 5 in the portal.css with this one. If you have any customisations in this section like margins/colours, just take from this what you need:
/*PART 5 - SITE TOOL LINKS - children of #toolMenuWrap */ /*wrapper for ul that lists the links to tools*/ #toolMenu{ width: 9.6em; padding: 0; margin: 1em 0 0 0; color: #000; background: inherit; } #toolMenu ul{ width:auto; list-style: none; margin: 0; padding-right: 0; padding-left: 0; } #toolMenu li{ margin: 0; width: auto; padding-top: 4px; border: 1px solid #fff; text-align: right; } /*span shim for fine grained manipulation of link display (decorative) also hide if are going to be using icon links (as background of <a> nad <li> */ #toolMenu li.selectedTool span{ display: block; text-decoration: none; padding-bottom : 2px; padding-right : 23px !important; padding-top : 2px; margin-bottom : 0px; margin-left : 0px; margin-right : 0px; margin-top : 0px; background-position : center right !important; background-repeat : no-repeat !important; filter:alpha(opacity=50); opacity: 0.50; -moz-opacity: 0.50; } #toolMenu li span{ } #toolMenu li a:link,#toolMenu li a{ display: block; text-decoration: none; color: #00664B; padding-bottom : 2px; padding-right : 23px !important; padding-top : 2px; margin-bottom : 0px; margin-left : 0px; margin-right : 0px; margin-top : 0px; background-position : center right !important; background-repeat : no-repeat !important; } #toolMenu li a:hover{ text-decoration: none; color: #003123; } #toolMenu li a.selected{ text-decoration: none; color: #000; cursor: text; } #toolMenu li a.selected:hover{ text-decoration: none; color: #000; cursor: text; } /* .selectedTool { font-weight: bold; } */
Now, rebuild both the portal and reference components via 'maven sakai' in those directories, restart Tomcat for good measure (not required for the skin changes, but may be required for the portal changes) and you're done.
Going a step further
Making a few more simple changes to macros.vm and your portal.css, you can add icons to the Login/Logout links, and even add custom links in the top right hand corner, like this:
![]()
and
![]()
To do this, see the following block of code that needs to be modified in macros.vm
<div id="loginLinks"> <a href="${loginLogInOutUrl}" title="${loginMessage}" id="loginLink1"> #if (${loginHasImage1}) <img src="${loginImage1}" alt="${loginMessage}"/> #else ${loginMessage} #end </a> <a href="https://my.une.edu.au" title="To myUNE" id="myUneLink1" >To myUNE</a> #if (${loginHasLogInOutUrl2}) <a href="${loginLogInOutUrl2}" title="${loginMessage2}" id="loginLink2"> #if (${loginHasImage2}) <img src="${loginImage2}" alt="${loginMessage2}"/> #${loginMessage2} #end </a> #end </div>
Note the extra id's in the <a> tags, as well as the extra link.
And the corresponding styles in portal.css
/*main CAS link*/
#loginLink1{
display: block;
font-size: normal;
margin-bottom: 5px;
padding-right: 20px;
background-repeat: no-repeat;
background-position: center right;
background-image: url(images/lock_16.png) !important;
}
/*secondary login link*/
#loginLink2{
display:block;
font-size: x-small;
}
/* myUNE link */
#myUneLink1{
margin: 1em 0 2em 0;
display: block;
font-size: normal;
padding-right: 20px;
background-repeat: no-repeat;
background-position: center right;
background-image: url(images/home2_16.png) !important;
}
Make sure the images you have are in the right spot, rebuild the reference component by running 'maven sakai' in $SAKAI-SRC/reference, and you are done!
Acknowledgements
It would not have been possible for me to do this without the assistance from the following people:
- Chris Dunstall, CSU
- Shikh Qurishi, portfolio4u
- Ian Boston, CARET
Thanks to all of you!