mirror of
https://github.com/TryGhost/Ghost.git
synced 2025-04-15 03:01:37 -05:00
🎨Improved image counting for the {{reading_time}} helper (#9366)
refs #9200 - We have not yet counted the images within your html, this commit counts images based on the this algorithm: https://blog.medium.com/read-time-and-you-bc2048ab620c - Added imageCount utility, which counts images using an img-tag regex, amended from the general tag-regex found in wordCount - Added this imageCount to the {{reading_time}} helper, adding 12 seconds to the reading time for every image - The feature image is still counted as before - The first image adds 12 seconds, the second 11, the third 10, and so on - Images from the tenth onwards add 3 seconds to the reading time
This commit is contained in:
parent
1da2eec915
commit
301e1b2419
4 changed files with 65 additions and 36 deletions
|
@ -39,11 +39,14 @@ module.exports = function reading_time(options) {// eslint-disable-line camelcas
|
|||
|
||||
html = this.html;
|
||||
imageCount = this.feature_image ? 1 : 0;
|
||||
imageCount += localUtils.imageCount(html);
|
||||
wordCount = localUtils.wordCount(html);
|
||||
readingTimeSeconds = wordCount / wordsPerSecond;
|
||||
|
||||
// add 12 seconds to reading time if feature image is present
|
||||
readingTimeSeconds = imageCount ? readingTimeSeconds + 12 : readingTimeSeconds;
|
||||
for (var i = 12; i > 12 - imageCount; i -= 1) {
|
||||
// add 12 seconds for the first image, 11 for the second, etc. limiting at 3
|
||||
readingTimeSeconds += Math.max(i, 3);
|
||||
}
|
||||
|
||||
readingTimeMinutes = Math.round(readingTimeSeconds / 60);
|
||||
|
||||
|
|
|
@ -23,6 +23,16 @@ module.exports.wordCount = function wordCount(html) {
|
|||
return html.split(' ').length;
|
||||
};
|
||||
|
||||
/**
|
||||
* Image count Utility
|
||||
* @param {string} html
|
||||
* @returns {integer} image count
|
||||
* @description Takes an HTML string and returns the number of images
|
||||
**/
|
||||
module.exports.imageCount = function wordCount(html) {
|
||||
return (html.match(/<img(.|\n)*?>/g) || []).length;
|
||||
};
|
||||
|
||||
module.exports.findKey = function findKey(key /* ...objects... */) {
|
||||
let objects = Array.prototype.slice.call(arguments, 1);
|
||||
|
||||
|
|
|
@ -3,10 +3,27 @@ var should = require('should'), // jshint ignore:line
|
|||
// Stuff we are testing
|
||||
helpers = require('../../../server/helpers');
|
||||
|
||||
var articleHtml =
|
||||
'<div class="kg-card-markdown"><p>Ghost has a number of different user roles for your team</p>' +
|
||||
'<h3 id="authors">Authors</h3><p>The base user level in Ghost is an author. Authors can write posts,' +
|
||||
' edit their own posts, and publish their own posts. Authors are <strong>trusted</strong> users. If you ' +
|
||||
'don\'t trust users to be allowed to publish their own posts, you shouldn\'t invite them to Ghost admin.</p>' +
|
||||
'<h3 id="editors">Editors</h3><p>Editors are the 2nd user level in Ghost. Editors can do everything that an' +
|
||||
' Author can do, but they can also edit and publish the posts of others - as well as their own. Editors can also invite new' +
|
||||
' authors to the site.</p><h3 id="administrators">Administrators</h3><p>The top user level in Ghost is Administrator.' +
|
||||
' Again, administrators can do everything that Authors and Editors can do, but they can also edit all site settings ' +
|
||||
'and data, not just content. Additionally, administrators have full access to invite, manage or remove any other' +
|
||||
' user of the site.</p><h3 id="theowner">The Owner</h3><p>There is only ever one owner of a Ghost site. ' +
|
||||
'The owner is a special user which has all the same permissions as an Administrator, but with two exceptions: ' +
|
||||
'The Owner can never be deleted. And in some circumstances the owner will have access to additional special settings ' +
|
||||
'if applicable — for example, billing details, if using Ghost(Pro).</p><hr><p>It\'s a good idea to ask all of your' +
|
||||
' users to fill out their user profiles, including bio and social links. These will populate rich structured data ' +
|
||||
'for posts and generally create more opportunities for themes to fully populate their design.</p></div>';
|
||||
|
||||
describe('{{reading_time}} helper', function () {
|
||||
it('[success] renders reading time for less than one minute text correctly', function () {
|
||||
var data = {
|
||||
html: '<div class="kg-card-markdown"><p>This is a text example! Count me in ;)</p></div>',
|
||||
html: articleHtml,
|
||||
title: 'Test',
|
||||
slug: 'slug'
|
||||
},
|
||||
|
@ -17,23 +34,11 @@ describe('{{reading_time}} helper', function () {
|
|||
|
||||
it('[success] renders reading time for more than one minute text correctly', function () {
|
||||
var data = {
|
||||
html: '<div class="kg-card-markdown"><p>Ghost has a number of different user roles for your team</p>' +
|
||||
'<h3 id="authors">Authors</h3><p>The base user level in Ghost is an author. Authors can write posts,' +
|
||||
' edit their own posts, and publish their own posts. Authors are <strong>trusted</strong> users. If you ' +
|
||||
'don\'t trust users to be allowed to publish their own posts, you shouldn\'t invite them to Ghost admin.</p>' +
|
||||
'<h3 id="editors">Editors</h3><p>Editors are the 2nd user level in Ghost. Editors can do everything that an' +
|
||||
' Author can do, but they can also edit and publish the posts of others - as well as their own. Editors can also invite new' + ' authors to the site.</p><h3 id="administrators">Administrators</h3><p>The top user level in Ghost is Administrator.' +
|
||||
' Again, administrators can do everything that Authors and Editors can do, but they can also edit all site settings ' +
|
||||
'and data, not just content. Additionally, administrators have full access to invite, manage or remove any other' +
|
||||
' user of the site.</p><h3 id="theowner">The Owner</h3><p>There is only ever one owner of a Ghost site. ' +
|
||||
'The owner is a special user which has all the same permissions as an Administrator, but with two exceptions: ' +
|
||||
'The Owner can never be deleted. And in some circumstances the owner will have access to additional special settings ' +
|
||||
'if applicable — for example, billing details, if using Ghost(Pro).</p><hr><p>It\'s a good idea to ask all of your' +
|
||||
' users to fill out their user profiles, including bio and social links. These will populate rich structured data ' +
|
||||
'for posts and generally create more opportunities for themes to fully populate their design.</p></div>',
|
||||
html: articleHtml +
|
||||
'This needed about twenty-five more words before passing the one minute reading time, ' +
|
||||
'since the word count was 250, and the average speed is 275.',
|
||||
title: 'Test',
|
||||
slug: 'slug',
|
||||
feature_image: '/content/images/someimage.jpg'
|
||||
slug: 'slug'
|
||||
},
|
||||
result = helpers.reading_time.call(data);
|
||||
|
||||
|
@ -42,26 +47,28 @@ describe('{{reading_time}} helper', function () {
|
|||
|
||||
it('[success] adds time for feature image', function () {
|
||||
var data = {
|
||||
html: '<div class="kg-card-markdown"><p>Ghost has a number of different user roles for your team</p>' +
|
||||
'<h3 id="authors">Authors</h3><p>The base user level in Ghost is an author. Authors can write posts,' +
|
||||
' edit their own posts, and publish their own posts. Authors are <strong>trusted</strong> users. If you ' +
|
||||
'don\'t trust users to be allowed to publish their own posts, you shouldn\'t invite them to Ghost admin.</p>' +
|
||||
'<h3 id="editors">Editors</h3><p>Editors are the 2nd user level in Ghost. Editors can do everything that an' +
|
||||
' Author can do, but they can also edit and publish the posts of others - as well as their own. Editors can also invite new' + ' authors to the site.</p><h3 id="administrators">Administrators</h3><p>The top user level in Ghost is Administrator.' +
|
||||
' Again, administrators can do everything that Authors and Editors can do, but they can also edit all site settings ' +
|
||||
'and data, not just content. Additionally, administrators have full access to invite, manage or remove any other' +
|
||||
' user of the site.</p><h3 id="theowner">The Owner</h3><p>There is only ever one owner of a Ghost site. ' +
|
||||
'The owner is a special user which has all the same permissions as an Administrator, but with two exceptions: ' +
|
||||
'The Owner can never be deleted. And in some circumstances the owner will have access to additional special settings ' +
|
||||
'if applicable — for example, billing details, if using Ghost(Pro).</p><hr><p>It\'s a good idea to ask all of your' +
|
||||
' users to fill out their user profiles, including bio and social links. These will populate rich structured data ',
|
||||
title: 'Test',
|
||||
slug: 'slug',
|
||||
feature_image: '/content/images/someimage.jpg'
|
||||
html: articleHtml,
|
||||
title: 'Test',
|
||||
slug: 'slug',
|
||||
feature_image: '/content/images/someimage.jpg'
|
||||
},
|
||||
result = helpers.reading_time.call(data);
|
||||
|
||||
// The reading time for this HTML snippet would be 63 seconds without the image
|
||||
// The reading time for this HTML snippet would be 55 seconds without the image
|
||||
// Adding the 12 additional seconds for the image results in a reading time > 1 minute
|
||||
String(result).should.equal('1 min read');
|
||||
});
|
||||
|
||||
it('[success] adds time for inline images', function () {
|
||||
var data = {
|
||||
html: articleHtml +
|
||||
'<img src="test.png">',
|
||||
title: 'Test',
|
||||
slug: 'slug'
|
||||
},
|
||||
result = helpers.reading_time.call(data);
|
||||
|
||||
// The reading time for this HTML snippet would be 55 seconds without the image
|
||||
// Adding the 12 additional seconds for the image results in a reading time > 1 minute
|
||||
String(result).should.equal('1 min read');
|
||||
});
|
||||
|
|
|
@ -31,4 +31,13 @@ describe('Helpers Utils', function () {
|
|||
result.should.equal(8);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Image Count', function () {
|
||||
it('[success] can count images', function () {
|
||||
var html = '<div class="kg-card-markdown"><p>This is a <img src="hello.png"> text example! Count me in ;)</p><img src="hello.png"></div>',
|
||||
result = helperUtils.imageCount(html);
|
||||
|
||||
result.should.equal(2);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
Loading…
Add table
Reference in a new issue