DotNetNuke

DotNetNuke Skin Proxy Re-visited

December 28, 2009

author:

DotNetNuke Skin Proxy Re-visited

Some years ago, I had presented a solution for dynamically loading a skin layout based on the user’s browser type. Fast-forward to the present — at the Fall 2009 OpenForce Conference in Amsterdam I had a chance to speak to Armand Datema (@nokiko) on the same topic. The conversation occurred following my session on Advanced Skinning with DotNetNuke where I presented an early prototype of “Skinfigurator,” my module for rule-based skin loading. Armand was looking for a solution to dynamically choose a skin at run-time while overcoming the pesky ContentPane issue. If you are unfamiliar with the issue, here’s a quick synopsis…

DotNetNuke skins require the presence of a container HTML element with an ID of “ContentPane” and a runat=”Server” attribute. This is fine for most skins as it’s no big deal to define an area that serves as the default location for content (i.e. ContentPane). In the case of dynamic skin proxies (i.e. skins that load a layout based on some arbitrary set of conditions) this requirement is a problem since different layouts may want the ContentPane to be located in different places within the layout HTML.

In any event, as a result of my tinkering with skin proxies I found a clean solution for this problem. Ultimately I decided not to use it for Skinfigurator (more about the how/why in another post), however the technique is still quite useful. I promised Armand I would share it with him, and although I have been slow in making this post, it’s better late than never 🙂

The solution is trivially simple and involves just one file — the skin proxy layout. Basically what this proxy does is tap into the Init event in the page life-cycle to dynamically load the skin layout control. Since this event happens prior to the point where the DotNetNuke framework skin loader does its thing, you don’t have to bother with creating ContentPane elements in the skin proxy layout. All you need is the logic for dynamically selecting which layout to display to the user. Your Here’s the code for the skin proxy layout (I called mine LayoutSelector.ascx)

<%@ Control language="vb" AutoEventWireup="false" Explicit="True" Inherits="DotNetNuke.UI.Skins.Skin" %>
<script runat="server">
	Protected Overrides Sub OnInit(ByVal e As System.EventArgs)

		Dim layout = "Portal.ascx"
		If (Request.Querystring("layout") <> "") Then
			layout = Request.Querystring("layout") + ".ascx"
		End If
		Controls.Add(LoadControl(TemplateSourceDirectory + "/layouts/" + layout))
	End Sub
</script>

In my example, I have the code checking for a querystring variable and loading a control based on the value provided. Of course, this is not something you will want to do in production use. More likely you will want to have conditional logic based on the user, portal, browser, tab or some other controlling factor that determines which skin layout will be loaded.

There is one other thing to be aware of that is related to usability. By default, DotNetNuke lists all layouts (i.e. user controls) it finds in a skin folder in any skin layout selector in the UI. To ensure that your proxy logic is used, you will want your proxy layout control to be the only control in the skin’s root folder. All the dynamically selectable layouts should be in a sub-folder. In my example, I use a sub-folder called “layouts.” The folder structure for your skin will look something like this:

[MyCoolSkin]
— LayoutSelector.ascx
— skin.css
— [layouts]
—– Portal.ascx
—– Portal2.ascx
—– Portal3.ascx

Using this approach, the user will only be able to choose “LayoutSelector” and the Portal, Portal2 and Portal3 layouts will be hidden from the skin layout selector UI.

Co-founder/CTO WhenHub; co-founder DNN Software; founder Edaptable; educator; Open Source proponent; Microsoft MVP; tech geek; creative thinker; husband; dad. Personal blog: http://www.kalyani.com. Twitter: @techbubble
2 Comments
  1. Webmaster

    Hello. I was directed to this posting from the DNN forum. I was trying to find out if there a way to assign different skins to the user profile page, based on the user's role group? For example, we would like users in role group 1 to have their user profile pages using skin 1 and users in role group 2 to have their user profile pages using skin 2.

    We have 1 portal with multiple sites - each site is branded uniquely and has its own set of menus, etc. - site 1 uses skin 1, site 2 uses skin 2, etc.

    This is why we would like to have the profile pages of the users that belong to different sites to have the same skins as the sites they belong to.

    Just to reiterate, we are hosting these different sites under one portal.

    Would your solution work for our needs? I'm a DNN newbie and any help you can provide will be tremendous. Thank you.

  2. Rabid9797

    Webmaster, you should check out this module on snowcovered. I was searching for(and found) a way to change skins based on url but came across this http://www.snowcovered.com/Snowcovered2/Default.aspx?tabid=242&PackageID=6163 It changes skins based on role, I don't know if its what you need but its a start

Leave a comment

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.