Adding Authors to Middleman Blog

Michael on Mar 9

Building this blog was our first time working with Middleman, and so far, the experience has been pretty great. There are lots of great benefits to using a static-site generator, and middleman has allowed us to do this without compromising on ease of development or flexibility.
However, there was one feature that did not seem to be part of the middleman-blog functionality, so I will briefly outline below how we solved this.

While you can add your own data to the front-matter section of an article, there didn't seem any way to refer to an Author as an object. This would be particularly useful if wanting to associate more than just a name with an Author (such as profile picture, twitter handle etc), and to be able to show a profile page for that author, that includes all of their articles.

Setting up the Author model

Because of Middleman's flexible approach to organizing pages and data, this is actually very easy. First, create a new authors.yml file in \data, and populate with data in the following structure:

1
2
3
- author_slug:
  name: Author Name
  photo: path_to_image

Where author_slug is the key to reference this author by, and then list any other useful properties - these are up to you, and will be determined by what you are looking to output onto the page. e.g.

1
2
3
4
5
6
7
- michael:
  name: Michael
  photo: /images/authors/michael.png
  twitter: michaelrshannon
- gregor:
  name: Gregor
  photo: /images/authors/gregor.png

Now that you have your authors data, add the key/value author: author_slug to the frontmatter of each article, where the value maps to the primary key in your authors.yml file.

Ok, we now have the author data saved in a format that middleman can understand, and a foreign_key reference at the top of each article - next, we need to update the layout being used to render an article to retrieve the relevant author data. At the top of the article layout, add the following:

1
<% author = find_author(current_article.data.author) %>

At this stage, we're going to get an error, as the find_author method doesn't yet exist. Open up config.rb, and within the helpers section, add the following:

1
2
3
4
5
6
def find_author(author_slug)
  author_slug = author_slug.downcase
  result = data.authors.select {|author| author.keys.first == author_slug }
  raise ArgumentError unless result.any?
  result.first
end

Most of the heaving lifting is now done - if we want to access any of the properties defined in authors.yml, we can do so off the newly assigned author object (e.g. <img src="<%= author.photo %>" />)


Listing an author's articles

We can however expand on this starting point. Let's say we want to get the collection of articles by a given author. In config.rb add the following:

1
2
3
4
5
def articles_by_author(author)
  sitemap.resources.select do |resource|
  resource.data.author == author.name
  end.sort_by { |resource| resource.data.date }
end

This will return all articles by the provided author, sorted by date.

Author Profile Pages

Another feature this now opens up is the ability to have author profile pages. First, we need to add the path mapping to these pages:

1
2
3
4
5
6
data.authors.collect {|author| author.keys.first }.each do |author_slug|
  proxy "/authors/#{author_slug}.html",
        '/authors/template.html',
        locals: { author_slug: author_slug },
        ignore: true
end

This is the first bit of Ruby that has any real Middleman specific syntax, but the basic purpose of this is to set up a collection of proxies (driven by the contents of data.authors), that maps authors/author_slug to /authors/template.html.erb, passing in the value of author_slug to the template.

Now, create a new folder source/authors, and within that a new file template.html.erb, and set up like any other middleman page. Then, after the frontmatter, add <% author = find_author(author_slug) %>. You can now put together your author profile page, using the author object in the same way as on the article template.

There is one final step, which will aid with working with author pages - add the following to the helpers section of your config.rb:

1
2
3
def author_path(author)
  "/authors/#{author.keys.first}"
end

This is a pretty simple helper, but it is a bit more robust and DRYer than hard-coding the path whenever wanting to link to the author profile page.


This has been my first time working with Middleman, so if you've spotted something that could be improved, let me know in the comments below, or on Twitter at @michaelrshannon!


Edits

Edits

https://blog.pixelcab.in/2015/03/23/blogging-on-heroku-with-middleman#create-an-article-layout