Integrating DotLess Dynamic CSS with DotNetNuke

I've been hearing about the Less CSS framework for a while, and it always looked like a great idea-for Ruby developers.  Then I had a thought-maybe I should search "less css .net."  30 seconds later, I'm staring at DotLessCss and wondering how hard it would be to integrate with DotNetNuke.  Turns out, it's pretty easy.

One caveat is that you need the extension .LESS to be handled by ASP.Net.  If you have wildcard support enabled for .Net in IIS through your host or are running ASP.Net 4.0, you're set.  I already had this configured for extension-less urls, but if you don't have it set up, ask your host.  It's literally a 30-second modification-if they try to charge you, see if you can press them to do it as a favor for being such a great customer. :)

Once that's completed, the following steps should get you there:

  1. Copy dotless.Core.dll into your \bin folder
  2. In web.config, under / (IIS 7), add
  3. In /(IIS 6), add
  4. In the DNN root, open Default.aspx.vb, and browse down to ManageStyleSheets() (around line 340)
    Since I don't really use the default.css file (except to paste a CSS reset into the top of the file) or the portal.css (which I delete so it doesn't get added to the list of files to download), I only added in .Less support for the skin css files.  Look for the following:

    If File.Exists(Server.MapPath(ctlSkin.SkinPath) & "skin.css") Then
    objCSSCache(ID) = ctlSkin.SkinPath & "skin.css"
    Else
    objCSSCache(ID) = ""
    End If

    which becomes

    ' .LESS CSS
    If File.Exists(Server.MapPath(ctlSkin.SkinPath) & "skin.less") Then
    objCSSCache(ID) = ctlSkin.SkinPath & "skin.less"
    Else If File.Exists(Server.MapPath(ctlSkin.SkinPath) & "skin.css") Then
    objCSSCache(ID) = ctlSkin.SkinPath & "skin.css"
    Else
    objCSSCache(ID) = ""
    End If

This way, if skin.less exists, DNN will disregard skin.css.  If you want to use .Less in other places, you can make the same modification above for default.css or below for portal.css.  If you prefer to leave the .css extension, you could use .less.css instead (Visual Studio will still provide most CSS intellisense).

I like the modification above because you can fit it into any DotNetNuke installation without having to recompile any of the DNN core DLLs.  What works for skins, though, doesn't work for containers.  The container CSS injection isn't handled from default.aspx.vb, instead being compiled as DotNetNuke.UI.Containers.Container.  Changing this would require making a similar change in the DNN source code and the recompiling.

CAUTION:  Keep in mind that upgrades will now break your sites, so you'll have to add those lines back into default.aspx.vb every time you run anything that overwrites it.  For me, that's a price worth paying, but it does add an extra step in your site maintenance.  Use this with caution, especially on a production site.  As always, make changes on your test server first.  Even if you only use this on your test server, you can always use .Less to emit your final skin CSS file.