Once you have liberated your content from Wordpress, getting it generated by Snow is fairly trivial.
- Compile Snow.
- Copy SnowSite somewhere.
- Copy the fresh Snow files into a sub folder of the folder you created in #2. Mine is called
_compiler and contains
- Clean out the _posts folder, as it contains the markdown for philiphaydon.com, who is the creator of Snow.
- Edit the
snow.config. You'll want to change things to reflect your details, e.g. your name, email, blog title etc. The urlFormat is important. Mine is set to
yyyy/MM/dd/slug, which follows the same pattern as my old wordpres blog. This important because it means that the blog posts be generated with the same url, which means I don't have to dick about with 302 redirects or any of that shit.
- Compile your site. This is best achieved via a batch file which should live in the folder above the \Snow folder you created in #2. The batch file will look something like:
.\Snow\_compiler\Snow.exe config=.\Snow\ debug=true server=true
Here, we tell snow where to find the
snow.config file, specify that we'd like snow to give us some debug output to the console window, and that we want it to fire up its built in web server so that we can preview our site.
Name the batch file
compile.snow.bat so that Snow doesn't delete it when it compiles your site. When you now execute the batch file, Snow should compile your blog and fire it up in your default webbrowser, so you can check it out, and make sure it looks ok.
At this point, you should be ready to deploy your site somewhere.
Wherein I show you how I moved my blog from Wordpress, to a statically generated html hosted on github. I will assume that you have a wordpress blog, hosted on either Wordpress.com or your own hosting. If you don't have a wordpress based blog, then that's ok, most of this will still apply.
We can identify a pretty broad set of tasks straightaway:
- Export posts from wordpress into markdown.
- Configure Sandra.Snow to publish our markdown.
- Make it look nice.
- Setup github to publish our new site.
- Update our DNS settings.
Liberating content from Wordpress
Jekyll has some tooling that enables auto-exporting of your blog and its contents into markdown for you, but as it is still (relativly) early days for Sandra.Snow, there is no such tooling for us to leverage.
Wordpress makes it fairly easy to export your blog posts, pages, comments and some other meta-information, packaging everything up into a single XML file, that depending on the number of blog post and other content you have, can be fairly large.
When you click export, you'll be able to download the XML file containing your content. Now we just have to pull out what we want.
I looked around for something that would do the conversion of my wordpress content into markdown, but I couldn't find one that I liked, or that worked exactly the way that I wanted it to. So I wrote my own.
The export file format isn't documented anywhere that I could find online, there were a few bits and pieces here and there on blogs and on some forums, but, honestly, it's just an xml file, it's not all that difficult. The only thing that may trip you up is the number of xml namespaces it uses, although if like me you've had a job maintaining software which manages complex xml, then it's no big deal.
I found it has a root
<rss> element, followed by
<channel> and then
<item> where an item is a post, comment or even a page. An item is then broken down into further child elements which include things like the title of the post (or page, or comment), the url, publication date, actual content of the post, and various other pieces of meta data about the post. For example:
<title>Definitely given up on my github-csharp-api project</title>
<pubDate>Thu, 07 Nov 2013 21:08:19 +0000</pubDate>
<content:encoded><![CDATA[Not that I'd spent much time working on it lately. The fine folks at github have released Ocktokit.net, a C# library for accessing the github api. It's an official api - it renders my crappy project useless, so I'm putting it down completely.
I will not work on it anymore.]]></content:encoded>
So I defined a POCO
Item.cs model class to hold everything interesting about a post, and then parsed the document to get all of the items.
Items = (from item in _document.Root.Element("channel").Elements("item")
select new Item
Title = item.Element("title").Value,
PublicationDate = ParseDateTime(item.Element("pubDate").Value),
Author = item.Element(dc + "creator").Value,
Fairly standard Linq-to-Object parsing of the XML document. You can see the XML Namespace
dc being used, that is just a static namespace member defined as
private static XNamespace dc = "http://purl.org/dc/elements/1.1/"; at the top of the class.
Now that we have a whole bunch of
Items, we can move on to generating the markdown.
Markdown is really fairly simple. Before I embarked on this process, I'd never realised how powerfully simple it is. Our
Item now contains the (mostly) encoded content of our post, so we don't have any worry about doing any escaped html removal. To my eyes, and someone correct me if I'm wrong, but it seems to me that Wordpress virtually converts our content into markdown when it generates the export. I could be wrong, but it's what it looks like to me.
We can then use the Visitor pattern to control how we want our
Items to be processed.
I did not have very many pages on my wordpress blog, so I was not concerned with converting them. Similarly, I'd already converted my wordpress blog to use disqus comments, so I did not need to write a Visitor to handle converting the comments.
As this post is already getting fairly long, I will leave a discussion of the Visitor pattern to another time, but you can see the
PostVisitor implementation in detail in the repo on Github.com.
After switching my blog over to use Sandra.Snow, I noticed that in at least one feed aggregator that my blog shows up in, it wasn't displaying correct. The escaped html in the feed generator from the markdown by Snow wasn't getting rendered in the aggregator correctly. After a little digging it was apparant to me that the
RssResponse in Snow was not correctly setting it's content type.
I could have left it there, or submitted a small patch to fix the issue (I still will), but I noticed that the feed it generates isn't a pure atom feed, so I basically copied the relevant classes (changing 'rss' to 'atom') in the class names, and did a little configuration, and swapped over the feed to use atom.
Even though I know that the atom feed validates, this post is in part a test to see what happens...
I'm writing this up mostly for my own benefit so that I don't have to go searching for it again in future.
When you have a git repository which has a few submodules (.e.g. a vim dotfiles repo), you may find that you'll notice one day that they all point to ancient commits in their parent repositories. Consequently, you want to update them, to get the new shiny things.
To do so is fairly straightforward (from your parent repository):
git submodule update --recursive --remote
This tells git that you want to update the submodules to the latest commit on the submodules remote tracking branch (
--remote) and to do it recursively (
--recursive) on all of the submodules (and their submodules if any).
Then if you check the
git status you should see something like this:
M:\vimfiles [master +0 ~9 -0]> git status
# On branch master
# Changes not staged for commit:
# (use "git add ..." to update what will be committed)
# (use "git checkout -- ..." to discard changes in working directory)
# modified: bundle/ctrlp (new commits)
# modified: bundle/delimitmate (new commits)
# modified: bundle/nerdtree (new commits)
# modified: bundle/tagbar (new commits)
# modified: bundle/vim-jade (new commits)
# modified: bundle/vim-pathogen (new commits)
# modified: bundle/vim-powerline (new commits)
# modified: bundle/vim-ps1 (new commits)
no changes added to commit (use "git add" and/or "git commit -a")
You may find this confusing, as you have just updated all the submodules to the latest commit. Why are are there new commits? If you do a
diff on one of them, you'll see something like this:
M:\vimfiles [master +0 ~9 -0]> git diff bundle/ctrlp
diff --git a/bundle/ctrlp b/bundle/ctrlp
index be5842a..b5d3fe6 160000
@@ -1 +1 @@
-Subproject commit be5842a376f16c16c5dc4cc1879d7168a074f7de
+Subproject commit b5d3fe66a58a13d2ff8b6391f4387608496a030f
Which makes sense, because you have asked git to update the submodule(s) to the latest commit, so it is therefore unsuprising that your repo now knows that its submodules have changed. You need to tell your repository to actually use the latest commit of the submodules, and then commit everything:
git submodule update
git commit -am "Updated submodules to latest"
Hope that helps someone.
No longed bound to wordpress
For most of the time I've been blogging, I've used Wordpress. It's very good software, but kind of requires
somewhere to host it. Either on your own custom hosting, or wordpress.com. For a long time, I paid for my own
hosting provider. But the times they are a changing, and I'm no longer prepared to pay for my own hosting.
Github provide a way of hosting a website, for free, it's called Github Pages. Using a tool called Jekyll, it is
possible to take a series of Markdown files and generate a static html website from them. The only drawback to Jekyll
is that that it's written in Ruby, it can be a pain to configure on Windows, and I'm primarily a windows kind of guy.
It's also true that the vast majority of guides/tutorials out there for running a blog with Jekyll assume that you'll
be doing it on either a Mac or a Linux machine. I work entirely on Windows, and there is no way I'm going to try to
configure Ruby on all the machines I use (or might use).
Sandra.Snow is written in C#, and uses Nancyfx to process the markdown into static html, exactly like Jekyll. I'm
not sure about the name myself, but there you go.
Over the next few posts I'll go over how I switched my blog from a hosted Wordpress to a staticly generated site using Snow.