Learn More





DNN Community Blog

The Community Blog is a personal opinion of community members and by no means the official standpoint of DNN Corp or DNN Platform. This is a place to express personal thoughts about DNNPlatform, the community and its ecosystem. Do you have useful information that you would like to share with the DNN Community in a featured article or blog? If so, please contact .

The use of the Community Blog is covered by our Community Blog Guidelines - please read before commenting or posting.

Next Version of DNNMenu

I am getting a little excited for what is in store for the community with the upcoming release of the DotNetNuke Webcontrols v2.0.  Unfortunately, I have not had much time to blog on what I have been working on. This blog entry is meant as a means to allow the community to offer constructive feedback on the direction of one of the core controls found in DotNetNuke, the DNNMenu.

Brief History
Before I discuss where we are going, lets review where we started and how we got to this point. The first Menu control within DNN was the SolpartMenu. It provided a hierarchical navigation structure to your portal. It was developed to work against many of the older browsers like Netscape, MacIE, IE5, etc. Back then I had the mentality that the control should handle all the different quirks between browsers. This caused a lot of the rendering of the menu to be hardcoded to handle specific use cases across all browsers. Probably the easiest to explain is the embedded border logic found within solpart when you hover a menu. This has caused many skin developers headaches (including myself). Seeing that there was a lot of logic within Solpart that needed refactoring, and no easy way to make those changes without killing the hundreds of existing skins out there, I felt it was best to create a new menu. Additionally, the DNN project has been making strides to segregate itself from third party components. Therefore, I decided to offer the next version of the menu to the core. This version would utilize the ClientAPI, thus allowing the menu script to not contain any cross-browser logic when it needed to position itself. It could focus on the single idea of rendering the menu.

The original skin object dealing with the menu structure was hardcoded to both obtain the DNN tab hierarchy and populate the solpartmenu.  In order to allow any control an easy means of integrating with the DNN core, I developed the Navigation Provider. With that in place, both the menu contents (styles, text, etc.) along with the control doing the rendering could easily be tweaked without the need to modify core code.

The navigation document above discusses some design decisions that were made. Namely, how should the hierarchy be passed down to the client.  The tradeoff that was chosen was to do what was most efficient, and allowed for the most flexibility. This decision led to most controls rendering only a container control with expando properties attached.

<span class="NavRootNode" id="nav_NavMenu" orient="0" sysimgpath="Images/" imagepaths="images/" rarrowimg="Images/icon_arrow_right-sm.gif" carrowimg="Images/icon_arrow_right-sm.gif" css="NavRootNode" csschild="NavChildNodeDefault" csshover="NavHoverClass" csssel="NavSelClass" mbcss="NavMenuBarClass" mcss="NavMenuClass" cssicon="NavIconDefault"></span>

The structure for the menu would be passed separately as XML. When the control initialized, the xml would be read in and the menu's html would be created.

Decision to use Expandos
I still like the idea of having the main container object for the control contain all its properties directly on the element. However, custom expandos cause issues with conformance validation. In order to address this problem, version 2 of the webcontrols will now pass these parameters separately in a JSON.  I borrowed this idea from how the AJAX Control toolkit functions. In fact, I even added similar attributes to the toolkit to automatically build this json string.

<ClientProperty(), ClientPropertyName("sysimgpath"), DefaultValue("")> _
SystemImagesPath() As String

This simple change allows the menu to render 100% valid XHTML code. (This of course, is not hard to do, as the only thing rendered to the client is a SPAN tag with an ID).

Decision to use XML
The decision to use xml was one I wish I didn't make. At the time, JSON was not the buzz word it is today. The amount of effort I spent on creating a cross browser implementation of an XML parser is annoying to think about. Not to mention how much more verbose XML is in comparison to JSON. I guess the only good thing that came out of this was the fact that I could truly say that my AJAX code was true to its acronym (Asynchronous JavaScript and XML). Version 2 of the webcontrols no longer use the dnn.xml namespace, though the namespace will still exist in the ClientAPI. .

New RenderingMode Property
The menu now has a RenderMode property that supports a few different ways of rendering. When set to its default (Normal) the following will be rendered from the server to the client.

<span class="NavRootNode" id="ctl00_NavMenu"></span>

Many people have become concerned with this as they feel that this does not address search engine crawlers. What most fail to realize, is that the server-side control detects if a crawler is viewing the page (System.Web.HttpContext.Current.Request.Browser.Crawler), and if it returns true, a spider friendly version of the menu is rendered. Something like


div width="100%" class="DNNMenu NavMenuBarClass" name="nav$NavMenu" id="nav_NavMenu">
div name="0" id="0" style="padding-left:0px;">
span class=" "></span><a class="NavRootNode" href="default.aspx">Home</a>

While this markup is far from pretty, it serves its purpose. Crawlers can obtain the values and I also hear they aren't that picky as to what the rendering looks like ;)

Still, there are those in the community who really want the capability of rendering an unordered list in a similar manner to the original SuckerFish implementation. Apparently, there is some mistrust as to whether the method provided by ASP.NET actually works. The reason I have never gone this approach is outlined in the document above. It states that the html markup for a control typically is larger than the raw data itself.

In order to appease this group of users, I have decided to add a new RenderingMode of UnorderedList to the menu. Instead of the server spitting a simple version of the span element, an
unordered list will be emitted to the client.

<ul class="NavRootNode" id="ctl00_NavMenu">
li id="ctl00_NavMenuctr0">
a href="default.aspx">Home</a>
li id="ctl00_NavMenuctr10">
ul id="ctl00_NavMenusub10">
li id="ctl00_NavMenuctr12">
a href="about.aspx">About</a>

This is the part where I am hoping the users who love css rendering, especially the suckerfish fans can help.  I can't seem to find any css menus that allow for an icon to show up to the left of the text.  I would expect to be able to do something like the following and have it work fine across all browsers.


li><img src="folder.gif" /><a>New...</a></li>

However, I cannot seem to find any other unordered list menus putting icons in their menus.  Is this a limitation of this approach?  Ideally, the menu would support an optional icon, where one item in a menu has an icon and the other does not, and things still line up (this is easily accomplished with tables).  Also, I am struggling with finding an example of these menus that do not require fixed width submenus.  I would like the menu to automatically expand to the size of the max width of the text contained.  Any info on if this is possible to accomplish would be greatly appreciated.

The first version of the DNNMenu allowed for its client-side rendering to not use tables.  Instead it placed the burden of getting the css right on the designer, something that few were able to do partially due to the reasons above.  I fear that if I don't find the answers to these questions this new rendering mode will suffer the same fate.






There are currently no comments, be the first to post one.

Comment Form

Only registered users may post comments.


2sic Daniel Mettler (125)
Aderson Oliveira (15)
Alec Whittington (11)
Alex Shirley (10)
Andrew Nurse (30)
Anthony Glenwright (5)
Antonio Chagoury (28)
Ash Prasad (22)
Ben Schmidt (1)
Benjamin Hermann (25)
Benoit Sarton (9)
Beth Firebaugh (12)
Bill Walker (36)
Bob Kruger (5)
Brian Dukes (2)
Brice Snow (1)
Bruce Chapman (20)
Bryan Andrews (1)
cathal connolly (55)
Charles Nurse (163)
Chris Hammond (203)
Chris Paterra (55)
Clinton Patterson (28)
Cuong Dang (21)
Daniel Bartholomew (2)
Dave Buckner (2)
David Poindexter (3)
David Rodriguez (2)
Doug Howell (11)
Erik van Ballegoij (30)
Ernst Peter Tamminga (74)
Geoff Barlow (6)
Gifford Watkins (3)
Gilles Le Pigocher (3)
Ian Robinson (7)
Israel Martinez (17)
Jan Blomquist (2)
Jan Jonas (3)
Jaspreet Bhatia (1)
Jenni Merrifield (6)
Joe Brinkman (270)
John Mitchell (1)
Jon Henning (14)
Jonathan Sheely (4)
Jordan Coopersmith (1)
Joseph Craig (2)
Kan Ma (1)
Keivan Beigi (3)
Ken Grierson (10)
Kevin Schreiner (6)
Leigh Pointer (31)
Lorraine Young (60)
Malik Khan (1)
Matthias Schlomann (15)
Mauricio Márquez (5)
Michael Doxsey (7)
Michael Tobisch (3)
Michael Washington (202)
Mike Horton (19)
Mitchel Sellers (28)
Nathan Rover (3)
Navin V Nagiah (14)
Néstor Sánchez (31)
Nik Kalyani (14)
Peter Donker (52)
Philip Beadle (135)
Philipp Becker (4)
Richard Dumas (22)
Robert J Collins (5)
Roger Selwyn (8)
Ruben Lopez (1)
Ryan Martinez (1)
Salar Golestanian (4)
Sanjay Mehrotra (9)
Scott McCulloch (1)
Scott S (11)
Scott Wilkinson (3)
Scott Willhite (97)
Sebastian Leupold (80)
Shaun Walker (237)
Shawn Mehaffie (17)
Stefan Cullmann (12)
Stefan Kamphuis (12)
Steve Fabian (31)
Timo Breumelhof (24)
Tony Henrich (3)
Torsten Weggen (2)
Vicenç Masanas (27)
Vincent Nguyen (3)
Vitaly Kozadayev (6)
Will Morgenweck (37)
Will Strohl (163)
William Severance (5)
Try Evoq
For Free
Start Free Trial
a Demo
See Evoq Live
Need More Information?