DotNetNuke Software

DotNetNuke Widgets Guide (Part 1 of 4)

December 25, 2009

author:

DotNetNuke Widgets Guide (Part 1 of 4)

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.

Founder NftyDreams; founder Decentology; co-founder DNN Software; educator; Open Source proponent; Microsoft MVP; tech geek; creative thinker; husband; dad. Personal blog: http://www.kalyani.com. Twitter: @techbubble
15 Comments
  1. [...] This post was mentioned on Twitter by Nik Kalyani and Dylan Barber, James Wallace. James Wallace said: RT @TechBubble Working on Part 2 of #DotNetNuke Widgets Guide... Part 1 is here http://bit.ly/7fOlg3 [...]

  2. ubiq

    Thanks for the tips! Is this skin avail for purchase btw? or free as a 'holiday' gift ;o)

  3. ubiq

    Bling..lol, wasn't sure if that is standard or specific to this site's lingo. it sure is Bling though! I really like the web2.0 theme!

  4. Efficion Consulting

    Nik, I greatly appreciate your working on this series but I must say, I'm still unconvinced by your (or anyone's) argument for the need of DNN widgets. I think the thing that will finally convince me is really good widgets. Currently, darn near all of the widgets I've seen seem unnecessary and/or degrade user experience.

    I'm not trying to be argumentative, and I'm doing my best to be informed (the STL DNN UG just spent an hour and a half on this and no one came away convinced), I just have yet to see a practical example of a useful DNN widget that isn't better handled through a external reference to a jQuery plugin.

    Clean Markup, Reusability, and Behavior Injection and Modification - can be addressed just as well by referencing external Javascript files and jQuery libraries.

    Testability and Maintainability - While I agree with this in theory, as you know, jQuery is a much more standardized Javascript framework that likely has existing plugins for doing whatever people need. If I'm going to package Javascript, it'd make more sense to do it as a jQuery than as a DNN Widget as that provides for a much wider audience.

    Performance- From a usability standpoint, I actually see the post-rendering issue as a usability negative. The content is initially rendered one way, and then changed (usually a half second or more) later. This is very confusing/disorienting to the users I've interacted with. Rendering it once the right way, even if slightly delayed seems more usable to me.

    Sincerely,
    David O'Leary
    Efficion Consulting

    • techbubble

      @david You make some valid points. I will share an example of a Product Catalog widget in Part 4 of this series that will hopefully better demonstrate the practicality of using the Widget framework.

      W.r.t. packaging, Widgets are not an either/or choice with jQuery. In fact, you can use jQuery plugins just fine within Widgets.

      On the performance front, if you have UI elements that you know will change visually, you should consider having a CSS style of "display:none" initially so that the Widget can do its thing. This may not always be practical and in those situations, using a Widget may not be the right choice.

      As developers, we find it pretty easy to deal with <script> elements and jQuery plugins. End-users authoring content struggle with this. Widgets make it possible for you to integrate re-usable Javascript (be it jQuery, or YUI or something else) so that even end-users can add interactive elements to content. Ideally this would be done by providing a toolbar icon in the rich-text editor which shows a selection of Widgets, the user clicks on one and then fills in parameter values. The idea is to provide a level of abstraction from Javascript for a user who does not know how to program, but knows HTML. Content editors that are HTML-literate already do this when they embed Flash. Widgets build upon this knowledge.

      Widgets may not be the right solution for everything. But the ability to package script so that it can be embedded in arbitrary locations with arbitrary parameters using HTML markup can be quite useful in many scenarios. As an analogy, consider that a DotNetNuke module is primarily a user control with a UI for managing its presence and settings. One could argue that it is pretty easy to add control references on an ASP.NET page and set attribute values as needed in code, thus making a module useless. This argument is true, but in some situations, a module is better and makes the user control that much more practical and useful. Widgets are no different if you think about them as packaged scripts that due to their abstraction, are easier to manage and more practical to use.

      • Efficion Consulting

        Thanks Nik. I am continuing to actively look for practical ways to use widgets. One of the paradoxes or challenges is that the only people that can build widgets, don't really need widgets (though I suppose that could be said of modules). I want to help make widgets a success, but I, and most people I've discussed widgets with are trying to get over a mental hump of proper usage where they really add value. Currently, it seems many of the available samples just aren't compelling enough.

  5. [...] is Part 2 of my four-part series on DotNetNuke Widgets. In Part 1 of the series, I covered some fundamental concepts related to DotNetNuke Widgets. In this post, I will introduce [...]

  6. [...] how you can develop your own Widgets for DotNetNuke. If you haven’t already done so, read Part 1 (overview of DotNetNuke Widgets) and Part 2 (DotNetNuke Widgets reference) to better understand the [...]

  7. suryaprakash

    hi Kalyani...

    I want to create a box(widget kind) of thing
    feature of box should be:
    1. it will fetch dynamic data from DB based on query string.
    2. it should be configurable for admin to configure on home/inner pages.... where ever i want......


    So please let me know how to handle these kind of things.... in DNN

    • techbubble

      This sounds like the perfect scenario for a DotNetNuke module. Any time you have DB interaction, or need settings to be persisted, it is best to create a module or a skin object. Widgets are for client-side interactions only.

      • suryaprakash

        Ok.. i think i didnt put my question in proper way...
        Lets say i have article/news modules ... n i have configured my news/article module in inner page and on my home page i want a box to show top 5 recent items from article/news content.. n clicking on item i should show article/new in detail section in different page.....

        Hope this is clear...
        I am sorry this is frustrating....

  8. VZ

    Thanks for the article...

    I a new to DNN, but a 'hack' developer. I posted the code in the page, and it did 'bang' off of Flickr (with a message that it doesn't support frames)... the 'duck' is just an image - not a widget - so it was of little help. Also, I don't understand from the example where the url is. is it the param value? The 'widget' I'm specifically am trying to embed has very poor documentation... they only provide: http://yourcompany.theirproduct.com/#@loadWidge... (I can get the SID)

    sorry for the confusion... but I'm weary from wading through the documentation that is out there

  9. chaloum

    Did you get an answer to this. I'm in the same boat its very frustrating

  10. Webhostingpad Coupon

    Very informative put up, love the way in which you write and I feel that the knowledge helps in a way. I don't usually say this, but I think this is a nice job done. In the event you prefer to alternate links, I would be more than pleased to supply a hyperlink again to your site. Hope to listen to from you soon. Cheers

  11. dave

    good walkthrough - as a side note - I'd recommend adding links to the other posts in this series at the end (or beginning) of each of these individual posts,so people don't have to hunt for the other 3 posts.

Leave a comment

Leave a Reply to VZ Cancel reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.