Hi followed the latest video with @DoncoMarketing showing the read time - really cool as I was using a custom php function before and putting it in via a shortcode.
I tried to evolve getting more than just the number so it would deal with min/mins and hr/hrs (not that many blogs are that long!).
But anything I’ve tried, it outputs formatted like 2,2 mins for example. It seems to be localising it were it shouldn’t?
class ReadTimeDynamicContent {
const GROUP = 'custom_dynamic_content';
public static function setup() {
add_filter('cs_dynamic_content_' . self::GROUP, [self::class, 'calculateReadTime'], 0, 4);
add_action('cs_dynamic_content_setup', [self::class, 'register']);
}
public static function register() {
cornerstone_dynamic_content_register_group([
'name' => self::GROUP,
'label' => 'Custom Dynamic Content',
]);
cornerstone_dynamic_content_register_field([
'name' => 'reading_time',
'group' => self::GROUP,
'label' => 'Reading Time',
'controls' => [
[
'key' => 'minutes',
// Use 'text' for safer output in frontend display,
// but if you want raw number for calculations elsewhere, use 'number'
'type' => 'text',
'label' => 'Minutes',
],
[
'key' => 'formatted',
'type' => 'text',
'label' => 'Formatted',
],
],
]);
}
public static function calculateReadTime($result, $field, $args = []) {
switch ($field) {
case 'reading_time':
$content = get_post_field('post_content', get_the_ID()); // Get current post content
$word_count = str_word_count(strip_tags($content));
// Calculate total minutes, always integer
$total_minutes = max(1, (int) ceil($word_count / 200));
$hours = (int) floor($total_minutes / 60);
$minutes = $total_minutes % 60;
// Pluralization logic for hrs/mins
$formatted = '';
if ($hours > 0) {
$formatted .= $hours . ' ' . ($hours === 1 ? 'hr' : 'hrs');
if ($minutes > 0) $formatted .= ' ';
}
if ($minutes > 0 || $hours === 0) {
$formatted .= $minutes . ' ' . ($minutes === 1 ? 'min' : 'mins');
}
$result = [
// Always output as string to ensure "text" field type works as expected and avoids localization
'minutes' => (string) $total_minutes,
'formatted' => $formatted,
];
break;
default:
break;
}
return $result;
}
}
add_action('init', [ReadTimeDynamicContent::class, 'setup']);