Child pages
  • Widget Best Practice
Skip to end of metadata
Go to start of metadata

Introduction

Writing widgets with HTML and Javascript is intended to be easy, and provided you follow some simple guidelines you will find it a lot easier, quicker and fun. Javascript has a chequered history. Just as the HTML standard has been hampered by Browser wars, the Javascript implementations have had their differences. These differences extend beyond what is available in each implementation to, in some cases how the browser parses the html and javascript itself. Older versions of Internet Explorer were particularly prone to strange behavior. Fortunately the browsers have become more standards compliant and the older versions of the really odd browsers have become largely obsolete. So the main cause for HTML and javascript getting such a bad name as a development platform is receding.

The best practice for widget writing is contained below but if you want a more general and more authoritative source on modern HTML, Javascript and CSS the follow three books are worth reading.

Javascript is also a poorly supported language when it come to tools. There are no compliers other than what is embedded into browsers, very few IDE's and limited debugging support. However this to has changed recently. Firefox has an excellent debugger in FireBug and Firefox v2 is a good standards compliant browser, consequently it is the browser that most developers use to develop with. The other browsers are getting better in standards compliance and developer support. Safari 3 on the Mac has some reasonable support for development (once you have turned it on) including a good profiler, however its Javascript debugging support is limited. Internet Explorer 6 is frankly awful, however Internet Explorer 7 is better and if you have been able to afford Visual Studio or one of the other Microsoft Development platforms you get a reasonable debugger, there are even some poor imitations of FireBug available for Internet Explorer but I would not recommend using it as a development platform as you are bound to create widgets that only work properly on Internet Explorer. Internet Explorer 8 is said to be more standards compliant than earlier browsers. The widget framework has been tested (and passed) on IE8 beta with no problems. Other browsers that I haven't mentioned include Opera. When developing a widget you should expect your widget to be able to work on FF1.5, FF2.0, IE5.5, IE6, IE7, Safari3, Opera8, Opera9 and IE8 when its released.

Recomended Development Platform

Developing widgets does not need as much as developing Java back end services for Sakai. If your widget is going to modify data on a Sakai server then you will need to have a Sakai server accessible to your machine, but you will not need to have it running on your machine or have access to its disk. Widgets work in the client so you just need a way of loading them into a browser. Initially this can be direct from the File System, but later you can use an instance of Apache to proxy through to the Sakai server. I will explain how to do this later.

To develop Sakai Widgets you need

  • An editor
  • A browser
  • The widget SDK

Ideally this would be

Code Compilation and Validation

You will save yourself a considerable amount of time if you validate your Javascript, html and css. This will give you give you something a bit closer to a compiler and will catch strange errors. The HTML Tidy plugin for Firefox will validate your pages as you load them. Valid XML is important to ensure that your widget does not put Internet Explorer into Quirks Mode when it will apply CSS in a different way. In addition if you pass your CSS through a CSS validator that will tell you where there may be issues with the format, althogh most browsers will warn you of issues in the console log. When it comes to Javascript it is well worth passing your Javascript through jslint to make certain that you are not making basic formatting mistakes that may be syntactically correct but have strange side effects. I have found that this tool has exposed a number of otherwise hidden bugs. So thats

Build

You will probably want to create a maven 2 build for your project to make it deploy as a war. At the moment we want to maintain rapid development and feel that imposing a build onto what is a filesystem development pattern slows down the development. However we may add a build structure that incorporates some of the tools above.

Javascript Guidelines

It is vital with any HTML fragment that will co-exist in a borwser window with other HTML fragments that it is well behaved. If we were building a new Facebook, we would provide server infrastructure to ensure that all harmful tags and constructs were striped from the code, but we are not so we are using developer education and code review, which may be automated to ensure that the code conforms. The main requirement is that what ever is expose to the global name space is guarenteed to have a minimal footprint on that space, and to be unique in that space.

Examples:

Bad Code

This code exhibits a number of problems, its functions are in global space at the top of the javascript stack and generic names have been used. If 2 widgets with different hideElement() functions were used the later one would take precedence breaking the earlier widget. Code like the above is not acceptable for a widget environment.

Slightly better Bad Code

The above is slightly better, as now at least the fuctions and global variables probably wont collide with other widgets, but there is still a significant amount of stuff being put into the global space.

Acceptable Bad Code

Now at least we have one top level variable in global space and all the variables that are needed are protected in the widgets namespace. There is minimal chance of collision with this approach. I am not commenting on the suitability of the methods, just the layout and the impact on other widgets.

Classes, Objects or static namespaces

There is plenty of argument on evils of various javascript constructs. For widget development you can use what you like, if it works and does not interfere with other developers. However if you can thing of you code as service oriented code where static methods exist within namespaces, the you will not need to fight with things like the this pointer. If however you decide to use classes that can exist as a standalone object then you need to be aware of scoping and visibility, especially when you start to use setTimeout() calls.

CSS Guidelines

As with Javascript there is a global naming issue with the css that you use within a widget. You should construct your CSS classes so that thy do not interfere with the portal or other widgets. There are number of ways of doing this.

Bad CSS Code

This is bad because all links in on the page will be styled using the styles from the widget and not from the portal. If anyone else happens to use widget_title, then it will also be styled incorrectly. However from a performance point of view, .widget_title is scoped to the whole document and will slow down css rendering if it is not applicable to the whole document

Slightly better Bad CSS Code

This is slightly better since now I just need to add the class mywidget to all links within the widget. The widget_title class is still scoped incorrectly.

Modified Markup
Slightly better Bad CSS Code

Now the widget html is encapsulated in a div with class mywidget_container, which enables me to scope my css down to the container. This allows me to write simple class names inside the container but gain control over the css with scoping. It prevents the css leaking into other containers, and optimizes the rendering by reducing the volume of css available at the top level.

Conclusion

If widgets are written along these guidelines then it will be easier to write the widgets in the first place and easier to integrate them. The page has tried to guide the development of html/javascript widgets, it does not attempt to comment of the best practice for code style or code content and makes no comment on the design, usability or accesability of the resulting widget.

  • No labels