diff --git a/ghost/email-service/lib/EmailRenderer.js b/ghost/email-service/lib/EmailRenderer.js index 1a66fd4249..373bd90dad 100644 --- a/ghost/email-service/lib/EmailRenderer.js +++ b/ghost/email-service/lib/EmailRenderer.js @@ -10,6 +10,7 @@ const htmlToPlaintext = require('@tryghost/html-to-plaintext'); const tpl = require('@tryghost/tpl'); const cheerio = require('cheerio'); const {EmailAddressParser} = require('@tryghost/email-addresses'); +const {registerHelpers} = require('./helpers/register-helpers'); const messages = { subscriptionStatus: { @@ -755,53 +756,16 @@ class EmailRenderer { return replacements; } + getLabs() { + return this.#labs; + } + async renderTemplate(data) { + const labs = this.getLabs(); this.#handlebars = require('handlebars').create(); - // Helpers - this.#handlebars.registerHelper('if', function (conditional, options) { - if (conditional) { - return options.fn(this); - } else { - return options.inverse(this); - } - }); - - this.#handlebars.registerHelper('and', function () { - const len = arguments.length - 1; - - for (let i = 0; i < len; i++) { - if (!arguments[i]) { - return false; - } - } - - return true; - }); - - this.#handlebars.registerHelper('not', function () { - const len = arguments.length - 1; - - for (let i = 0; i < len; i++) { - if (!arguments[i]) { - return true; - } - } - - return false; - }); - - this.#handlebars.registerHelper('or', function () { - const len = arguments.length - 1; - - for (let i = 0; i < len; i++) { - if (arguments[i]) { - return true; - } - } - - return false; - }); + // Register helpers + registerHelpers(this.#handlebars, labs); // Partials if (this.#labs.isSet('emailCustomization')) { diff --git a/ghost/email-service/lib/helpers/register-helpers.js b/ghost/email-service/lib/helpers/register-helpers.js new file mode 100644 index 0000000000..8d097f251a --- /dev/null +++ b/ghost/email-service/lib/helpers/register-helpers.js @@ -0,0 +1,55 @@ +module.exports = { + registerHelpers(handlebars, labs) { + handlebars.registerHelper('if', function (conditional, options) { + if (conditional) { + return options.fn(this); + } else { + return options.inverse(this); + } + }); + + handlebars.registerHelper('and', function () { + const len = arguments.length - 1; + + for (let i = 0; i < len; i++) { + if (!arguments[i]) { + return false; + } + } + + return true; + }); + + handlebars.registerHelper('not', function () { + const len = arguments.length - 1; + + for (let i = 0; i < len; i++) { + if (!arguments[i]) { + return true; + } + } + + return false; + }); + + handlebars.registerHelper('or', function () { + const len = arguments.length - 1; + + for (let i = 0; i < len; i++) { + if (arguments[i]) { + return true; + } + } + + return false; + }); + + handlebars.registerHelper('hasFeature', function (flag, options) { + if (labs.isSet(flag)) { + return options.fn(this); + } else { + return options.inverse(this); + } + }); + } +}; diff --git a/ghost/email-service/test/email-helpers.test.js b/ghost/email-service/test/email-helpers.test.js new file mode 100644 index 0000000000..7231b19989 --- /dev/null +++ b/ghost/email-service/test/email-helpers.test.js @@ -0,0 +1,142 @@ +const assert = require('assert/strict'); +const {registerHelpers} = require('../lib/helpers/register-helpers'); + +describe('registerHelpers', function () { + it('registers helpers', function () { + const handlebars = { + registerHelper: function (name, fn) { + this[name] = fn; + } + }; + const labs = { + isSet: function () { + return true; + } + }; + registerHelpers(handlebars, labs); + + assert.ok(handlebars.if); + assert.ok(handlebars.and); + assert.ok(handlebars.not); + assert.ok(handlebars.or); + assert.ok(handlebars.hasFeature); + }); + + it('if helper returns true', function () { + const handlebars = { + registerHelper: function (name, fn) { + this[name] = fn; + } + }; + const labs = { + isSet: function () { + return true; + } + }; + registerHelpers(handlebars, labs); + + const result = handlebars.if(true, { + fn: function () { + return true; + }, + inverse: function () { + return false; + } + }); + + assert.equal(result, true); + }); + + it('if helper returns false', function () { + const handlebars = { + registerHelper: function (name, fn) { + this[name] = fn; + } + }; + const labs = { + isSet: function () { + return true; + } + }; + registerHelpers(handlebars, labs); + + const result = handlebars.if(false, { + fn: function () { + return true; + }, + inverse: function () { + return false; + } + }); + + assert.equal(result, false); + }); + + it('and helper returns true', function () { + const handlebars = { + registerHelper: function (name, fn) { + this[name] = fn; + } + }; + const labs = { + isSet: function () { + return true; + } + }; + registerHelpers(handlebars, labs); + + const result = handlebars.and(true, true); + + assert.equal(result, true); + }); + + it('usefeature helper returns true', function () { + const handlebars = { + registerHelper: function (name, fn) { + this[name] = fn; + } + }; + const labs = { + isSet: function () { + return true; + } + }; + registerHelpers(handlebars, labs); + + const result = handlebars.hasFeature('test', { + fn: function () { + return true; + }, + inverse: function () { + return false; + } + }); + + assert.equal(result, true); + }); + + it('usefeature helper returns false', function () { + const handlebars = { + registerHelper: function (name, fn) { + this[name] = fn; + } + }; + const labs = { + isSet: function () { + return false; + } + }; + registerHelpers(handlebars, labs); + + const result = handlebars.hasFeature('test', { + fn: function () { + return true; + }, + inverse: function () { + return false; + } + }); + + assert.equal(result, false); + }); +}); \ No newline at end of file