DotNetNuke Widgets Guide (Part 1 of 4)

December 25, 2009

WidgetsStarting with Release 5.x, the DotNetNuke platform has included a Javascript-based Widgets framework for dynamically injecting client-side interactivity into skins and modules. Like most Open Source developers, I thoroughly enjoyed coding the Widget framework but neglected to document it properly. In this four-part series I hope to correct this shortcoming. In Part 1, I will introduce some fundamental concepts of the DotNetNuke Widget Framework. In Part 2, I will provide a reference for existing widgets that are included with DotNetNuke. In Part 3, I will step through the process of developing a Widget. Finally, in Part 4 I will create a working Widget that you can download and use to increase your understanding of the framework and to build your own Widgets.

Widget Fundamentals

Just as you can add modules to a DotNetNuke page to add application functionality, so also can you add Widgets to DotNetNuke skins and modules to add interactivity. For example, in a skin, Widgets may enable a user to dynamically switch a stylesheet to change page appearance, add a photo gallery, embed a video etc. In a module, Widgets can provide interface elements for navigation, drag-and-drop sorting capabilities etc. Widgets are first-class citizens of DotNetNuke’s extensibility model and can therefore be packaged individually or in combination with DotNetNuke modules and skins using the familiar DotNetNuke manifest and zip file model. Widgets are created using Javascript code that builds on the Microsoft ASP.NET AJAX client-side library and can leverage jQuery or any other client-side framework for additional capabilities. They can be embedded into any extension type that manifests itself in the client browser (module, skin, skin object, container) and use a syntax that should be familiar to skin designers. Here’s an example of a Flickr Widget:

<object codebase="EmbedWidget" codetype="dotnetnuke/client" id="MyWidget">
    <param value="Flickr" name="type" />
</object>

That’s it…three lines of HTML markup to embed a Flickr slideshow like the image below instantly into a DotNetNuke page. Go ahead…try it out by adding the above markup in an HTML module (in source)…I’ll wait.

Flickr slideshow using EmbedWidget

At this point you are probably wondering what the benefit of Widgets is if they are coded in Javascript and make use of pre-existing client-side libraries. After all it’s not that difficult to embed a simple <script> element into your skin or module and add any code that you desire directly at the appropriate location. And using my simplistic example of a Flickr slideshow, you could just as easily get the embed code for the slideshow and use it directly.

Five Reasons for using the Widget framework

Let’s address these questions by reviewing the five primary reasons for using the Widgets framework:

Clean Markup: Using Widgets enables you to keep the HTML markup for your skin or module clean and script-free. Since Widgets are embedded using the standard <object> element, you can add functionality without sacrificing readability. In fact, Widgets lend themselves to more semantic markup as the intent of the markup is usually evident from the name of the Widget and the parameter name/value pairs. Embedding script directly or referencing an external script makes your markup harder to read and maintain.

Reusability: If you have some Javascript code that needs to be used in multiple skins or modules, wrapping it into a Widget makes it easy for you to re-use the code while taking advantage of DotNetNuke’s packaging and versioning capabilities. Sure, you could store a script file in a central location and reference it, but Widgets afford you greater control in using, deploying and maintaining the code. Furthermore, by implementing the code as a Widget, you now have the ability to easily pass parameters without messing around with querystring parameters to script file references or in-line Javascript variable declarations. Such reusability does come at a small price in terms of time and effort required, so it’s probably not a good idea to create a Widget for a single-use script.

Testability and Maintainability: Unlike context-less Javascript files or embedded script, Widgets are stand-alone, contextual entities. Therefore they can be tested and debugged in a variety of scenarios quickly and easily with minimal effort. If you just add a <script> reference to a Javascript file in your HTML markup, you have no way of knowing if the dependencies for the script are being loaded or not. You have no idea if any variable necessary to pass parameters to the script are already on the page or not. These issues are eliminated using Widgets. When you use a Widget, you know that its dependencies will be correctly loaded and its parameters are available in the Widget’s HTML markup itself.

Performance: Browsers execute inline script and fetch scripts referenced using the <script> element synchronously while rendering a page (you could use the “defer” attribute, but browser support for this is not consistent). This puts an unnecessary wait penalty on the site visitor. Using jQuery’s document.ready() method mitigates this somewhat, but remember, the browser still has to switch context from HTML to Javascript, parse the script and then switch context back to HTML. Widgets provide a cleaner way to add client-side interactivity as they are loaded at the end of a page when the DOM is ready. Thus, the visitor will have a better user experience as HTML, CSS and images will already have been rendered. If you would like to learn more about how browsers handle script, read Timing and Synchronization in JavaScript.

Behavior Injection and Modification: It’s quite easy to add “onclick” and “onmouseover” attributes to HTML elements to add client-side interactivity. Unfortunately, this results in horrible markup that is difficult to maintain and difficult to debug. Widgets force you to use behavior injection and modification in order to attach events to DOM elements. This keeps all behavioral code in one location and makes it incredibly easy to maintain through good use of jQuery selectors. It’s also results in a cleaner separation between the markup and the script.

Hopefully this information has provided you with enough knowledge to understand when Widgets are a good idea and when they are not. Now let’s take a deeper look at the client-side page life-cycle to understand the Widget rendering process.

Widget Rendering Process

Widgets are rendered only if the Site Setting “Enable Skin Widgets” is checked. This value is checked by default, so you can be assured that Widgets will render on most DotNetNuke sites. (We should probably re-name this setting to “Enable Client-side Widgets”…when I was first coding the Widget framework, I was focused on usage scenarios involving skins and used the term “skin widgets.” The term stuck even though Widgets can be used in any DotNetNuke extension that renders code to the browser.) By enabling this setting, a single reference to a Javascript file is injected into the very end of the page:

&lt;script type=&quot;text/javascript&quot; src=&quot;/Resources/Shared/scripts/initWidgets.js&quot;&gt;&lt;/script&gt;

When the script loads, it initiates a four-step process: Framework Initialization, Widget Detection, Widget Instantiation and Widget Rendering. This process is illustrated below:

Widget Rendering Process

The Widget framework uses jQuery to load all required scripts in an asynchronous manner. When a script is done loading, an event is fired to carry out the next step in the rendering process. All of this happens pretty fast, and most notably, after the page is already rendered in the browser. If you view the HTML source for the page, you will see no difference in the markup from what was originally sent by the server (i.e. <object> elements). However, if you query the DOM using FireBug or a similar tool, you will see that each <object> Widget element has been replaced with a <div> or similar element with the same ID as originally given to the <object> element. This enables you to use CSS for styling the Widget using an ID selector (i.e. #MyWidget).

In this post, I provided an introduction to the DotNetNuke Widget Framework. In the next post in this series, I will introduce you to the Widgets included with DotNetNuke and provide a usage reference for each Widget.