Archive for tag: DotNetNuke

Searching For a New Framework

It's been a while since I've posted to this blog, and there's really no excuse I can give except this: I got bored.  Of course, there was plenty of work to be done, but I really just got tired of DotNetNuke.  My solution to break free from this crushing boredom?  Switch platforms!

I'd been toying around with the idea of learning a new framework, and I really thought that I wouldn't want anything else until there was a legitimate CMS built on top of Microsoft's MVC platform.  While I still believe that MVC will be the future of Microsoft's web stack (sorry WebForms!), I finally faced up to the fact that there won't be a mature contender in that category for a bit longer.  So, my other options?

Umbraco

I had really liked the concepts behind Umbraco when I tested it out a few years ago, but it was far from perfect and lacked much of the drop-in functionality of DNN.  It's still not perfect, but two years of dealing with DNN's obvious design deficiencies finally got the best of me.  After giving it a few days of solid examination, I'm sold.  Unless I have a compelling reason to use DotNetNuke, Umbraco will be my new framework of choice.

Drupal

I recently built a site for a local political candidate in Drupal.  They had already purchased hosting and instead of trying to get the money refunded, I decided to see why it was so popular.  It turns out, Drupal is a lot of fun to design for, giving you as much freedom as Umbraco.  The administration terminology took a little time to get used to, but with the right modules, it's easy to use.

WordPress

I've also had the opportunity to build two sites in WordPress, and I am constantly amazed at the level of thought given to the user experience.  I don't use the words 'stupid simple' often, but WordPress is the yardstick I would measure that concept by.  You'd think something as simple as a feedback form would be installed by default, and getting a backup script installed took a little shoehorning.  Overall, though, I have trouble recommending anything else to someone just looking to turn a key and blog.

 

Read more ››

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.

Read more ››

Modifying the new DNN Blog Module

I posted a while back some modifications I had made to the DNN Blog module that I found useful, namely adding the calendar-looking date to the blog entry list.  These are updated instructions for the new DNN Blog module that is now shipping with DNN 5.

Open up ViewBlog.ascx, locate and add the following after theDIV.BlogHead (line 49)

<div class="BlogPublished" title="<%# DataBinder.Eval(Container.DataItem, "AddedDate") %>">
 <span class="BlogPubMonth">
  <%# Left(MonthName(Month(DataBinder.Eval(Container.DataItem, "AddedDate"))), 3) %>
 </span>
 <span class="BlogPubDate">
  <%# Day(DataBinder.Eval(Container.DataItem, "AddedDate"))%>
 </span>
</div>

The only change I made was to add the full date as the title of the containing DIV, so that hovering over with your mouse will give the full timestamp.

I must commend the Blog module team for making the CSS much more legible and predictable in this release, although there are still a few lingering inline styles that get in the way of fully skinning the DNN Blog.  But, if that was the cost of getting awesome tags, categories, and recent items, I can find little fault in their priorities.

Read more ››

Consuming and Parsing Yelp API Requests Using jQuery

I've been hard at work designing a business directory for our neighborhood association, Newbold Neighbors, and I was enamored with the idea of not having to reinvent the wheel in terms of creating a review system.  Why do the hard work when Yelp has already done it?

I just bought another hosting plan with PowerDNN so I can begin my (slow) migration over to DotNetNuke 5.  I haven't even gotten as far as moving my own site over, but I knew that I wanted to use some of the new features for the neighborhood site (or at least I wanted new people using it to gain the advantage of never knowing some of the hang-ups/eccentricities of DNN4…)  Moving the skins and containers over was a cinch-just update the file references in the headers.  So far, so good.

I had purchased a copy of DNNDev's XMod a while back, and never really found a use for it.  I checked around SnowCovered and saw that for previous owners, the upgrade to XMod 5.5 was just $20!  What a deal-especially since it's the first version to support DNN5.  After reviewing XMod's functionality, I decided that it was definitely the right tool for the job.  Since I heart clean urls, I also went with the XMod Details View (free) which lets me show a detail view using the record id.  The only downside (actually, my biggest complaint with DNN) is the lack of slugability (I can't do /business/details/marinos-auto-repair, but I can do /business/details/id/5).

I used their tools to create a simple database of company names, phone numbers, addresses, photos, etc, and then got the layout working.

So, here's where the magic happens.  I use jQuery to get the phone number from the .phone in each .business element and pass it off to the Yelp query.  Using the callback=? is required for jQuery to perform a cross-domain JSON query.  jQuery replaces the ? with a custom identifier transparently.

I have three different views - small, regular, and details.  I want basic data displayed on the small, a bit more for regular, and some custom stuff for the details (adding in trends, individual reviews, etc).

I am pretty pleased with how it came out.  If you want to take a look, it can be found over at www.NewboldNeighbors.org/Businesses.  As someone who fancies himself a .Net programmer, jQuery has made the transition back to client-side processing fun again.  Hope this saves someone a few hours of coding.  Enjoy!

Read more ››

DotNetNuke is a designer's nightmare

I hate to say this about the framework I love, but it's true.  Anyone who's ever spent more than a few minutes developing skins or modules knows it, but so far it hasn't inspired anyone to step up to the plate and take on refactoring/refining the CSS into a more workable state.  Maybe it's not as big a deal as I think, but I'm tired of looking through the CSS that gets sent downstream and comparing it to other frameworks that do a tremendously better job of producing clean code.  I'm not a huge fan of reading other people's rants if they're not willing to offer suggestions, so here goes.  Please feel free to agree or disagree with any of these points- that's what comments are for.

Create a consistent CSS naming scheme

Enforce (or at least strongly recommend) that developers use a distinct namespace when creating the CSS for their modules.  Take, for instance, the DotNetNuke Blog module.  IMO, all of the CSS entries should be proceeded by a distinct selector (i.e. .dnnblog) that all of the blog sub-modules are wrapped in.  If I want every blog module on my site to have a certain background image, or use a certain typeface, I should be able to do it in a straight-forward manner.

Zero out default.css

And then add back in any of the available CSS reset files out there.  Yahoo's, Eric Meyers's, any of them will do.  After that, define basic styles: headers, paragraphs, etc., using the minimum amount of CSS.  Don't define font-family anywhere, especially not for every textual element possible.

If DNN wants the default skin to look polished and awesome, great!  Keep it all in the skin.css-that's what it's there for.  But don't make me hunt down and override items, especially when I'm banging my head against the wall because a div > div > ul > li is displaying in a different font than div > ul > li (remove all font-family definitions from default.css and the problem disappears).

Create an admin.css

All of the administration classes, both in the control panel up top and in the admin pages, should be rolled into an admin.css file that is only included if you're logged in as an admin.  There is no reason that CSS for the control panel is sent down with every page view.  Also, create a dnnadmin class that it's all wrapped in.

Get it done for DNN v6

The DotNetNuke skinning team lead, Timo Breumelhof, mentioned that this work was deliberately avoided so as not to introduce any breaking changes for existing installations.  Considering DNN5 broke existing skins and modules, wouldn't that have been the perfect time to also break the CSS?  I mean, if a developer already has to go back in and update class names, replace depreciated functions, etc., wouldn't that be the perfect time to do this?  No one ever said a cross-version upgrade would go smoothly (heck, even a lot of minor upgrades don't go smoothly…), but at some point, we've got to bite the bullet and move on.

Allow custom classes to be defined in the module settings

For instance, in a certain text module, let me go into the settings and assign a class to that module that would be injected into the container wrapper.  This is less important with the text module since I could just go in and wrap my text in a classed div, but say I want two surveys on the same page that look entirely different.  True, that can be done now using separate containers, but it seems like it would be a nice advanced option to have.

Update (3/14/2011)

While I haven't given up on DNN, the lack of designer friendliness has led me into the arms of Umbraco.  I'm writing this update as I'm migrating my old blog entries over, and I must say-I'm impressed with the Umbraco I see now versus what I tried out two years ago.

Read more ››

Success with extension-less DotNetNuke urls

Finally!  For the longest time, I've been jealous of the great urls that blog solutions like WordPress and even BlogEngine.net give us.  I realize that DotNetNuke is an amazing platform that is virtually limitless in its modularity and expandability, but c'mon-can we PLEASE get some nice looking URLs built-in to the platform?

Enter iFinity Friendly Url provider

Using Bruce Chapman's amazing Friendly Url provider from iFinity, I was able to get it working by making the wildcard ISAPI modification in IIS (thanks to Kyle over a PowerDNN.com for making the change).  It would be nice to have this sort of control within the control panel, but IIS 7 provides for overriding defaults from within web.config (although I was told by Kyle that people have been having issues getting an already working DNN install migrated over…)

web.config entry

Here's what it took for me to get the beauty working.

includePageName="true"
logCacheMessages="false"
regexMatch="[^\+a-zA-Z0-9 _-]"
urlFormat="HumanFriendly"
redirectUnfriendly="false"
parameterHandling="ordered"
pageExtensionUsage="never"
doNotRewritePage="(\.axd)|(/DesktopModules/)"
ignoreFileTypeRegex="(?<!linkclick\.aspx.+)(?:\.pdf$|\.gif$|\.png$|\.css$|\.js$|(?<!exif\.aspx.+)\.jpg$|\.html|\.htm|\.axd|\.swf$|\.flv$"
checkForDupURls="true"
doNotRedirect="SearchResults;"
replaceSpaceWith="-"
doNotRedirectRegex="[.]*(/logoff.aspx)"
forceLowerCase="true"
redirectWrongCase="true"
useBaseFriendlyUrls=""
triggerDictionaryRebuildRegex="&ctl=tab|/ctl/tab|/Admin/Tabs/"
allowDebugCode="false"
cacheTime="1000"
/>

Are you using this on your DNN site as well?  What has your experience been with URL rewriters (PageBlaster, HREF Exchanger, iFinity, Vertrian?)

Read more ››