How to Calculate Article Reading Time with a Custom Middleman Extension

This is a quick how-to guide on implementing an estimated reading time feature for your Middleman blog with a custom Middleman extension.

Write the custom extension

You can just drop the code below into the main directory for your Middleman project. Mine is under torspark.com/reading_time.rb. Note that this is above the /source directory where most of your work will go in a Middleman project. You could also put it in a top level /extensions directory alongside the /source & /build directories if you plan to write a lot of custom extensions. I don’t have a need for this yet, so I just left it as an individual file.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# Outputs the reading time
# ex: Read this in "about 3 minutes"

class ReadingTime < Middleman::Extension
  def initialize(app, options_hash={}, &block)
    super
  end

  helpers do
    def reading_time(input)
      words_per_minute = 180

      words = input.split.size
      minutes = (words//words_per_minute).floor
      minutes_label = minutes === 1 ? ' minute' : ' minutes'
      minutes > 0 ? "about #{minutes} #{minutes_label}" : 'less than 1 minute'
    end
  end
end

::Middleman::Extensions.register(:reading_time, ReadingTime)

You can easily customize line #11 to match the average reading speed for your readers. 180 words per minute is a conservative estimate for proofreading on a monitor. The average adult can read between 250 to 300 words per minute. Most of my articles are at least a little technical, so I decided to stick with 180 wpm.

Lines #13–16 calculate the total number of words in the article, and then pluralize the label if necessary.

The last line registers the extension so you can activate it in the config.rb file, like the code below.

Activate & use your extension

1
2
require 'reading_time'
activate :reading_time

Next, we just need to use the helper in our layout. The estimated reading times you can see on Torspark’s home page and in the upper right of this page (assuming I haven’t redesigned things…) are generated with the code below.

1
2
3
4
5
6
7
# links on source/index.html.haml:
= link_to "Read this article in #{reading_time article.body}", article

# Estimated reading time in source/layouts/article.haml:
%p
  Read this article in
  = reading_time current_article.body

Alternative

For something this simple, you could just drop lines #10–17 from the first code block above into the helper section of your Middleman config.rb file. I went ahead and built out the full extension, because I’m planning to flesh it out a little more. The separate file also makes things a little cleaner to manage.

Feedback? Questions?

That’s all there is to writing and using your own custom extension for Middleman. I hope it helps you customize your site. I’d love to hear about the custom extensions you use. Drop me a line.

Should I make a gem for you?

Also, I’d consider building this out a little more and making a gem if you’re interested. Let me know.

Want to Know More?

If you have any questions or comments, feel free to contact me. I love talking about this stuff, and I make sure to answer every email.

Hey There!

Say Hi!