From 2e28bc2a5f80291b3eaa59c21a6fefb484e79d60 Mon Sep 17 00:00:00 2001 From: Naz Gargol Date: Tue, 3 Dec 2019 11:32:46 +0700 Subject: [PATCH] Added fallback to excerpt in {{excerpt}} helper for gated content (#11430) refs https://github.com/TryGhost/Ghost/issues/10062 - When content gating is in place a lot of times both `html` and `custom_excerpt` fields on posts/pages are empty and the output of `{{excerpt}}` helper is also empty. We do return an `excerpt` property as a part of post resource which can serve as a safe fallback for when the above fields are not filled. It massively improves the experience of using the helper with gated content - Refactored nested ternaries to be more readable - Added fallback to excerpt property when HTML is hidden from members - Removed note about the review of excerpt helper - Added test case for 'excerpt' property --- core/frontend/helpers/excerpt.js | 25 +++++------ core/test/unit/helpers/excerpt_spec.js | 61 ++++++++++++++++---------- 2 files changed, 49 insertions(+), 37 deletions(-) diff --git a/core/frontend/helpers/excerpt.js b/core/frontend/helpers/excerpt.js index ae3cf6c565..f7635ca864 100644 --- a/core/frontend/helpers/excerpt.js +++ b/core/frontend/helpers/excerpt.js @@ -10,20 +10,19 @@ var proxy = require('./proxy'), SafeString = proxy.SafeString, getMetaDataExcerpt = proxy.metaData.getMetaDataExcerpt; -/** - * @NOTE: - * - * Content API v2 returns a calculated `post.excerpt` field. - * See https://github.com/TryGhost/Ghost/issues/10062. - * We have not touched this helper yet, we will revisit later. - */ module.exports = function excerpt(options) { - var truncateOptions = (options || {}).hash || {}, - excerptText = this.custom_excerpt - ? String(this.custom_excerpt) - : this.html - ? String(this.html) - : ''; + let truncateOptions = (options || {}).hash || {}; + let excerptText; + + if (this.custom_excerpt) { + excerptText = String(this.custom_excerpt); + } else if (this.html) { + excerptText = String(this.html); + } else if (this.excerpt) { + excerptText = String(this.excerpt); + } else { + excerptText = ''; + } truncateOptions = _.pick(truncateOptions, ['words', 'characters']); _.keys(truncateOptions).map(function (key) { diff --git a/core/test/unit/helpers/excerpt_spec.js b/core/test/unit/helpers/excerpt_spec.js index 2475e74140..9a71832110 100644 --- a/core/test/unit/helpers/excerpt_spec.js +++ b/core/test/unit/helpers/excerpt_spec.js @@ -1,22 +1,23 @@ -var should = require('should'), +const should = require('should'), // Stuff we are testing helpers = require('../../../frontend/helpers'); describe('{{excerpt}} Helper', function () { - it('renders empty string when html and excerpt are null', function () { - var html = null, - rendered = helpers.excerpt.call({ - html: html, - custom_excerpt: null - }); + it('renders empty string when html, excerpt, and custom_excerpt are null', function () { + const html = null; + const rendered = helpers.excerpt.call({ + html: html, + custom_excerpt: null, + excerpt: null + }); should.exist(rendered); rendered.string.should.equal(''); }); - it('can render excerpt', function () { - var html = 'Hello World', + it('can render custom_excerpt', function () { + const html = 'Hello World', rendered = helpers.excerpt.call({ html: html, custom_excerpt: '' @@ -26,8 +27,20 @@ describe('{{excerpt}} Helper', function () { rendered.string.should.equal(html); }); + it('can render excerpt when other fields are empty', function () { + const html = '', + rendered = helpers.excerpt.call({ + html: html, + custom_excerpt: '', + excerpt: 'Regular excerpt' + }); + + should.exist(rendered); + rendered.string.should.equal('Regular excerpt'); + }); + it('does not output HTML', function () { - var html = '

There are
10
types
of people in the world:' + + const html = '

There are
10
types
of people in the world:' + 'c those who ' + 'understand trinary,

those who don\'t
and' + '< test > those<<< test >>> who mistake it <for> binary.', @@ -43,7 +56,7 @@ describe('{{excerpt}} Helper', function () { }); it('strips multiple inline footnotes', function () { - var html = '

Testing1, my footnotes. And stuff. Footnote2with a link right after.', + const html = '

Testing1, my footnotes. And stuff. Footnote2with a link right after.', expected = 'Testing, my footnotes. And stuff. Footnotewith a link right after.', rendered = helpers.excerpt.call({ html: html, @@ -55,7 +68,7 @@ describe('{{excerpt}} Helper', function () { }); it('strips inline and bottom footnotes', function () { - var html = '

Testing1 a very short post with a single footnote.

\n' + + const html = '

Testing1 a very short post with a single footnote.

\n' + '', expected = 'Testing a very short post with a single footnote.', rendered = helpers.excerpt.call({ @@ -68,7 +81,7 @@ describe('{{excerpt}} Helper', function () { }); it('can truncate html by word', function () { - var html = '

Hello World! It\'s me!

', + const html = '

Hello World! It\'s me!

', expected = 'Hello World!', rendered = ( helpers.excerpt.call( @@ -85,7 +98,7 @@ describe('{{excerpt}} Helper', function () { }); it('can truncate html with non-ascii characters by word', function () { - var html = '

Едквюэ опортэат праэчынт ючю но, квуй эю

', + const html = '

Едквюэ опортэат праэчынт ючю но, квуй эю

', expected = 'Едквюэ опортэат', rendered = ( helpers.excerpt.call( @@ -102,7 +115,7 @@ describe('{{excerpt}} Helper', function () { }); it('can truncate html by character', function () { - var html = '

Hello World! It\'s me!

', + const html = '

Hello World! It\'s me!

', expected = 'Hello Wo', rendered = ( helpers.excerpt.call( @@ -118,8 +131,8 @@ describe('{{excerpt}} Helper', function () { rendered.string.should.equal(expected); }); - it('uses custom excerpt if provided instead of truncating html', function () { - var html = '

Hello World! It\'s me!

', + it('uses custom_excerpt if provided instead of truncating html', function () { + const html = '

Hello World! It\'s me!

', customExcerpt = 'My Custom Excerpt wins!', expected = 'My Custom Excerpt wins!', rendered = ( @@ -135,8 +148,8 @@ describe('{{excerpt}} Helper', function () { rendered.string.should.equal(expected); }); - it('does not truncate custom excerpt if characters options is provided', function () { - var html = '

Hello World! It\'s me!

', + it('does not truncate custom_excerpt if characters options is provided', function () { + const html = '

Hello World! It\'s me!

', customExcerpt = 'This is a custom excerpt. It should always be rendered in full length and not being cut ' + 'off. The maximum length of a custom excerpt is 300 characters. Enough to tell a bit about ' + 'your story and make a nice summary for your readers. It\s only allowed to truncate anything ' + @@ -159,8 +172,8 @@ describe('{{excerpt}} Helper', function () { rendered.string.should.equal(expected); }); - it('does not truncate custom excerpt if words options is provided', function () { - var html = '

Hello World! It\'s me!

', + it('does not truncate custom_excerpt if words options is provided', function () { + const html = '

Hello World! It\'s me!

', customExcerpt = 'This is a custom excerpt. It should always be rendered in full length and not being cut ' + 'off. The maximum length of a custom excerpt is 300 characters. Enough to tell a bit about ' + 'your story and make a nice summary for your readers. It\s only allowed to truncate anything ' + @@ -184,7 +197,7 @@ describe('{{excerpt}} Helper', function () { }); it('puts additional space after closing paragraph', function () { - var html = '

Testing.

Space before this text.

And this as well!

', + const html = '

Testing.

Space before this text.

And this as well!

', expected = 'Testing. Space before this text. And this as well!', rendered = ( helpers.excerpt.call( @@ -200,7 +213,7 @@ describe('{{excerpt}} Helper', function () { }); it('puts additional space instead of
tag', function () { - var html = '

Testing.
Space before this text.
And this as well!

', + const html = '

Testing.
Space before this text.
And this as well!

', expected = 'Testing. Space before this text. And this as well!', rendered = ( helpers.excerpt.call( @@ -216,7 +229,7 @@ describe('{{excerpt}} Helper', function () { }); it('puts additional space between paragraph in markup generated by Ghost', function () { - var html = '

put space in excerpt.

before this paragraph.

' + + const html = '

put space in excerpt.

before this paragraph.

' + '
' + '

and skip the image.

', expected = 'put space in excerpt. before this paragraph. and skip the image.',