The term category and tag are used interchangeably throughout this posting; they are assumed to be the same thing.

Having recently adopted Jekyll to power this website, I have been doing a bit of hacking/extending to get some added features in. A few days ago it was integrating Twitter with Jekyll, and now it's generating a tag cloud.

Back in July, Alex Young blogged about his Jekyll migration, and thoughtfully included a link to some code he wrote to list all posts broken out by category/tag.

I wanted to take this a bit further, and generate a per-category page which listed all the postings for that category, but also to generate a tag cloud.

Generating tag pages

After making a few changes to Alex's code, I ended up with a tag stub in a Rakefile which loops through all the categories used on the site and generates a static HTML page with a list of all the postings in that category.

Remember that this code snippet requires you to define your per-post categories in the YAML header of each post, e.g.

categories:
  - jekyll
  - blog
  - ruby

(You need to mkdir tags in your Jekyll directory before executing the code below)

Now, the Rakefile segment:

desc 'Generate tags page'
task :tags do
  puts "Generating tags..."
  require 'rubygems'
  require 'jekyll'
  include Jekyll::Filters
  
  options = Jekyll.configuration({})
  site = Jekyll::Site.new(options)
  site.read_posts('')
  site.categories.sort.each do |category, posts|
    html = ''
    html << <<-HTML
---
layout: default
title: Postings tagged "#{category}"
---
    <h1 id="#{category}">Postings tagged "#{category}"</h1>

    html << '<ul class="posts">'
    posts.each do |post|
      post_data = post.to_liquid
      html << <<-HTML
        <li>#{post_data['title']}</li>
      HTML
    end
    html << '</ul>'
    
    File.open("tags/#{category}.html", 'w+') do |file|
      file.puts html
    end
  end
  puts 'Done.'
end

There is also a gist here

Now you can run rake tags and it will generate a number of HTML files in the tags/ subdirectory; regenerating through Jekyll will then copy these files over to your site. Navigating to /tags/jekyll.html should list all your Jekyll related posts.

Generating your tag cloud

The below snippet does something similar, but just loops through each category and counts the number of tagged postings. It then does some very rudimentary font-size scaling to make the more popular tags bigger.

puts 'Generating tag cloud...'
require 'rubygems'
require 'jekyll'
include Jekyll::Filters

options = Jekyll.configuration({})
site = Jekyll::Site.new(options)
site.read_posts('')

html =<<-HTML
---
layout: default
title: Tag cloud
---

<h1>Tag cloud</h1>

    HTML

    site.categories.sort.each do |category, posts|
      html << <<-HTML
      HTML
      
      s = posts.count
      font_size = 12 + (s*1.5);
      html << "twitter?) with any queries or improvements, or post a comment below.