Cover V14, i12
dec2005.tar

Making a Dashboard Widget for Systems Administration Purposes

Mihalis Tsoukalos

With the release of Mac OS X 10.4 (a.k.a. Tiger), Apple introduced a new feature called Dashboard. Dashboard is like a second layer to the desktop that consists of widgets, which are small, lightweight, task-specific applications. Figure 1 shows my personal Dashboard setup. Dashboard is activated and de-activated and, at the same time, widgets are shown and hidden, respectively. In this article, I will describe the construction of a widget for systems administration purposes.

The Structure of a Widget

Widgets are grouped into directories that must have the .wdgt extension. Widgets consist of an HTML page, JavaScript code for making the widget dynamic, Cascading Style Sheets (CSS) commands, a widget background image in PNG format, an icon image in PNG format, and a compulsory property list file called Info.plist. The icon image is what appears in the Dashboard Widget bar, and the property list file contains required information such as the main HTML page for the widget, the version of the widget, as well as other optional information.

CSS is a popular Web standard for defining the appearance of HTML pages; it usually comes in a separate file but can also be embedded inside an HTML page. The use of CSS is not required, but it greatly improves the look of HTML pages and therefore is highly desired. Last but not least is the JavaScript code, which supports the dynamic behavior of widgets. A widget can be tested during its development phase using a Web browser such as Apple's Safari provided that it does not use some particular features such as the widget.system() call.

The "Hello Sys Admin magazine" Widget

Before introducing the sys admin widget, I'll present a very simple one. This is the simplest widget that can be constructed, and it just displays "Hello Sys Admin magazine" on the Dashboard. It consists of the following components:

Default.png -- The background image used in the HelloSysAdmin.html page. The file name is mandatory.

Icon.png -- The icon that is shown for each widget in the Dashboard dock.

HelloSysAdmin.html -- The main HTML page for the widget.

Info.plist -- The property list file. Please note that the easiest way to create a new Info.plist file is with the Property List Editor.

Figure 2 shows the contents of the property list file as shown inside the Property List Editor, whereas the contents of the HelloSysAdmin.html HTML file are shown in Listing 1. The Dashboard Reference Guide lists all the allowed property list keys; however, as shown in Table 1, only the required keys along with their types and descriptions are listed. Also note that, for clarity, you can put the CSS information in a separate file and utilize that file by including the following statements inside the main HTML file of the widget:

<style>
     @import "StyleSheetName.css";
</style>
Description of the Sys Admin Widget

The previous example is static, but with the assistance of the JavaScript language, a widget can act dynamically (i.e., automatically) and periodically change the information that it displays. Our widget is going to be dynamic, and its purpose is to inform us about the uptime of our computer, its load average as well as the total capacity and the free space of each of the mounted devices. Its refresh rate is 5 seconds, because we do not want to disturb our operating system all the time, but this can be changed at will.

The Construction of the Sys Admin Widget

The files that are part of the Sys Admin widget are shown in Figure 3. Next, I'll talk about them in more detail:

SA.html -- The main HTML file for the widget.

SA.css -- The file with the stylesheet information for decorating our widget.

Default.png -- The background image of our widget (remember: this file name is mandatory).

Icon.png -- As we have told before this is the image of the widget that is shown in the Dashboard dock. The file name is mandatory.

Info.plist -- The property list file of the Sys Admin widget.

SA.js -- The JavaScript code used for the widget.

It must be said that dynamic widgets need some specific JavaScript code and mandatory practices to operate correctly. Now, let us explain SA.html file (Listing 2) in more detail. It is a regular HTML file. The only obligation that must be met is that an element must be declared inside the HTML code for presenting the output information. In our case, the element is called "OurInfo", and it should be specified as read-only.

In Listing 2, you can also see where in the HTML file the JavaScript and the CSS code files must be included. The HTML file looks very simple because the whole logic of the widget has been transferred inside the JavaScript code. This abstraction improves the readability and the maintainability of the code.

I will now explain file SA.js (Listing 3) in more detail. Four functions, getData(), UpdateWidget(), show(), and hide() are declared inside the file. Function UpdateWidget() is called from the SA.html file upon the complete loading of the HTML file. The very important code line "if (window.widget)" checks whether Dashboard is active and defines the action that must be done when it is active or when it is hidden (e.g., the widget does not consume CPU time when Dashboard is hidden). The code line "if (window.widget)" actually assigns methods to "widget.onshow" and "widget.onhide" properties.

Function show() sets the refresh rate interval for function UpdateWidget(), which is 5000 milliseconds or 5 seconds. Function hide(), which is relative to the previously mentioned property "widget.onhide", stops updating the widget when Dashboard is hidden. The getData() JavaScript function does all the crucial work.

The HTML output code is stored into variable OUTPUT_DATA. It must be told that the widget.system() function is only available to Dashboard widgets and cannot be used and tested in a Web browser such as Safari. It is a very powerful function because it allows the widget to execute external commands. Imagine that if you did not want to use JavaScript, you could have used an external Perl script that could produce all the HTML output!

Finally, document.getElementById("OurInfo").innerHTML = OUTPUT_DATA; outputs the contents of variable OUTPUT_DATA into an HTML element called "OurInfo". You must declare this element into the HTML code of the widget or else you will get no output. As you can see, SA.js uses the widget.system() call, and in order to use the widget.system call, the Info.plist file must contain an entry named AllowSystem with the Boolean value of "yes".

Listing 4 shows the small CSS code of our widget. For more extended information about CSS, refer to Cascading Style Sheets: The Definitive Guide book from O'Reilly. Graphic files Default.png and Icon.png have been made with Adobe Photoshop CS2 for Mac. Note that Icon.png file has to be 82x82 pixels. Refer to the Dashboard Reference for the full requirements for those two image files.

Finally, Listing 5 shows the contents of Info.plist file. This is actually an XML text file, so you can also create it with a simple text editor, but I think it is much easier if you use the Property List Editor.

The Installation of a Widget

It is easy to install a widget -- just double-click it and a message asking whether you really want to install it will appear on screen. In general, Dashboard provides two places for a user to install widgets: the first one is directory ~/Library/Widgets, which is inside the user home directory, and the other is /Library/Widgets, which is in the root directory of the Mac OS X 10.4 boot hard disk. If you want a widget to be available only to you, you can install it in the location inside your home directory; otherwise, put it in the system-wide location. You can uninstall a widget by simply deleting it (i.e., moving it to the Trash) from its installation directory or by using the Widget Manager.

After successfully installing the Sys Admin widget, you will get a picture similar to Figure 4. The Widget Manager, which was added with the release of Tiger 10.4.2 update, improves the control and the security we have over widgets.

Conclusions

Apple wisely decided to include widgets in Tiger. Existing widgets serve us well, but we can also construct new widgets to meet our specific needs. The making of a widget is not that difficult; it mainly involves some HTML, JavaScript, and CSS knowledge, as well as a lot of imagination.

Acknowledgments

I thank Anastasios Tjoumaidis for sharing part of his JavaScript knowledge with me.

Useful Links

Apple downloads: Dashboard -- http://www.apple.com/downloads/dashboard/

Developing Dashboard Widgets -- http://developer.apple.com/macosx/ dashboard.html

Dashboard Reference -- http://developer.apple.com/documentation/ AppleApplications/Reference/Dashboard_Ref/index.html

Flanagan, David. 2001. JavaScript: The Definitive Guide, 4th Ed. O'Reilly & Associates -- http://www.oreilly.com/catalog/jscript4/

Meyer, Eric. 2004. Cascading Style Sheets: The Definitive Guide, 2nd Ed. O'Reilly & Associates -- http://www.oreilly.com/catalog/css2/

Musciano, Chuck & Bill Kennedy. 2002. HTML & XHTML: The Definitive Guide, 5th Ed. O'Reilly & Associates -- http://www.oreilly.com/catalog/html5/

Mihalis Tsoukalos lives in Greece with his wife, Eugenia, and works as a high school teacher. He holds a B.Sc. in Mathematics and a M.Sc. in IT from University College London. Before teaching, he worked as a Unix systems administrator and an Oracle DBA. Mihalis can be reached at: tsoukalos@sch.gr.