Howto write a blog CMS with Sinatra (and Contentful)

Posted by Andreas Tiefenthaleron 7. April 2014

This is a guest post by Andreas Tiefenthaler, Software Developer at Contentful. During a hack day at Contentful two weeks ago, he wrote a simple Sinatra blog app, backed by Contentful’s Content Delivery API, and deployed it on anynines (where else?). We asked him to share his experience.

My plan was to create a dead-simple blog application, to demonstrate how to use the contentful.com Ruby Gem. I decided I wanted to deploy the app from the very first commit on to avoid a hassle at the end of the hackathon, as we were supposed to showcase running applications.

Getting started with Contentful

Contentful is a CMS as a Service and allows you to create your own platforms without building the same backend over and over again. Contentful’s Content Delivery API works with JSON data; images, videos and other media is delivered as files. The API is a globally distributed CDN for content: All content, both JSON and binary, is served from the server closest to where a user is requesting content from, minimizing latency.

I created the BlogPost and BlogCategory Content-Types within Contentful as my data model.

These two types are linked to each other, to make sure we actually get to show a post for a certain category. And perform search operations.

To mockup a basic blog layout, I recommend using PureCSS, which is a set of small, responsive CSS modules. To use it to your blog page, simply add the following to your markup:<link rel="stylesheet" href="http://yui.yahooapis.com/pure/0.4.2/pure-min.css">
Copy-wise, I used hipsum.co, to give my blog that bit of hipster ipsum. Later on I added a markdown parser to be able to use the rich text feature.

Next, I started setting up a data model that represents a post within the application. The fetcher itself pulls the content from the delivery api and parses it into these models. The first draft of my simple blog was done and got deployed to the anynines infrastructure following their Getting Started guide.

I then decided to have a separate page per blog post with a perma-link. I added Redis to my project to store the slug and I created a method that creates a slug out of the title:

title.downcase.gsub(/[^a-z1-9]+/, '-').chomp('-')

And in my app.rb:get '/post/:perma_link' do
perma_link = params[:perma_link]
id = $redis.get(perma_link)
if $redis.exists(id)
post = redis_fetch_post(id)
else
post = BlogFetcher.fetch_post(id)
end
end
While I was already at it I wanted to speed things a bit up and used Redis as a cache to temporarily store the data fetched from our API. I added Redis to my manifest.yml to be able to use it with anynines.

Deploying with anynines

One of the advantages of using anynines is definitely that its support team. After some minor adjustments to use my setup in production I was able to push my app and see the results live and working. Due the limitations of a one-day hackathon I was not able to implement all my ideas. One of the key features I’d still like to implement is the ability to invalidate existing content through the Contentful webhooks.

To use my example app, clone the repository and run bundle install. After successfully installing the dependencies execute rackup. You will need to create a space and a content model to be able to use it. You can find my blog online, here: blog.de.a9sapp.eu.