Clint Patterson's Blog


Read the thoughts and musings of a cultured redneck here

Why you shouldn?t host a DotNetNuke site in a sub-folder
Specify Alternate Text
Skin folder structureI first encountered DotNetNuke incidentally.  The Admissions office at the University where I was employed was using an outside vendor for an admissions application and the application ran off DotNetNuke.  I had heard the term ?DotNetNuke? before, but didn?t have any experience with it.  It didn?t take long before the Admissions team asked us to add their logo into the background.  I was caught in the situation that many web/IT people find themselves...that?s the ?Hey you mess with computers so come do this? situation where you have no clue and have to learn something new to complete a task.
All the Admissions team wanted was their logo in the background of the site.  I started using the Firebug plug-in to look at the styles of the site and eventually I traced down the background image and over wrote the file with an updated image.  This was my first look into the folder structure of DotNetNuke.  Now days I can zip through those folder paths much more quickly, but back then it was a major headache.
This ?DotNetNuke? thing kind of intrigued me a little, especially since I could change the background!  I figured I would try to play around with it on the side and figure out what it was all about.  After all, another request from Admissions ?Can you do this too? was inevitably in my future.  I went over to GoDaddy and set up a hosting account with the sole purpose of running a DotNetNuke site on it.  I just wanted to learn about the framework and GoDaddy offered it as a 3rd party extension.  Within a couple of days I had a test site up and running and started my path of learning DotNetNuke.
GoDaddy installed the 3rd party extension of DotNetNuke in a sub-folder.  At the time it didn?t matter to me, but later down the road I would come to learn that this wasn?t a good thing.  I continued tinkering around with DotNetNuke on the side for a while and got a little better handle on it. I even started a new site running DotNetNuke on a different hosting install on GoDaddy.  I was making my way along until one day I installed a bad module?a really bad module.  Upon installation of this module my site crashed.  This was back in the DNN 4.9 days I believe.  I didn?t have a ton of background in DNN and I wasn?t a strong developer so fixing this was not going to be easy.  I got in touch with GoDaddy?s support and they responded ?We don?t support 3rd party applications.?  I was dead in the water.  
After hours of Googling I was able to find out how to remove this bad module via FTP.  I removed it and the site instantly came back up. Looking back the situation I didn?t really like the fact that my host couldn?t support the application that was running my sites.  I researched more and found other hosts that support DotNetNuke.  It became obvious to me that PowerDNN was the top dog in the DNN hosting world?and yes, they actually can help when things go wrong.  
PowerDNNShortly thereafter I moved my site over to PowerDNN.  When I moved the site the tech-support guy at PowerDNN recognized my site being in a sub-folder as an indicator that I was coming from GoDaddy.  He asked me if I wanted to leave my site in the sub-folder and he also recommended to me that this was not a good practice. Though, I told him to go ahead and leave it in the sub-folder because I had some good search engine results going by that time and I didn?t want to mess up / break any links I had showing up for my site.  He advised me again that this wasn?t the best configuration for the installation, but he did what I asked and left it in the sub-folder.  Yes, I should have listened to him!
After moving my site to PowerDNN I noticed that my site was loading way faster and that was (and is) awesome! They obviously knew something about DNN.  Everything was going good.  Time went by and then I learned about how DotNetNuke is multiportal and how you can run more than one site off a single DNN installation. It was almost too good to be true I thought.  I followed the directions and tried to create a new parent portal to run my 2nd site.  Fail!  I kept getting errors and I tried a couple of different times to make sure I was following the directions properly.  Finally I broke down and emailed in to PowerDNN.  That?s when I was informed that my site needed to be located at the root in order for the multi-portal feature to work correctly with the way I was setting up redirects and configuring my site.  Now, you may be an IIS guru or know a lot about domains and can make it work from within a sub-folder, but for the ?Regular Joe? like me I can?t make it happen.  
I had to bite the bullet ? I had to move the site to the root.  It?s not that I minded it being at the root, I just didn?t want to change the path that the links in search results had and I didn?t want to break every image/hyperlink that was on my site by altering the path.  Though, in order for my site to properly run more than one portal a move was necessary.  
I went ahead with my fingers crossed and requested that the PowerDNN guys move my site out of the sub-folder into the root.  I was impressed with how they informed me of what would occur if I did this.  They told me all the non-relative links would break and they let me know how long it would take them to get everything moved.  It didn't take long at all and my site was up and running in the root within the hour. They were accurate with both predictions of timing and the non-relative links being broken!  
  Broken Image
  I had to fix hundreds of these!
Moving the site did mess up my search results, but it only messed them up for a couple of days.  Google had crawled and re-indexed my site within 3 days and the new path was now showing up in the search results.  Also, the new site I was hoping to run off the same DNN instance was working the way it was supposed to?go figure!  Along with having users emailing in saying that "The site was down" (because they had the page stored in their cache with the old address), I did have to spend a whole week going back through the skin files, pages, and blog entries cleaning up all the now-broken links that I had just created for myself.  I also had to email frustrated users back telling them how to delete their cookies/temp files and to refresh their browsers. It was not fun at all, but sometimes learning comes with pain and the pain is what helps the lesson you learn stick with you for a while!
When the PowerDNN tech-support guy saw my DNN site coming from a sub-folder he knew it was an artifact of hosting a site at GoDaddy.  In retrospect I really wish I had listened to him when he advised me to not put the site in a sub-folder. I can?t praise PowerDNN?s team enough for the communications, knowledge, and support they gave me through the whole process of me learning a lesson!
  1. Don?t host a DNN site at GoDaddy
  2. Don?t host a DNN site in a sub-folder
  3. PowerDNN rocks!
Lesson learned. Don?t let it happen to you too!


JQuery Leaving Site Alert with External Link Icon for MOSS 2007
Specify Alternate Text
My wife and I recently celebrated our 1 year anniversary. We went on a weeklong trip to Turks & Caicos and like any loving husband would do, I bought two books to read during our vacation!  I bought a CSS3 book and a JQuery book. Yes I?m behind in all the trends, but I?m slowly making my way.  I knew a little about CSS3 and very little about JQuery so I figured I try to get clued in some so I wouldn?t be too far behind times. 
I really enjoyed both books and I?m still working on finishing the JQuery book.  As anyone would probably do, I started playing around with some code snippets seeing what I could make happen.  I used some of the CSS3 concepts I learned here in the design of this site and started using some small JQuery snippets at work.  I began showing some of my co-workers things I was testing out and before I knew it I was getting all kinds of questions about JQuery that I had no business fielding.  I?m sure similar scenarios may have happened to you before when you start learning something new, then you mess up and show someone an example, and all of a sudden you get coined the ?Champion? of whatever it is you?re investigating and a flood of requests ensue.  Fun times.
The Task
It didn?t take too long before I was tasked with trying to figure something out for our site.  The initial task was to use JQuery to add a small icon beside any link that was an external link to our site.  This had to be done in a way to where our end users wouldn?t have to take an additional step, but rather JQuery would find these external links and insert the icon dynamically.  This would give our site visitors a better user experience, cover us in case of some rare legal matter where someone thought they were on our site and something bad occurred, and wouldn?t require any extra steps on the part of our content managers.
First Steps
The JQuery book I have has many examples, but I was looking for a specific one so I started Googling and found some very helpful JQuery snippets on various sites.  The JQuery code I ended up using was a version from that I modified a little bit. The script from Learning JQuery?s site is posted below.  

$(document).ready(function() {
    $('#extlinks a').filter(function() {
          return this.hostname && this.hostname !== location.hostname;
     }).after(' < img src [equals] "/images/external.png" alt="external link"/ >');

The main part of the code that I needed was the 

            ?return this.hostname && this.hostname !== location.hostname? 

This snippet compares the path of a link to the host site?s address and if they differ then JQuery adds an image (specified by the img src path) after the link.  This code does work, but if you notice the code is selecting links that reside in a class by the name of ?extlinks?.  In my scenario I needed the JQuery code to select the links without the users having to take an additional step and there?s no way that our end-users (literally hundreds across the organization) would be able to apply a class to a link that was external (and be happy about it).  This code got me closer, but didn?t ultimately do what I needed it to do.
I thought about it, Googled, and researched more and then tried a different method.  I still wanted to use the URL path comparison part of the script, but instead of adding an image after the link I figured I should add a class to the link.  Doing it this way would allow me to find the links and add the small icon without the content manager having to take an extra step.  So I created a class called ?externallink? with this code.
    background: url( center right no-repeat;
This style uses the external icon as a background image that sits just to the right of any external hyperlink.  This doesn?t allow for any alt text on hover, but I?ll take that rather than asking all of our content managers to apply styles to external links.  The updated JQuery script to add the additional class looked like this:
The Updated Task
Success?at least momentary? I thought.  I sent out an email with a link to an updated page to my co-workers and they started giving feedback on it.  Of the feedback the two crucial ones were ?That looks good, but can you make it pop-up a message to the users that lets them know they?re leaving our site? and ?What about some of the applications maintained inside our site, but that have different URLs.?  So my second JQuery script attempt was shot down within minutes.  Additionally, I started thinking about it and I went to test out what would happen if an image got hyperlinked and, as you would imagine, the icon was added just to the right of the image. In some cases this distorted page margins when images were using the max-width of content areas.  
There?s also one more thing to add.  The site I was implementing this script on has a ?Dev? server an ?Authoring? server (where edits are made) and a ?Production? server where the live site resides.  One other thing that I noticed was that the current script was looking at the authoring server?s URL, and since it was different, ever link pretty much had an external icon. Though, once the page was published and on the production server everything looked the way I anticipated.  This would probably raise questions to our content managers if they saw a ton of external-link icons in their editing environment. This was yet another reason to filter out specific URL paths.
It was evident that there needed to be 3 additional updates to the script:
  • It had to be able to cull out specific URLs that were still ?internal? to our site and organization even though they had different URLs
  • It had to disregard images, anchor tags, & mailto tags
  • And it needed pop-up a message letting users know they were exiting the site
The Road to the "Solution"
With the updated requests I had to go back to the starting blocks.  I always love it when that happens!  Since part of the updated request was to be able to cull out specific URLs I had to find a way to make this happen.  I ended up using some of the JQuery Selectors to filter out the href values in the URLs. If the path contained certain words that are specific to our URL then I remove the externalink class that was added & add a new internallink class to it. The newly created internallink class has an empty background image. I thought it should work without adding the internallink class to it, but for some reason it didn?t, so I?m going with what works at this point.
The additional CSS class
.internallink { background: url(); }
The JQuery
//If the URL is a "mailto:" tag (to send an email) then add the class "internal" to the link
//If the URL is an anchor(contains "#" in the path) then add the class "internal" to the link $("a[href*='#']").removeClass('externallink').addClass('internallink');
//If the URL contains "" in the path then add the class "internal" to the link $("a[href^='']").removeClass('externallink').addClass('internallink');
That code allowed me to filter out specific URLs, #?s, and mailto links.  I still had the problem of hyperlinked images having external icons added to them as well as I still needed to get the pop-up message alerting users that they were leaving our site.
The ?Leaving Site Alert?
It wasn?t too bad as far as figuring out what code to insert to give the user a pop-up message alerting them that they were leaving our site.  I used the typical javascript style pop-up message by adding the code below:
//When an external link is clicked pop-up the exiting site message
      alert('You are leaving');
This just finds any link that has been cast as an external link and adds the pop-up message when it is clicked.
Removing the Icon from Images
I struggled with trying to figure out the code to remove the externallink icons from images that were hyperlinked.  I tried and tried (and in retrospect I was close), but couldn?t figure it out.  I posted a Tweet to my twitter account and shortly thereafter Johnathan Sheely responded with the exact line of JQuery code that did the job (Insert big thanks to Johnathan here!).  The code snippet he tweeted to me was:
$("div a img").each(function(){$(this).parent().removeClass("externallink")
This code removed the class of externallink from any hyperlinked image and met the goal.  After implementing this I realized that the images still needed to have the pop-up message shown even though they didn?t need the little icon.  This was easily achieved by creating a new class (with no properties) of externalimage and adding it into the script.  This would allow me to cast hyperlinked images as externallinks, but yet remove the icon from them.  The updated script?
$("div a img").each(function(){$(this).parent().removeClass("externallink").addClass("externalimage");});
Then I just added a click function to the externalimage class and the images now had no icon + a pop-up.
      alert('You are leaving');
The Solution (as of today)
I didn?t think buying a JQuery book would get me into this much trouble.  I am by no means a JQuery guru and I think there is probably a better solution for this problem out there.  If you have any insights into this scenario feel free to post in the comment section below.  
Found 2 exceptions and needed to update the post. Inside the CMS many of the link clicks run "javascript void()" scripts.  So when someone, in edit mode, clicks the "preview" button button they would get the message "You are leaving Mecklenburg County".  To overcome this I added a line to make any a href with the text "javascript" in it be cast as an internal link by adding this line:
The other issue was similar, but I had to go about fixing it in a different manner.  When clicking the Site Actions button the JQuery script would fire the "You are leaving Mecklenburg County" message.  Took me  a bit to figure out what was happening, but the Site Actions button is using an image as the link and the script was casting it as an "externalimage"...just the way I coded it to! The way I overcame this was to filter the path of the hyperlinked image.  This image resided in a folder that had the path of " _layouts " in it.  I updated the script to remove the class of "externalimage" add the class of " internallink " to any hyperlinked image with the path of "_layouts " in it as shown below:
//If the path for the img source has "_layout" in it then add class "internalink" to the link
$("div a img[src*='_layouts']").each(function()$(this).parent().removeClass("externalimage").addClass("internallink");});
This did the trick and now I think the script is usable inside of MOSS 2007.

Clint Patterson

I also blog on other sites...

And contribute to OSS Documentation...

See my pics on UnSplash