As of April 2016, www.newventuresoftware.com is running on Sitefinity CMS. One of the more interesting engineering challenges of moving our website from WordPress over to Sitefinity was migrating all of our original blog content. The two systems are very different, built on different platforms (PHP vs .NET) and using different databases (MySQL vs MSSQL in our case) with completely different schemas. We thought about different approaches to dealing with this problem and even considered to do a straight database to database migration, however, the complexity of the task was really high due to the specifics of the schema used by Sitefinity. At the end, we chose to use the official XML export functionality of WordPress and the Sitefinity API. This article will outline how we migrated our data and give you some pointers if you need to do the same.
Exporting the data
The first step of our journey is to export our WordPress data somehow. There are many ways to do this, however, we’ve chosen to use the built-in export functionality as being the most straightforward. Just log-in to your WordPress backend and select the following option:
It will produce an XML file with all the available data that you have created. This is all the data that we will need to begin our import into Sitefinity.
Accessing and parsing the data
Our next step would be to access the files and parse it within the Sitefinity application. To do this we simply need to host the XML file somewhere within Sitefinity, in our case we put it in a top-level folder called “Import”. Next we need to load the file during the appropriate state of the Sitefinity startup process. We will use the following hook:
Next we need to load the file:
Parsing and cleaning the data
Once the XML document is loaded we need to process the data. We will focus on the blog posts as the most important piece of content here. First we need to filter out the other data, then we need to deserialize the xml to our own POCO:
The actual process of mapping the data is very straightforward – we use the XMLDocument APIs to read the important pieces and move them to our POCO:
Now we have a collection of strongly typed POCOs with sanitized data and we have taken care of all type conversion. We are ready to use the parsed data to import it into the Sitefinity blog provider.
Pouring into Sitefinity
What happens here is pretty straightforward. We obtain a reference to the BlogsManager for the blog we want to import the data to. In our case we are using a non-default one so we are using its GUID to specify it, but you may change it accordingly for your case. Next we create a new blog post item for each post we want to import, map the data and call to important methods to save the data: BlogsManager.RecompileAndValidateUrls() and BlogsManager.Lifecycle.PublishWithSpecificDate(). The first one validates the blog post and the second one sets the publish date so that it is preserved as the original. Finally we call BlogsManager.SaveChanges().
A note about categories and tags
As you see from the code above we have special methods for categories and tags. It is of course possible to import the taxonomies into Sitefinity using the APIs, however, we opted to do that manually since it was a lot quicker to just paste the list of tags and categories when creating a dummy post. It is very convenient and straightforward to just use the UI and we were done in under a minute. We still need to map each blog post with its imported categories and tags though and this is what the following code accomplishes:
This whole process moves your blog post content including its formatting verbatim. However, when the automatic import was done, some small manual adjustments still had to be done. These were required because of slight CSS and backend differences between our WordPress and Sitefinity implementations. Your mileage may vary, but we couldn't have done it without the code above because of the amount of content that we had on hand. Hopefully it helps you too if you are dealing with a similar situation.
Full source download: click here