Background
I have recently moved this blog server from using Community Server 2007 (CS2007) to BlogEngine.NET.
We started blogging in 2004 using .Text, moving through the free early versions of Community Server then purchased Community Server Small Business edition in 2007. This cost a few hundred pounds. We recently decided that we had to bring this service up to date, if for no other reason, to patch the underling ASP.NET system up to date. We checked how much it would cost to bring Community Server to the current version and were shocked by the cost, many thousands of dollars. Telligent, the developers, have moved to only servicing enterprise customers, they have no small business offering. So we needed to find a new platform.
Being a [SharePoint](http://www.blackmarble.co.uk/SectionDisplay.aspx?name=Specialisations&subsection=SharePoint 2010) house, we consider SharePoint as the blog host. However, we have always had the policy to have systems that have external content creation i.e. you can post a comment, not be on our primary business servers. As we did not want to install a dedicated SharePoint farm for just the blogs we decided to use another platform, remembering we needed on that could support multiple blogs that we could aggregate to provide a BM-Bloggers shared service.
We looked at what appears to be the market leader Wordpress, but to host this we needed a MySql Db, which we did not want to install, we don’t need another DB technology on our LAN to support. So we settled on BlogEngine.NET, the open source .NET4 blogging platform that can use many different storage technologies, we chose SQL2008 to use our existing SQL server investment.
Installation
So we did a default install of BlogEngine.NET. We did it manually as I knew we were going to use a custom build of the code, but we could have used the Web Platform Installer
We customised a blog as a template and the used this to create all the child blogs we needed. If we were not bring over old content we would have been finished here. It really would have been quick and simple.
Content Migration
To migrate our data we used BlogML. This allowed us to export CS2007 content as XML files which we then imported to BlogEngine.NET.
BlogEngine.NET provides support for BlogML our the box, but we had install a plug-in for CS2007
This was all fairly straight forward, we exported each blog and imported it to the new platform, but as you would expect we did find a few issues
Fixing Image Path (Do this prior to import)
The image within blog posts are hard coded as URLs in the export file. If you copied over the image files (that are stored on the blog platform) from the old platform to the new server, on matching urls, then there should be no problems.
However, I decided I wanted images in the location they are meant to be in i.e the [blog]files folder using BlogEngine.NETs image.axd file to load them. It was easiest to fix these in the BlogML XML file prior to importing it. The basic edited was to change
src=’http://blogs.blackmarble.co.uk/blogs/rfennell/image_file.png’
to
src=’/wp-content/uploads/sites/2/historic/image_file.png’
I did these edits with simple find and replace in a text editor, but you could use regular expressions.
Remember also the images need to be copied from the old server (…blogsrfennellimage_file.png) to a the new server ( …App_Datablogsrfennellfilesimage_file.png)
We also had posts written with older versions of LiveWriter. This placed images in a folder structure (e.g. ..blogsrfennelllivewriterpostsnameimage_file.png). We also need to move these to the new platform and fix the paths appropriately.
Post Ownership
All the imported posts were shown to have an owner ID not the authors name e.g. 2103 as opposed to Richard.The simplest fix for this was a SQL update after import e.g.
update [BlogEngine].[dbo].[be_Posts] set [Author] = ‘Richard’ where [Author]=‘2103’
The name set should match the name of a user account created on the blog
Comment Ownership
Due to the issues over spam we had forced all users to register on CS2007 to post a comment. These external accounts were not pulled over in the export. However, BlogEngine.NET did not seem that bothered by this.
However no icons for these users was show.
These icons should be rendered using the websnapr.com as a image of the commenter’s homepage, but this was failing. This it turned our due to their recent a API changes, you now need to pass a key. As an immediate solution to this I just removed the code that calls websnapr so the default noavatar.jpg image is shown. I intend to look at this when the next release of BlogEngine.NET appears as I am sure this will have a solution to the websnapr API change.
There was also a problem many of the comment author hyper links they all seemed to be http://. To fix the worst of this I ran a SQL query.
update be_PostComment set author = ‘Anon’ where Author = ‘http://’
I am sure I could have done a better job with a bit more SQL, but our blog has few comments so I felt I could get away with this basic fix
Tags
CS2007 displays tag clouds that are based on categories. BlogEngine.Net does the more obvious and uses categories as categories and tags as tags.
To allow the BlogEngine.NET to show tag clouds the following SQL can be used to duplicate categories to tags
insert into be_PostTag (BlogID,PostID, Tag)
select be_PostCategory.BlogID, postID, categoryname from be_PostCategory, be_Categories where be_PostCategory.CategoryID = be_Categories.CategoryID and be_PostCategory.BlogID =’[a guid from be_blogs table]’
A workaround for what could not be exported
Were we had a major problem was the posts that were made to the original .Text site that was upgraded to Community Server, these were posts from 2004 to 2007.
Unlike all the other blogs these posts would not export via the CS BlogML exporter. We just got a zero byte XML file. I suspect the issue was some flag/property was missing on these posts so the CS2007 internal API was having problems, throwing an internal exception and stopping.
To get around this I had to use the BlogML SDK and some raw SQL queries into CS2007 database. There was a good bit of trial and error here, but by looking at the source of BlogML CS2007 exporter and swapping API calls for my best guess at the SQL I got the posts and comments. It was a bit rough, but am I really that worried over 5 year old plus posts?
Blog Relationships
Parent/Child Relationship
When a child blog is created an existing blog is copied as a template. This includes all its page, posts and users. For this reason it is a really good idea to keep a ‘clean’ template that as as many of the setting correct as possible. So when a new child blog is create you basically only have to create new user accounts and set its name/template
Remember no user accounts are shared between blogs, so the admin on the parent is not the admin on the child, each blog has its own users.
Content Aggregation
A major problem for Black Marble was the lack of aggregation of child blogs. At present BlogEngine.NET allows child blogs, but no built in way to roll up the content to the parent. This is a feature that I understand the developers plan to add in a future release.
To get around this problem, I looked to see if it was easy to modify the FillPosts methods to return all post irrespective of the blog. This would, I my opinion, have taken too much hacking/editing due to the reliance on the current context to refer to the current blog, so I decided on a more simplistic fix
- I create a custom template for the parent site that removes all the page/post lists and menu options
- Replaced the link to the existing syndication.axd with a hand crafted syndication.ashx
- Added the Rssdotnet.com open source project to the solution and used this to aggregate the Rss feeds of each child blog in the syndication.ashx page
This solution will be reviewed on each new release of BlogEngine.Net in case it is no longer required.
Summary
So how was the process? not as bad as I expected, frankly other than our pre-2007 content it all moved without any major issues.
It is a good feeling to now be on platform we can modify as we need, but has the backing of an active community.