From 8136b14c9587273c7c8d6a2da287a3998a83ee9c Mon Sep 17 00:00:00 2001 From: Marcel Kapfer Date: Tue, 3 Jun 2025 19:33:49 +0200 Subject: [PATCH] =?UTF-8?q?=F0=9F=90=9B=20Fix=20article=20reading=20time?= =?UTF-8?q?=20calculation?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- site/models/article.php | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/site/models/article.php b/site/models/article.php index cb93c26..a56bddf 100644 --- a/site/models/article.php +++ b/site/models/article.php @@ -12,6 +12,8 @@ class ArticlePage extends Page { private const READING_TIME_FORMAT = '%d words, ~%d min reading time'; + private const WORDS_PER_MINUTE = 150; + /** * @param array|string|null $options */ @@ -21,13 +23,28 @@ class ArticlePage extends Page return '/' . $date .'/' . $this->slug(); } + /** + * Simple function for estimating the reading time of the article. + * + * The algorithm counts all words in p-Elements and divides them by + * words-per-minute amount defined in WORDS_PER_MINUTES. It outputs the + * text defined in READING_TIME_FORMAT containing the estimated word count + * and estimated reading time. + * + * @return string Text with estimated reading time. + */ public function readingTime(): string { + // After requiring PHP 8.4 or higher, replace DOMDocument with + // DOM/HTMLDocument and remove the LIBXML_NOERROR option. This option + // is only needed because DOMDocument only supports HTML4 and + // therefore throws warnings for HTML5 tags. $doc = new DOMDocument(); $doc->loadHTML( '' - . $this->text()->kirbytext() - . '' + . $this->text()->kirbytext() + . '', + LIBXML_NOERROR ); $pElems = $doc->getElementsByTagName('p'); @@ -37,7 +54,7 @@ class ArticlePage extends Page } $wordCount = count(explode(' ', $text)); - $readingTime = (int)ceil($wordCount / 150); + $readingTime = (int)ceil($wordCount / self::WORDS_PER_MINUTE); return sprintf(self::READING_TIME_FORMAT, $wordCount, $readingTime); }