Read time macro overview #
Here's a short summary on read time macro functionality:
- Read time is calculated based on the assumption that average human reads 256 words per minute.
- Time returned by the macro will be outputted in human-readable format that is adjusted to the locale of your current website. For example, for english it will be "2 minutes" and for german "2 minuten".
- Macro will round read time to minutes. If read time is less than one minute, the macro will output
less than 1 minute
. While1 minute
in this sentence is automatically adjusted to current site locale,less than
must be provided by static translations. - Text passed to macro will be stripped of HTML to avoid getting misleading results.
- Words separated by dashes instead of spaces will still be treated as two words.
Macro code #
{% macro readTime(text) %}
{% spaceless %}
{# settings #}
{% set wordsPerMinute = 265 %}
{% set showLessThanMinute = true %}
{# logic #}
{% set plaintext = text|striptags|replace({'â': ' ', 'â': ' ', '-': ' ', '\n': ' '}) %}
{% set words = plaintext|split(' ') %}
{% set minutes = ceil(words|length / wordsPerMinute) %}
{% set seconds = minutes * 60 %}
{% set formatter = create({ class: 'craft\\i18n\\Formatter' }) %}
{% if (words|length / wordsPerMinute) * 60 < 60 and showLessThanMinute %}
{{'less than'|t ~ ' ' ~ formatter.asDuration(60)}}
{% else %}
{{formatter.asDuration(seconds)}}
{% endif %}
{% endspaceless %}
{% endmacro %}
Advice: for grabbing text taken from multiple fields or sources and mixed with HTML, its good idea to use set
with opening and closing tag - like this:
{% set text %}
{{entry.someField}}
{% for block in entry.someMatrix.all() %}
{{ block.subfield}}
{% endfor %}
{{entry.someOtherfield}}
{% endset %
Thanks to that, you can just use your already existing markup and easily pass it to macro.
How does it work? #
The first part of macro is pretty self-explanatory. We split the text into an array of words, count words and calculate read time. What about create
function?
Not every internal function of Craft CMS is available in Twig templates directly. To use asDuration
function that outputs time in human readable format, we need to instantiate craft\i18n\Formatter object using create
function. You can read more about it on nystudio blog.
Read time plugin #
As an alternative to macro, you can use the Read time plugin.
It also has the ability to return read time in human readable format adjusted to your locale. Other than that, it is able to return exact time, with minutes and seconds, return time as a numeric variable or just process entry
and all its related fields automatically.
All in all, I think that for basic usage, the macro will suffice.