Implementing an Estimated "Read Time" on Articles

Bill Renk
#Drupal | Posted

Recently, a client asked that we display an “estimated reading time” (which we’re just going to call “read time” from now on) for their articles. This is a usability feature that is ideally designed to keep the user on the page longer by letting them know about how long it will take them to read the article.

For implementation in Drupal, we decided to use a custom field. The calculation for the read time itself comes from Brian Cray’s blog post on the matter, where you may also find more background information on the subject overall.

The code below shows the field, widget and formatter definitions for the custom field using their respective hooks.

 

  1. // Implements hook_field_info().
  2. function read_time_field_field_info() {
  3. return array(
  4. 'read_time_field' => array(
  5. 'label' => t('Read Time'),
  6. 'description' => t('Time it takes to read article'),
  7. 'default_widget' => 'read_time_field_widget',
  8. 'default_formatter' => 'read_time_field_formatter',
  9. ),
  10. );
  11. }
  12.  
  13. // Implements hook_field_formatter_info().
  14. function read_time_field_field_formatter_info() {
  15. return array(
  16. 'read_time_field_formatter' => array(
  17. 'label' => t('Read Time Text'),
  18. 'field types' => array('read_time_field'),
  19. 'settings' => array('read_time_fields' =>
  20. array('body' => 'body'),
  21. 'format_text' => '@m m @s sec',
  22. 'word_per_minute' => '200'
  23. ),
  24. ),
  25. );
  26. }
  27.  
  28. // Implements hook_field_widget_info().
  29. function read_time_field_field_widget_info() {
  30. return array(
  31. 'read_time_field_widget' => array(
  32. 'label' => t('Read Time'),
  33. 'field types' => array('read_time_field'),
  34. ),
  35. );
  36. }

The formatter settings provide flexibility for the field display and the read time calculation:

 

  1. /**
  2. * Implements hook_field_formatter_settings_form().
  3. *
  4. * Allows for customization of the read time calculation.
  5. */
  6. function read_time_field_field_formatter_settings_form($field, $instance, $view_mode, $form, &$form_state) {
  7. $display = $instance['display'][$view_mode];
  8. $settings = $display['settings'];
  9.  
  10. $fields = field_info_instances($instance['entity_type'], $instance['bundle']);
  11. $options = array('title' => t('title'));
  12.  
  13. foreach($fields as $key => $field) {
  14. if(in_array($field['widget']['type'], array('text_textarea_with_summary', 'text_textarea', 'text_long', 'text_with_summary'))) {
  15. $options[$key] = $field['label'];
  16. }
  17. }
  18.  
  19. $element['read_time_fields'] = array(
  20. '#type' => 'checkboxes',
  21. '#options' => $options,
  22. '#default_value' => $settings['read_time_fields'],
  23. '#title' => t('Fields used to calculate read time'),
  24. );
  25.  
  26. $element['format_text'] = array(
  27. '#title' => t('Choose how users view dates and times:'),
  28. '#type' => 'textfield',
  29. '#size' => 10,
  30. '#default_value' => $settings['format_text'],
  31. '#description' => t('Enter a string with @m and @s as replacement values. For example: @m minutes @s seconds'),
  32. '#weight' => 0,
  33. );
  34.  
  35. $element['word_per_minute'] = array(
  36. '#title' => t('Words Per Minute'),
  37. '#type' => 'textfield',
  38. '#size' => 10,
  39. '#default_value' => $settings['word_per_minute'],
  40. '#weight' => 1,
  41. );
  42.  
  43. return $element;
  44. }

 

Looking at the above code, the first setting allows for selecting which text fields are to be used in the calculation of the read time. This could be useful if your article involves more than just the body field. The ‘format_text’ setting allows for specification of the display format. For instance, enter “@m mins @s sec” and the display will be produce “11 mins 20 secs.”

The final setting allows you to tweak the words per minute reading rate. Maybe the site audience is very bright and their rate is higher.

The custom read time field is currently available as a sandbox module that can be downloaded here:http://drupal.org/sandbox/brenk28/1865774.

Bill Renk