I've been waiting eagerly for the new Blog module to be released. Quite a while back, I posted on here how the Blog module developers could make people happy by putting the module title into the Url using the 'page name' functionality of the Friendly Url API. One of my readers thought it was a good idea and posted it on Gemini, now the results are in. Here's my experience with the upgrade.
It was back in my post 'An open letter to the DotNetNuke developers of the world : please start using the FriendlyUrlProvider API for custom page names' that I originally made a suggestion that the Blog developers change the DNN Blog module code to include the Blog entry title into the Entry Url. This latest release (version 3.5) includes this functionality : a job well done. Note that I'm not taking credit : all I did was talk about it, others took the actions of requesting through Gemini and actually coding and testing the solution.
But there's more. Not only did they implement a good scrubbing routine to clean up Blog titles and output nice Url-standard ASCII, they also put in a 301 redirect to move all your old Blog posts in search engine indexes and favourites locations over to the new one. They've also added Gravatar icons and modified the page title so that the Blog title appears in it. These are all great additions to the blog platform and much needed SEO improvements.
However, it wasn't all plain sailing for me. iFinity Forums user CodeGecko posted yesterday that his code was in a 301 redirect loop when trying to access blog posts using the iFinity Friendly Url Provider. That sounded quite grave, so I immediately installed Blog 3.5 on my test environment and checked out the blog posts. Everything was as you'd expect : no problems at all.
I was impressed with how easy the upgrade had gone, so I gallantly decided to upgrade the ifinity.com.au site blog module. Oh dear - instant 301 redirects on all blog entries, just as CodeGecko had reported. Cue panic and 'I wish I had taken a backup' moment. There's a difference though - this site uses the Url Master module, not the Friendly Url Provider. Still, there was obviously a problem.
Nevertheless, in life you can either complain about problems or do something about it. I cracked open the Blog module code, and found where the 301 redirect is issued, around line 183 of 'ViewEntry.ascx.vb':
Dim showSeoFriendly As Boolean = Convert.ToBoolean(m_oBlogSettings("ShowSeoFriendlyUrl"))
Dim correctUrl As String = Utility.BlogNavigateURL(TabId, m_oEntry, showSeoFriendly)
If (Not requestedUrl Is Nothing AndAlso Not requestedUrl.EndsWith(correctUrl)) Then 'See Note
'NOTE: We use EndsWith here because
'NavigateURL returns a relative URL to BlogNavigateURL
' when friendly URLs is not turned on for the portal.
'301 Redirect to the correct format for the page
Response.Status = "301 Moved Permanently"
Response.AddHeader("Location", correctUrl)
Response.End()
End If
Now, I'm not the one to ever point bugs out with glee, because as a developer, I'm in the daily business of finding bugs of my own making, but there's two bugs in this bit of code
Bug 1 : Ignores the SEO Url Switch on doing 301 redirects
The redirect switch is saved in the 'Blog Options' page : you can turn the 'SEO Urls' off if you like. This is useful, but the unfortunate thing is, you need to be able to turn off the redirects somehow, if they're causing grief (as mine were). Unfortunately, you can't. There's no off switch, even if you turn off the SEO Urls.
SolutionEither put 'If (ShowSeoFriendly and (not requestedUrl is nothing....) - in effect only redirecting if the Seo Friendly Urls are switched on, or create a new option in the Blog Options page to allow the 301 redirects to be switched off. 301 Redirects are a very blunt stick : you go here no matter what : You always need an off switch. I found out this very early on in my 301-redirecting career
Bug 2 : Case insensitive compare
Another problem with doing this type of redirect is that the Url isn't case sensitive. This was actually the issue in my case. My portal Alias entry was 'www.iFinity.com.au' - which, after being processed by IIS/ASP.NET/DNN, was coming through as www.ifinity.com.au : hence, the .EndsWith() comparison fails comparing iFinity.com.au/My-Long-Blog-Title and ifinity.com.au/My-Long-Blog-Title. You could also point the finger at the Url Master module for not generating a lower-case version of www.ifinity.com.au - in fact both modules are probably at fault here. But the Blog module could would be better served with a case-insensitive comparison.
I've posted this here not to try and show up the Blog module developers : far from it, I think the changes are excellent and I'm excited to try out the WLW functionality. But if someone comes along to my site and says 'hey my blog module is in a 301 redirect loop because of your product' I can at least point them to how to patch their blog module code or troubleshoot their install. And hopefully some others will come along looking for how to implement 301 redirects into their code for SEO goodness.
My Changes to get my Blog Module Running Again
To clarify : these changes didn't fix the problem : it merely allowed me to discover what was wrong. What was actually wrong was that my portal Alias was a mixture of upper and lower case : all I had to do was update the portalAlias table manually to get the problem fixed.
Here's my changes as I made to the module (running this very page)
Dim showSeoFriendly As Boolean = Convert.ToBoolean(m_oBlogSettings("ShowSeoFriendlyUrl"))
Dim correctUrl As String = Utility.BlogNavigateURL(TabId, m_oEntry, showSeoFriendly)
If (showSeoFriendly And (Not requestedUrl Is Nothing AndAlso Not requestedUrl.EndsWith(correctUrl,StringComparison.InvariantCultureIgnoreCase
))) Then 'See Note
'NOTE: We use EndsWith here because
'NavigateURL returns a relative URL to BlogNavigateURL
' when friendly URLs is not turned on for the portal.
'301 Redirect to the correct format for the page
Response.Status = "301 Moved Permanently"
Response.AddHeader("Location", correctUrl)
Response.AddHeader("X-Blog-Redirect-Reason", _
"No match for requested Url (" & requestedUrl & " _
and correct url " & correctUrl)
Response.End()
End If
You'll note that I also added in an informational response header : I just like to do this sort of thing, so when you get a 301 redirect you at least know why/which bit of code did it.
Oh, and another thing : I notice that after I installed my module, all my posts came up again on Google reader. It seems that changing the permanent links also updates your blog posts in RSS readers.