Estimating article reading times with Middleman

MIDDLEMAN

At the top of every Medium article there is an estimated reading time allowing users to decide whether to read an article now, later or not at all. How can we provide estimates for articles generated using Middleman?

Medium article showing estimated reading time

Before we get started adding estimated reading times we will assume that you have already created a Middleman site and installed the middleman-blog extension. Unfortunately, the middleman-blog extension doesn't provide any support for reading times. However, luckily there are a number of libraries that can calculate reading times such as readingtime.

The readingtime library calculates a reading time given some text and the number of words that can be read in a given amount of time.

To get started let's add the readingtime gem to our Gemfile:

  gem "readingtime"

Once this line is added we can install the dependency using bundler:

  bundle install

This will have installed the dependency for our middleman site. Before we can use the gem in our article layout we first need to make it available to our middleman site by adding require "readingtime" to our config.rb.

We are now able to calculate the reading times for each blog article. Each blog typically has an index.html.erb page where links to all of the articles appear. By default the middleman-blog extension generates one if you have run one of:

  middleman init MY_BLOG_PROJECT --template=blog
  middleman init --template=blog

In any case you should have an index.html.erb page looking something similar to this:

  <% page_articles.each_with_index do |article, i| %>
    <h2>
      <%= link_to article.title, article %>
      <span><%= article.date.strftime('%b %e') %></span>
    </h2>
    <%= article.body %>
  <% end %>

Here we are looping around each blog article and rendering a link to the article, the date the article was posted and finally the article's body content. To render reading times we can add the following inside the loop:

  <%= article.body.reading_time :format => :approx %>

Here we are calling reading_time on the article's body content and specifying how the time should be formatted. The readingtime gem supports a variety different formatting options.

You may have realised that if the article's body content contained HTML then this would be counted towards our reading time and would make our estimate less accurate. This is true, however this is unlikely to shift the reading time significantly.