philippecharrat / reader-time-bundle
A tool for calculating the time required to read online content
Package info
github.com/philippeCharrat/reader-time-bundle
Type:symfony-bundle
pkg:composer/philippecharrat/reader-time-bundle
Requires
- php: >=8.1
- symfony/config: ^6.0 || ^7.0
- symfony/dependency-injection: ^6.0 || ^7.0
- symfony/framework-bundle: ^6.0 || ^7.0
- symfony/twig-bundle: ^6.0 || ^7.0
Requires (Dev)
- phpunit/phpunit: ^10.0 || ^11.0
This package is auto-updated.
Last update: 2026-05-11 21:09:31 UTC
README
A Symfony bundle that provides a Twig filter to estimate the time required to read online content (text or rich HTML).
It supports:
- word counting (unicode letters)
- optional rich-content overhead (images + tables)
- per-language reading speed presets (WPM) for several languages
Requirements
- PHP >= 8.1
- Symfony FrameworkBundle ^6.0 || ^7.0
- TwigBundle ^6.0 || ^7.0
Installation
Install with Composer:
composer require philippecharrat/reader-time-bundle
Symfony Flex should auto-enable the bundle (depending on your project setup). If not, enable it manually:
// config/bundles.php return [ // ... PhilippeCharrat\ReaderTimeBundle\ReaderTimeBundle::class => ['all' => true], ];
Configuration
Create (or edit) the following file:
# config/packages/reader_time.yaml reader_time: words_per_minute: 200 minimum_minutes: 1
Options
- words_per_minute (int, default: 200, min: 1) Base reading speed used when no langcode preset is provided (or if it is unknown).
- minimum_minutes (int, default: 1, min: 0) Minimum value returned when content is not empty (use 0 if you want to allow returning 0 for very short content).
Usage (Twig)
A Twig filter is provided:
Filter name: reader_time_minutes
Signature: reader_time_minutes(content, onlyText = false, langcode = null)
Examples
Estimate from rich HTML (text + images + tables):
{{ article.content|reader_time_minutes }}
Estimate from plain text only (ignore images/tables):
{{ article.content|reader_time_minutes(true) }}
Use a language preset (affects WPM):
{{ article.content|reader_time_minutes(false, 'fr') }}
Available language codes : ar, zh, nl, en, fi, fr, de, he, it, ko, es, sv
How it works (high-level)
Text is extracted with strip_tags() and normalized whitespace.
Words are counted using a unicode letters regex (\p{L}+).
If onlyText=false, extra time is added for:
images (<img ...>) with a reduced weight when alt=""
tables (<table ...>)
Contributing
Issues and pull requests are welcome.