Adding per-tag Atom feeds to Middleman

Learn how to generate Atom/XML feeds based on tags by using Middleman.

Today we decided to add per-tag feeds to our blog. Middleman proved to be flexible enough to make this pretty easy.

When we set out, we had two main questions:
  1. How to access the tags in config.rb, given that new posts can just arbitrarily add new ones?
  2. How to generate the file for each category?

It took us a bit to find the answer to the first question, but it turns out that the ready callback which is run after the rest of config.rb is exactly what we needed:
ready do
  blog.tags.each do |tag, posts|
    proxy "/tags/#{tag}/feed.xml",
          locals: { tag: tag, posts: posts },
          ignore: true,
          layout: false

The second point was much easier to solve: We’re using Middleman’s dynamic_pages to proxy the request to an Atom template (tag.xml.builder), passing in each tag and its associated posts as locals. The ignore: true option makes sure that Middleman won’t try to build the template itself.

Here’s the builder in all its glory:
xml.feed "xmlns" => "" do
  site_url = ""
  xml.title "The Oozou Blog — #{tag.capitalize}"
  xml.subtitle "We handcraft beautiful Web and Mobile apps" URI.join(site_url, tag_path(tag)) "href" => URI.join(site_url, tag_path(tag)) "href" => URI.join(site_url, current_page.path), "rel" => "self"
  xml.updated( unless blog.articles.empty? { "Oozou" }

  posts.first(10).each do |article|
    xml.entry do
      xml.title article.title "rel" => "alternate", "href" => URI.join(site_url, article.url) URI.join(site_url, article.url)
      xml.updated File.mtime(article.source_file).iso8601
      xml.content article.body, "type" => "html"
Like 113 likes
Michael Kohl

Join the conversation

This will be shown public
All comments are moderated

Get our stories delivered

From us to your inbox weekly.