It can be very useful for readers to know how much time they can expect to spend on an article before they engage. That's why I decided to add an estimated reading time to my blog. It will take approximately 3 minutes to read this article and find out how I implemented that.
Update: reading_time-helper in Ghost
Since Ghost 1.17.0 a {{reading_time}}
-helper was implemented (see this page). I now use this helper on my site to calculate the reading time of my articles. However, the technique I describe here is still valid when using a different platform than (or an older version of) Ghost.
How fast does the average person read?
Before going all technical and start inserting scripts in webpages, we need to find out how fast the average (adult) person reads.
Research done in 2012 measured the speed at which subjects read aloud. They also found that the average reading speed varies per language. For English, the language for this blog, the average lies around 228 (± 30) words per minute (Table 2 in the article). This is the number we will use for our calculations later on.
Adding the reading-time
In order to add the reading-time estimation to a page, we'll go through the following steps:
- Add an empty tag as placeholder where the reading-time should be displayed.
- Create or locate an HTML-tag surrounding the post's contents (i.e. the words that need to be counted).
- Calculate the reading-time and place the results inside our placeholder-tag
Note: The page you want to make your modifications to, is the page displaying the contents of your articles. In Ghost, the file you'll be looking for is called post.hbs
, which is the page I will be modifying in this example.
Step 1 Add an empty placeholder-tag
The first step for adding a reading-time estimation to a page is to find the location you want this indication to show. For my pages it is next to the publication-date right before the title.
Add an HTML-tag (div
for example) in which the reading-time should be placed. In order to find it later in our script, I gave the tag the class 'reading-time'. This makes it easy to add some additional styling as well. In my case the code looks like follows:
<article>
... snip ...
<div class="reading-time"></div>
... snip ...
</article>
Step 2 Locate the article contents
In Ghost, the contents of an article are included with the {{content}}
helper. On my page, this helper is contained within a section with the class post-full-content
:
<section class="post-full-content">
{{content}}
</section>
This means that we can use the class name post-full-content
to retrieve the contents of the text later in the calculation script.
Step 3 Calculate the reading-time
Now add the following piece of javascript to the bottom of the page (between <script></script>
tags of course):
$(function () {
var txt = $(".post-full-content")[0].textContent,
wordCount = txt.replace( /[^\w ]/g, "" ).split( /\s+/ ).length;
var readingTimeInMinutes = Math.floor(wordCount / 228) + 1;
var readingTimeAsString = readingTimeInMinutes + " min";
$('article .reading-time').html(readingTimeAsString);
});
- The jQuery-code inside the
$(function() { ... })
will only run once the DOM is ready for Javascript code to execute (see the jQuery api reference for details on the .ready() function). - Line 2 retrieves the text contained in the 'post-full-content' section of the page and stores it inside the
txt
-variable. - Word count magic happens in line 4, where the text is processed in 3 steps:
- Remove all non word-characters, (i.e. not alphanumeric or underscore).
- Split the text by the space-character (i.e. the actual words in the text). This returns an array of words.
- Count the number of entries in the array (i.e. words in the text).
- Line 6 divides the number of words by 228, as we decided 228 would be the average amount of words per minute an adult would be able to read.
- Line 7 finalizes the text to be displayed by adding the word ' min' (for 'minutes') to the reading time.
- Line 9 substitutes the html inside the
reading-time
class within thearticle
tag, with the text to be displayed.
After this is done, you might want to do some extra styling on the reading-time class in your CSS to integrate it nicely inside your website.