Getting Started With Toto, a Tiny WordPress Killer

A couple of months ago I migrated UsabilityPost from WordPress to Toto and am really enjoying the switch. Toto is a tiny blogging engine by Alexis Sellier (creator of LESS) that on the face of it appears so simple, and yet is able to do so much.

Toto stores all your posts as text files. The engine is written in the Ruby programming language and so you can use Ruby throughout your template files to add extra functionality. Additionally, Toto works extremely well with Heroku, a Ruby cloud host, which makes deployment especially easy–you can actually get a new blog up and running in about 10 seconds.

I’m really excited about this because Toto isn’t just very easy to style, customize and deploy, it’s also secure and can handle huge traffic loads. Before Toto, WordPress would be my first choice if I wanted to start a new blog. Now, Toto has completely replaced WordPress for me. Need to start up a new blog for a project? Grab Toto, style a couple of template files, deploy on Heroku and it’s live, ready to handle everything you throw at it. No messing around with databases, config files and admin panels. Read my introduction to Toto to find out more about why I think Toto is so great.

Now, let’s get to the main subject of this post. I’d like to walk you through how to get started with Toto and share with you the little modifications and updates I’ve implemented on my template files to make the most of this little blogging engine.

Contents

  1. Installation
  2. Writing posts
  3. Running Toto locally
  4. Modifying the template
    • SEO-friendly description
    • SEO-friendly page titles
    • Navigation
    • Feedburner
    • Scheduled posts
    • Custom categories
    • Disqus comments
    • Blog configuration
    • www redirect

1. Installation

Edit 2012/09/06: If you’re on a Mac, I’ve written up new installation instructions for the latest version of OS X at this time, which is OS X Mountain Lion. If you’re on Mountain Lion, read the new guide instead and then skip to Section 2 below.

And here comes a little “catch”. While Toto is incredibly easy to use and customize, it does need a couple of things to get it running. You need Ruby and RubyGems to install and run Toto, and you’ll need Git to deploy it to Heroku. Ruby is the programming language of Toto, and Git is a distributed version control system used to record code changes and deploy the latest version to Heroku.

If you’re on a Mac (OS X 10.5 and higher), you should already have Ruby installed. To install Git you can use this installer. Linux people probably already know the drill, but if you don’t there’s more info on Ruby’s official site and the Git site.

Unfortunately, Windows is trickier. There is however a really good screencast that goes through all the steps involved with installing Git, Ruby and Ruby gems on Windows. It also shows you how to use Heroku on Windows.

(NOTE: You may also need to also install the Ruby development kit on Windows to get Toto working – get it before you install the Toto gem)

To use Heroku to host your blog, go there and get a new account for free if you haven’t already got one. Additionally, you’ll need to install the Heroku Ruby gem (gems are little Ruby tools). On OS X or Linux, open up a Terminal window (search for Terminal if you’ve never used it before) and type the following to get it installed:

sudo gem install heroku

It may ask you for your password, so be sure to type that in when required. Once it’s installed you can go ahead and get the Toto gem (the actual engine), together with a Ruby server to run it, if you don’t already have one. I recommend the Thin server.

NOTE: If you’re on Mac OS X, you’ll need to also install XCode before you try and install both, the Thin server and Toto. XCode is free and is available on any OS X installation disk, in the extras folder. Once you’ve got it installed you can install both gems with this command:

sudo gem install toto thin

After this, we’re ready to get stared. The first thing we need to do is grab a copy of Dorothy. Dorothy is the generic template for Toto–it basically has the set of folders and layouts you need together with a configuration file. Clone a copy of Dorothy using the following command, changing “myblog” to whatever folder name you want to put your new blog into:

git clone git://github.com/cloudhead/dorothy.git myblog

Note: this creates your blog folder in the directory you’re currently in (i.e. by default it will be the “Home” location on OS X). Now we need to set up Heroku for this newly created blog. We’ll navigate to our new folder and do this using the following commands (again substitute “myblog” to your blog’s name):

cd myblog
heroku create myblog --stack bamboo

The --stack bamboo bit specifies a Heroku stack which supports Varnish, the caching engine Toto uses (newer stacks on Heroku no longer have it). And that’s it. To deploy and view the new blog just type:

git push heroku master
heroku open

You should now see a newly deployed Toto blog running on Heroku. If you have a custom domain, there is a free module in Heroku that will let you use it (more info over at Heroku docs) I also recommend using their section on deployment with Git to learn more about it if you’re not familiar with Git–it’s very simple once you learn the basics.

Now…it may seem like it’s a lot of work just to get one blog running, but actually, once you do this first set up once, the next time you want to launch a blog you can do it with about 3 commands (clone Dorothy, initialize Heroku, deploy), which really does take about 10 seconds. This combination of a cloud hosting platform, Heroku, and a version control system, Git, really makes things incredibly simple and fast once you get the hang of it.

Migrating from WordPress?

Scott Stout has a Ruby script over at Github which will convert a WordPress XML export to slugified toto articles. I’ve used a similar, though a much simpler, script to migrate UsabilityPost over to toto. You can even migrate existing comments over to Disqus–the comments engine I recommend for toto–by first installing Disqus on your WordPress blog and then using their import service to get the old comments into Disqus.

2. Writing posts

Posts are all stored in the /articles/ folder. To create a new post just save a text file in that folder with its name in the following format:

yyyy-mm-dd-post-permalink.txt

So if you’re publishing a post on 7th May 2010 called “Blog Updates”, you’ll name the file like: 2010-05-07-blog-updates.txt

Right at the top of each post text file you can add additional post information. The one bit of info that is absolutely required is the title. You can use a different title to the permalink, as long as you specify it in the post as a custom “slug”. So for the above example I’d write the following at the very start of the post:

title: "Blog Updates And News"
slug: blog-updates

Then right below this, leave an empty line and start writing the post. Toto uses Markdown for formatting. If you’ve never used it before, check out the site, it’s a very easy way to format your content without writing any HTML. If you do want to use HTML, no problem, you can do that too.

That’s basically it, just write new posts and put them in the articles folder. I keep draft posts in a /articles/drafts/ folder. These posts don’t show up on the blog until I move them to the the articles folder.

If you’re using Heroku and are ready to publish, you’ll need to add these files to Git and push them to Heroku. You’ll use the following commands:

git add .
git commit -a -m "written some new articles"
git push heroku master

3. Running Toto locally

Ok, you’ve written some posts but what do they look like in your template–indeed, what does the site look like? How do we test it locally? Remember, we grabbed the Thin server when getting Toto installed. This will come handy here. Just open the Terminal, navigate to your blog folder, and type:

thin start

This will launch the Thin Ruby server. To see the site running on your machine, open a browser and navigate to: “http://localhost:3000”

4. Modifying the template

The HTML template is located in the /templates/ folder, with CSS, JavaScript and other assets located in /public/. “layout.rhtml” is the core template, with everything else being rendered inside it. If you edit this file, you’ll see a bit of code in the middle that reads:

<%= yield %>

This is where all the posts or the page content goes–i.e. it will replace “yield” when you load the page. All the other code around “yield” will show up on every page, so this is where you’ll add your navigation, header, footer and so on.

Let’s go ahead and make some updates to make this template more robust.

SEO-friendly description

A good practice is to have a different page description (this is the meta description bit between the head tags) for each page, especially article pages. This description will show up on search results pages and so is useful for making the most of that traffic source. To get custom description to show up for each post, use the following code:

<meta name="description"
content="<%= @context[:description] || 'Default description' %>" />

“Default description” will be used unless a bit of meta info called ‘description’ is provided in the post text file. When you want to use a custom description just add this to the top of the post file:

title: "Some Interesting Post"
date: 2010/05/07
description: "Custom description goes here..."

SEO-friendly page titles

Page titles (the bit between the <title> tags) are very important for a search friendly site, so we need to update that code a little bit to make the most of it. I use the following code:

<title>
<% if @path == 'index' %>
  Your Blog Name
<% elsif @path.split('/').compact.length == 4 %>
  <%= title %> - Your Blog Name
<% else %>
  <%= @path.capitalize.gsub(/[-]/, ' ') %> - Your Blog Name
<% end %>
</title>

Basically, “Your Blog Name” on the 3rd line will show up as the title if you’re on the home page. The 5th line will render the title of the blog post before the blog name when you’re on a blog post page. Finally, the 7th line will will show the title as: “About - Your Blog Name” when you’re on the About page–the @path... bit will be replaced with the title of the page you’re on. So edit the three instances of “Your Blog Name” to whatever you wish. The code here isn’t particularly clean, but it works well enough.

Dorothy comes with a few pages by default. You’ve got the index, the about page, the article page and a custom archive page. These templates are all located in the “/templates/pages” folder. If you want to add a page, just create a new template in this folder and call it whatever you like. So if you want a books page, create a “books.rhtml” file in the pages folder. You’ll then be able to access this new page by going to “yourwebsite.com/books”

If you’d like to highlight the current location on the navigation bar you can use a simple conditional statement using the @path variable. So for example, our navigation code may look something like this:

<ul>
  <li><a href="/">Home</a></li>
  <li><a href="/archive">Archive</a></li>
  <li><a href="/books">Books</a></li>
</ul>

The @path variable gives us the current location we’re at. So if we’re at the books page, @path will be “books”. The home path is called “index”. We can use this to set up some simple conditional statements to add an “active” class to the list items, which we can then target with CSS to add custom highlighting. The code will look as follows:

<ul>
  <li <%= ' class="active"' if @path == 'index' %>>
    <a href="/">Home</a>
  </li>
  <li <%= ' class="active"' if @path == 'archive' %>>
    <a href="/archive">Archive</a>
  </li>
  <li <%= ' class="active"' if @path == 'books' %>>
    <a href="/books">Books</a>
  </li>
</ul>

Feedburner

If you want to use Feedburner to serve RSS you’ll want to make a couple of quick changes. First of all, Feedburner has a limit on how much information it can store in its cache, so we’ll want to trim our RSS output a little so that it only shows a few posts at a time, and not all of your blog’s articles. Edit the “/templates/index.builder” file (it may be called “feed.builder”, in which case you should rename it to “index.builder” as the name should match your index page) and look at the articles loop. The first line should read something like:

articles.reverse.each do |article|

We want to limit the output to only a few items…say 10. This way we won’t fill up Feedburner’s cache. I changed this line to read:

articles.reverse[0..10].each do |article|

Now, to use Feedburner you’ll obviously want to place a subscribe link on your “layout.rhtml” file to point to your Feedburner subscribe URL. What you’ll also want to do though is add a bit of meta at the top of the layout file to say that the RSS for this page is located at Feedburner. Edit “layout.rhtml” and add this line between the <head> tags:

<link rel="alternate" type="application/rss+xml"
title="myblog" href="http://feeds.feedburner.com/myblog" />

Make sure to change the two instances of “myblog” above to whatever it is your blog is called and your Feedburner URL is. This will make sure that if someone uses a browser-based RSS reader, they’ll be redirected to Feedburner for the feed.

Scheduled posts

Want to write a bunch of posts in one go and then schedule the days on which they’ll be posted? This is possible by modifying just a couple of lines of code. First of all, to schedule a post, just set the posts’s date to whatever date you want the post to go out at (remember to set it both in the file name and in the “date:” meta inside the actual post). Then, we’ll want to edit the template files so it only shows posts that have their dates set to today or older. We’ll need to edit the “index.rhtml” file and the “index.builder” file (which generates the RSS).

In the “index.rhtml” template, edit the opening line of the posts loop (the default one will start something like “for article in articles…”) to read as:

<% articles.select {|a| a[:date] <= Date.today}[0...10].each do |article| %>

This will show the latest 10 articles on the index page, published today or earlier, but will not show any articles with a date set in the future. When that date arrives, they’ll automatically show up.

We’ll also want to edit the RSS builder to ensure the same thing happens with our RSS feed. Edit the “index.builder” file (it may be called “feed.builder”, in which case you should change it to “index.builder” as it needs to match the name of your index). If you’ve read the Feedburner section above, you saw me limit the number of posts to 10. Here I’ve got the same change incorporated, and I’m adding the date selection as well:

articles.select {|a| a[:date] <= Date.today}.reverse[0...10].each do |article| %>

Custom categories

Want to add custom categories to your posts? No problem, you can do this with the meta tags you add at the top of each post. The default tags are of course the title, date and the optional slug (permalink), but you can really add anything you like here. These tags are then accessible from your template files, allowing you to do some interesting things.

For example, over at UsabilityPost I’ve written a few book reviews. I don’t want my book reviews to show up together with normal blog posts, so I’ve given them a special category. The top of my book reviews’ text files looks like this:

title: "Rocket Surgery Made Easy"
date: 2010/01/18
category: book
thumbnail: http://img.usabilitypost.com/books/rocketsurgery.png
book_author: Steve Krug

I’ve got a couple more tags in there, but you get the idea. I’m adding all the extra stuff I need about this type of post here, and I’m using the “category: book” as the key to sorting these types of posts on the index pages.

So for example, I’ve create a separate page to display the book reviews at. I’ve called it “books.rhtml” and put the new template in the “/templates/pages” folder. To show only the books posts I use the following loop:

<% @articles.select {|a| a[:category] == 'book' }[0...10].each do |article| %>
  <a href="<%= article.path %>"><%= article.title %></a>
  <img src="<%= article.thumbnail %>" />
  by <%= article.book_author %>
  etc ...
<% end %>

Basically, you open the loop by selecting just the book posts. You can then access their special tags by simply calling them out, like “article.thumbnail” or “article.book_author”. This gives you a lot of flexibility for setting up custom categories and types of posts on your blog.

Disqus comments

Because Toto doesn’t use a database, the commenting engine has to be outsourced. Disqus is a popular choice for this right now. By default Toto comes with Disqus support. Disqus integration itself is no hassle at all, it’s only a few lines of code pasted into your template files, so you may want to update the default code in Dorothy to the most recent code Disqus give you.

To get started with Disqus you’ll need an account, so head over to their site to get a free one. Once you set up an account, you’ll be provided with some code to paste into the templates (ignore the WordPress plugins and so on, and choose custom website integration in their information section). One bit of code goes in the bottom of “article.rhtml” template file (where you want the comments to be shown), and the other bit on the bottom of “layout.rhtml”, which will get you the comment counters.

I have a comment counter shown next to my post headline on the index page and on the article page. To do this simply append “#disqus_thread” to the end of the link. So the code for the comment counter/link would look like this:

<a href="<%= article.path %>#disqus_thread">0 Comments</a>

When you load the page, for a moment you’ll see everything as “0 Comments”. Once Disqus loads though, it will change all the counters to their proper values, and the link will point to the comments section of that particular post.

Blog configuration

All the settings for your blog are located in the “config.ru” file. There are some helpful comments there to tell you how to go about modifying the settings. The main configuration takes place in the format of:

set [:setting], [value]

So if you want to set the default blog author, you’d add the following line:

set :author, "Dmitry Fadeyev"

Now, if you don’t specify a blog author in the post meta, the default one will be used. The settings I’ve got for this blog look like this:

set :author, "Dmitry Fadeyev"   set :date, lambda {|now| now.strftime("%d %b %Y") }
set :summary, :max => 1000, :delim => /~\n/
set :disqus, 'fadeyev'
set :title, 'Dmitry Fadeyev'
set :url, 'http://fadeyev.net'

Note the “:delim” setting. This sets a delimiter for the post summary. To use this, I just type “~” at the end of a paragraph in a post, and add an extra line break afterwards. Everything before the delimiter becomes part of the post summary shown on the index page (called with “article.summary”). I’ve also customized the date to look how I want it. Here’s a list of the Ruby date symbols you can use to format the date.

www redirect

Want to redirect the “www” address of your blog to a non-www version? For example, for this blog, “www.fadeyev.net” redirects to “fadeyev.net”. To do this I use the rack-rewrite gem. First of all, you need to install the gem:

sudo gem install rack-rewrite

If you use Heroku, you’ll need to add the new gem to the “.gems” file in your blog’s directory. The .gems file will then look something like:

builder
rdiscount
toto
rack-rewrite

Finally, add the following code to your “config.ru” file, above the “run toto” line:

# Redirect www to non-www
gem 'rack-rewrite', '~> 0.2.1'
require 'rack-rewrite'
if ENV['RACK_ENV'] == 'production'
  use Rack::Rewrite do
    r301 %r{.*}, 'http://yoursite.com$&', :if => Proc.new {|rack_env|
    rack_env['SERVER_NAME'] != 'yoursite.com'
  }
  end
end

Change the two instances of “yoursite.com” above to your blog’s domain. You can also do it the other way around, i.e. redirect non-www requests to www. To do this just add www to the two instances of “yoursite.com”, making it “www.yoursite.com”.

Parting words

So if you’re not scared of the command line, I really urge you to give Toto a try. It has really simplified blog deployment and management for me. My posts are no longer tucked away in a database somewhere–they’re all backed up in a folder on my drive. There’s very little, if no, security risks, because Toto doesn’t have an admin panel or a database. Everything also gets cached, which makes this little engine extremely fast and flexible. To add to all of this, it’s very easy to modify the template files and you’ve got the power of Ruby on your side.

May 2010