Creating Permalinks for SharePoint Blog Post Items

Home » SharePoint Administration » Creating Permalinks for SharePoint Blog Post Items

Creating Permalinks for SharePoint Blog Post Items

Posted on

Most commercial blogging platforms use a fixed URL structure, known as a "permalink", to identify posts – something like "http://www.myblog.com/2012/09/13/This-Is-My-Post.html". This structure makes it easy to reference a particular post, supports trackbacks/pingbacks, and makes it simple for search crawlers to locate content. Unfortunately, the SharePoint 2010 Blog template has no concept of how an actual blog platform should work – permalinks are an entirely foreign concept. Because SharePoint stores blog posts as individual list items, the URL structure is comprised of a fixed root path with a query string parameter for the item ID, such as "http://www.binarywave.com". Awful stuff.

Short of writing an HTTP Handler to construct friendly URL’s, SharePointers are stuck with this less-than-optimal format. That being said, it would be helpful if the various views for the Posts list in a blog actually used this link structure to refer to each item but, alas, they don’t; instead, they use and even worse path identifier that references an application page in the _layouts directory with parameters for the list and item ID (i.e. "http://www.myblog.com/_layouts/listform.aspx?PageType=4&ListId={89CBE813-99F7-4257-A23A-5FEFC377336B}&ID=269"). This is the equivalent of not only forgetting to put bullets in your gun but leaving the gun behind at the saloon on your way to the OK Corral – in other words, it makes an already bad situation even worse.

This makes summary listings of blog entries, such as the Archives view or Categories, next to impossible for search engines to follow and other bloggers to reference. If your blog happens to be a subsite under a publishing web it’s very likely that the Lockdown feature has been enabled which prevents readers from even accessing content in the _layouts directory. And if you are doing any type of SEO on your site at all then you likely have a robots.txt file with DISALLOW entries for system directories like _layouts, _vti_bin, _catalogs, etc. It’s enough to make you want to pull your hair out (if you have any left at this point).

Strangely enough, if you examine the views on the Posts list you’ll see a field entitled "Permalink". Now that sounds like a good solution to this problem, doesn’t it? If only it were so. The permalink field is a computed column that renders an icon with the proper link to the post (as proper as it gets, anyway – it’s still referencing ‘/Lists/Posts/Post.aspx?ID=[ItemID]’) instead of a hyperlink wrapped around the Title text. You’ll see this at the bottom of each post next to the email link and number of comments. That’s just throwing salt in the wound – first, take away real permalink functionality, then give us a field that almost-but-not-quite renders a semi-permalink. Oh, happy day.

So what can we do to fix this problem? Well, to begin with, we can add a column for the permalink value we want to create, the value of which should look something like "< a href=’http://www.myblog.com/Lists/Posts/Post.aspx?ID=1′ >My Post Title< /a >" (spaces added to fool the rich text editor); however, if we just create a computed column (which would be the simplest solution) then SharePoint will spit out the text of our markup and not an actual hyperlink (so much for simple solutions). So we need to use a Hyperlink column, which requires the format "Link, Text", meaning our input should look like "http://www.myblog.com/Lists/Posts/Post.aspx?ID=1, My Post Title". Ok, great, but how do we get that into the new column without manually having to input it each time we create a new post? And, even more challenging, how do we go back and update all of our old posts to use the new value?

There are a couple of ways to approach the first part of the problem, one with code and one without. Using code, we can write an event receiver to fire on ItemUpdated, parse out the ID and Title, then set the link column value and update the list item. Using a no code approach, we can use a workflow to do essentially the same thing – run on created or updated, set the link field value to a dynamic string formatted as "Link, Title", and use lookups to get the ID and Title values. Simple enough and should work just fine on new items. But what about fixing up the links on all of the existing items?

This can be done either with code (probably a simple console app) or Powershell. As writing an executable is probably overkill for this particular situation, Powershell would be a quicker way to get the desired result. Either way, the process is identical – get the list, loop through the list item collection, extract the Title and ID values from each list item, construct a string and store it in the link field. Here’s a script to do just that:

$site = new-object Microsoft.SharePoint.SPSite("http://www.myblog.com")
$web = $site.openweb()
$list = $web.lists["Posts"]
$items = $list.getItems()
foreach ($i in $items) {$i["PostLink"] = "http://www.binarywave.com/blogs/eshupps/Lists/Posts/Post.aspx?ID=" + $i.ID + ", " + $i.Title;$i["_ModerationStatus"] = 0;$i.update();}

There are a couple of things to note about this script. First, "PostLink" is the field that holds the link value (the name is arbitrary). It is an out-of-the-box Hyperlink field added to the Posts list. Second, don’t forget to call Update() on each item or the changes won’t persist to the database. Finally, and this one will give you heart palpitations if you forget to include it, be sure to Approve each list item by setting the _ModerationStatus field to zero (unless you’ve turned off approvals for the Posts list – it’s enabled by default); otherwise, when you go back to your site to view the wonderful results of your handiwork you’ll be presented with a blank web part on the default page of your blog. Manually approving hundreds of list items is nobody’s idea of a good time.

The last step is simply to alter the various views of the Posts list (such as "Archive") to use the new link value field instead of the "Title [Linked to Item with Edit Menu]" field. Now you’ve got all the bases covered – the workflow will handle creation of the permalink when new posts are created, the Powershell script fixed up all the existing items, and the views contain the proper links. Job done.

Now, if we could only get a REAL permalink field in the SharePoint blog template the world would be a much happier place – birds would sing, the sun would shine, money would grow on trees, Dr. Pepper would flow in streams, beer would be free…yeah, whatever. Don’t hold your breath.