Custom Dropbox-Driven Blog Engine

22 September 2012 - Blog

Update (21 Dec 2012)

Since writing this post, I've discovered a new blogging platform called Ghost. This is Markdown driven, and perfect for what I need. So I've decided to switch and use this instead. More details can be found in my more recent post about the Ghost platform.

Up until recently, this blog has used Wordpress as its platform. I disliked using the web-based WYSIWYG editor to edit posts, and much prefer writing posts locally in a native text-editor. I'm a big fan of the Markdown format, so a Markdown editor like MarkdownPad is an ideal solution. All of my markdown files are kept in a Dropbox folder so that I can edit them from multiple machines. To accommodate this in Wordpress, I initially found a markdown plugin which replaced the WYSIWYG editor with an embedded markdown editor. I would then copy and paste the contents of my dropbox markdown files into this Wordpress plugin's editor when I was ready to publish.

There were a few problems with this workflow:

  • Duplicate data: The files were kept in two places - dropbox and Wordpress. I was manually keeping them in sync via copy and paste. Certainly not in keeping with the DRY principle!
  • If I wanted to preview the post, I had to load up the Wordpress admin system, find the post, copy and paste the markdown into it, click preview, then wait for the page to load. This was quite time consuming.

I decided that it would be an interesting hobby project to write my own blog platform. This would mean that I could integrate it with Dropbox and completely manage it by editing markdown files rather than having to log into a web administration system.

At my workplace we develop using ASP.NET webforms, but I hadn't had chance to play with ASP.NET MVC, so I decided to rewrite my blog in MVC.

Below are some of the features that I wanted implementing (ontop of general standard blog functionality):

  • Syncing with dropbox.
  • Automatic markdown to HTML conversion.
  • Draft and work-in-progress posts also get synced and are visible on the site only by myself when I'm logged in.
  • Meta data (eg. title, publish date, tags, etc) also managed via Dropbox files.

ASP.NET MVC

As I mentioned earlier, this was the first time I've used the MVC variety of ASP.NET. However at work, I develop full-time using ASP.NET Webforms, and have also briefly touched upon the MVC design pattern in the PHP Zend Framework a couple of years ago. So the transition to ASP.NET MVC was relatively painless. I really do like the idea of the MVC design pattern, as it forces separation of the various types of 'code' - eg. business logic, HTML markup, database access, etc. It also makes unit-testing much easier.

Speaking of separation of code and HTML, I was very pleasantly surprised when an option in Visual Studio's New Project Wizard asked me if I wanted to either use the standard ASP.NET view engine, or something called Razor. I've heard Razor mentioned before on Twitter, but I didn't know what it was. A quick Google search told me what I needed to know. And wow - this is really nice to work with! For those that don't know, Razor allows you to embed code and access variables from within the HTML markup. Where normally, you'd do "<%= MyVariable %>", with Razor, you can just do @MyVariable. Infact you can cleanly embed various code constructs using the @ symbol, making the combination of HTML and code look much cleaner. I'd certainly recommend reading Scott Guthrie's introductory post about Razor to get a feel about how it works.

Dropbox Syncing

In the introduction above, I said that one of my reasons for doing this was an improved Dropbox and Markdown workflow. So one of the first things I looked into was Dropbox integration. I found a really nice 3rd party library called DropNet, which made the task of accessing my dropbox folders from my blog engine much simpler. This meant that I could focus on the business logic dropbox syncing classes rather than the dropbox-api integration. Thanks to NuGet, installing the library into my project was as easy as typing "Install-Package DropNet" into the Visual Studio Package Manger Console.

In my dropbox account I have a folder called "Blog", which I keep all my markdown, config, and image files. This means that I can easily write my posts from any of my computers or devices and everything is automatically kept in sync.

Markdown

I use MarkdownSharp for the Markdown conversion. Again, this was a breeze to install thanks to NuGet. I store the converted HTML in the database (rather than the markdown) - so the markdown conversion is performed at "dropbox sync time".

The freeware Markdown editor I use is called MarkdownPad. This is only available on Windows, but I'd imagine there are similar editors available for other platforms. It's a lightweight native application which supports split-screen mode. When in splitscreen mode, the text editor part is on the left-hand side, and the rendered HTML is on the right. The rendered HTML gets updated in real-time as you type.

Blogpost Metadata

So far I haven't discussed any meta data for my blog posts. For example: tags, url, publish date, visibility, etc. Given that I want this to be very DBD (DropBox Driven!), I decided that this should be stored in a config file in Dropbox. I went with JSON format, and the config.json file look like this:

{
    "posts": [{
        "filename" : "BlogEngine.txt",
        "title" : "BlogEngine",
        "tags" : [ "Blog", "ASP.NET", "MVC", "Dropbox", "Markdown" ],
        "publishdate" : "22/09/2012 18:00",
        "visibility" : "draft",
        "url" : "/2012/blog-engine"
    },{
        "filename" : "Git.txt",
        "title" : "A love of Git",
        "tags" : [ "Git", "Git-Tfs", "Source Control", "TFS", "VCS" ],
        "publishdate" : "25/08/2012 08:10",
        "visibility" : "public",
        "url" : "/2012/git"
    },{
        "filename" : "GitTfs.txt",
        "title" : "Bridging Git and TFS - Git-Tfs",
        "tags" : [ "Git", "Git-Tfs", "Source Control", "TFS", "VCS" ],
        "publishdate" : "25/08/2012 08:15",
        "visibility" : "public",
        "url" : "/2012/git-tfs"
    },{
        ... etc ...
        ... etc ...
        ... etc ...
        ... etc ...
    }]
}

Notice especially the visibility field. Any posts that have a visibility value other than 'public' will not be displayed on the site unless I've logged into the site under my account. When I'm logged in, I can see all posts, and any non-public posts display the status in red next to the title. This makes it really easy for me to preview the posts before I make them public.

Images and Assets

Another huge advantage to managing the blog via Dropbox syncing is that I no longer need to explicitly upload images. The images live in a sub-folder in the folder that contain my blog posts, and the dropbox syncing handles the rest. As the image paths are relative, I can see the images in MarkdownPad when editing posts, and the same paths work when the dropbox folders are synced with the website. It's all completely automatic. I'm only using this for images at the moment, but in the future the same functionality will work for any other media type - eg. embedded videos.

Hosting

I had initially planned to host it using the Microsoft Windows Azure platform. The shared hosting seemed reasonably priced. It was only near the time when I was ready to make my site live that I realised that the shared Azure hosting didn't support custom domain names. So I would need to upgrade to what they call a reserved site to use my own custom domain. The reserved sites are MUCH more expensive, so I had to find alternative hosting. Since then Microsoft have now updated their shared hosting to allow custom domains. Unfortunately though, it's a bit too late, as I'm now hosting my blog with Aspnethosting.co.uk, who I'm very happy with so far, and they are VERY competitively priced. I will probably revisit the Azure option at some point though, as I really like the direction they're heading with it.

[Update: 16/12/2012]: I've actually now moved back to Azure. One feature I love is Azure now supports continuous integration with private Github and Bitbucket repositories. So now I have a Git branch called "Live", and if I push any changes to that branch, it automatically gets deployed. And wow - it's fast! Deployment literally takes seconds!

Conclusion

Now that this is all up and running and I've turned the idea into a working website, I can definitely say that I'm much happier with my new dropbox-driven workflow. I've been using Trello to manage my to-do list for this project, and have a long list of future enhancements I want to implement. So perhaps there'll be a follow up post later down the line. To preempt any questions regarding whether I'm planning to open-source this - the answer is that I don't know. I've tried to abstract out a lot of the business logic, so I could perhaps strip out all the Coderhell specific code relatively easily. This is something I'll consider if there are enough interest in it.

Any ideas or feedback on this, then feel free to comment below.


.NET Oxford Links


Recent Posts


Featured Posts


Tags