mirror of
https://github.com/TryGhost/Ghost.git
synced 2025-01-03 00:15:11 +03:00
✨ Attr pass-thru & full context in partial helpers
refs #5162 - allow pagination and navigation partial helpers to have attributes passed through to them - e.g. {{navigation header=true}} -> {{#if header}} will now work - allows styling navigation to be done differently for different sections of the page - properly create a data frame, and pass through "this" context - means {{navigation header=true}} is the same as {{> navigation header=true navigation=@site.navigation}} - our partial helpers, have the same behaviour exactly as if the partial was called directly - this is additive, and improves behaviour
This commit is contained in:
parent
82788f2f5c
commit
d2b1e0d4b7
@ -3,6 +3,7 @@
|
||||
const _ = require('lodash'),
|
||||
// (Less) dirty requires
|
||||
proxy = require('../../../../helpers/proxy'),
|
||||
createFrame = proxy.hbs.handlebars.createFrame,
|
||||
templates = proxy.templates,
|
||||
urlService = proxy.urlService,
|
||||
SafeString = proxy.SafeString,
|
||||
@ -38,17 +39,18 @@ const subscribeScript = `
|
||||
|
||||
// We use the name subscribe_form to match the helper for consistency:
|
||||
module.exports = function subscribe_form(options) { // eslint-disable-line camelcase
|
||||
const root = options.data.root,
|
||||
data = _.merge({}, options.hash, _.pick(root, params), {
|
||||
// routeKeywords.subscribe: 'subscribe'
|
||||
action: urlService.utils.urlJoin('/', urlService.utils.getSubdir(), 'subscribe/'),
|
||||
script: new SafeString(subscribeScript),
|
||||
hidden: new SafeString(
|
||||
makeHidden('confirm') +
|
||||
const root = options.data.root;
|
||||
|
||||
const context = _.merge({}, options.hash, _.pick(root, params), {
|
||||
// routeKeywords.subscribe: 'subscribe'
|
||||
action: urlService.utils.urlJoin('/', urlService.utils.getSubdir(), 'subscribe/'),
|
||||
script: new SafeString(subscribeScript),
|
||||
hidden: new SafeString(
|
||||
makeHidden('confirm') +
|
||||
makeHidden('location', root.subscribed_url ? `value=${root.subscribed_url}` : '') +
|
||||
makeHidden('referrer', root.subscribed_referrer ? `value=${root.subscribed_referrer}` : '')
|
||||
)
|
||||
});
|
||||
|
||||
return templates.execute('subscribe_form', data, options);
|
||||
)
|
||||
});
|
||||
const data = createFrame(options.data);
|
||||
return templates.execute('subscribe_form', context, {data});
|
||||
};
|
||||
|
@ -6,16 +6,20 @@ var proxy = require('./proxy'),
|
||||
string = require('../lib/security/string'),
|
||||
_ = require('lodash'),
|
||||
SafeString = proxy.SafeString,
|
||||
createFrame = proxy.hbs.handlebars.createFrame,
|
||||
i18n = proxy.i18n,
|
||||
errors = proxy.errors,
|
||||
templates = proxy.templates;
|
||||
|
||||
module.exports = function navigation(options) {
|
||||
options = options || {};
|
||||
options.hash = options.hash || {};
|
||||
options.data = options.data || {};
|
||||
|
||||
var navigationData = options.data.blog.navigation,
|
||||
currentUrl = options.data.root.relativeUrl,
|
||||
self = this,
|
||||
output,
|
||||
data;
|
||||
output;
|
||||
|
||||
if (!_.isObject(navigationData) || _.isFunction(navigationData)) {
|
||||
throw new errors.IncorrectUsageError({
|
||||
@ -71,8 +75,8 @@ module.exports = function navigation(options) {
|
||||
return out;
|
||||
});
|
||||
|
||||
data = _.merge({}, {navigation: output});
|
||||
const context = _.merge({}, this, options.hash, {navigation: output});
|
||||
const data = createFrame(options.data);
|
||||
|
||||
return templates.execute('navigation', data, options);
|
||||
return templates.execute('navigation', context, {data});
|
||||
};
|
||||
|
||||
|
@ -6,10 +6,15 @@ var proxy = require('./proxy'),
|
||||
_ = require('lodash'),
|
||||
errors = proxy.errors,
|
||||
i18n = proxy.i18n,
|
||||
createFrame = proxy.hbs.handlebars.createFrame,
|
||||
templates = proxy.templates,
|
||||
pagination;
|
||||
|
||||
pagination = function (options) {
|
||||
options = options || {};
|
||||
options.hash = options.hash || {};
|
||||
options.data = options.data || {};
|
||||
|
||||
if (!_.isObject(this.pagination) || _.isFunction(this.pagination)) {
|
||||
throw new errors.IncorrectUsageError({
|
||||
level: 'normal',
|
||||
@ -36,10 +41,10 @@ pagination = function (options) {
|
||||
!_.isNumber(this.pagination.total) || !_.isNumber(this.pagination.limit)) {
|
||||
throw new errors.IncorrectUsageError({message: i18n.t('warnings.helpers.pagination.valuesMustBeNumeric')});
|
||||
}
|
||||
const context = _.merge({}, this, options.hash, this.pagination);
|
||||
const data = createFrame(options.data);
|
||||
|
||||
var data = _.merge({}, this.pagination);
|
||||
|
||||
return templates.execute('pagination', data, options);
|
||||
return templates.execute('pagination', context, {data});
|
||||
};
|
||||
|
||||
module.exports = pagination;
|
||||
|
@ -7,7 +7,7 @@ var templates = {},
|
||||
|
||||
// Execute a template helper
|
||||
// All template helpers are register as partial view.
|
||||
templates.execute = function execute(name, context, options) {
|
||||
templates.execute = function execute(name, context, data) {
|
||||
var partial = hbs.handlebars.partials[name];
|
||||
|
||||
if (partial === undefined) {
|
||||
@ -21,7 +21,7 @@ templates.execute = function execute(name, context, options) {
|
||||
hbs.registerPartial(partial);
|
||||
}
|
||||
|
||||
return new hbs.SafeString(partial(context, options));
|
||||
return new hbs.SafeString(partial(context, data));
|
||||
};
|
||||
|
||||
templates.asset = _.template('<%= source %>?v=<%= version %>');
|
||||
|
@ -197,8 +197,7 @@ describe('{{navigation}} helper with custom template', function () {
|
||||
optionsData = {
|
||||
data: {
|
||||
blog: {
|
||||
navigation: [],
|
||||
title: 'Chaos is a ladder.'
|
||||
navigation: [{label: 'Foo', url: '/foo'}]
|
||||
},
|
||||
root: {
|
||||
relativeUrl: ''
|
||||
@ -208,15 +207,33 @@ describe('{{navigation}} helper with custom template', function () {
|
||||
});
|
||||
|
||||
it('can render one item and @blog title', function () {
|
||||
var singleItem = {label: 'Foo', url: '/foo'},
|
||||
testUrl = 'href="' + configUtils.config.get('url') + '/foo"',
|
||||
var testUrl = 'href="' + configUtils.config.get('url') + '/foo"',
|
||||
rendered;
|
||||
|
||||
optionsData.data.blog.navigation = [singleItem];
|
||||
// Set @blog.title
|
||||
optionsData.data.blog.title = 'Chaos is a ladder.';
|
||||
|
||||
rendered = helpers.navigation(optionsData);
|
||||
|
||||
should.exist(rendered);
|
||||
rendered.string.should.containEql('Chaos is a ladder');
|
||||
rendered.string.should.not.containEql('isHeader is set');
|
||||
rendered.string.should.containEql(testUrl);
|
||||
rendered.string.should.containEql('Foo');
|
||||
});
|
||||
|
||||
it('can pass attributes through', function () {
|
||||
var testUrl = 'href="' + configUtils.config.get('url') + '/foo"',
|
||||
rendered;
|
||||
|
||||
// Simulate {{navigation isHeader=true}}
|
||||
optionsData.hash = {isHeader: true};
|
||||
|
||||
rendered = helpers.navigation(optionsData);
|
||||
|
||||
should.exist(rendered);
|
||||
rendered.string.should.not.containEql('Chaos is a ladder');
|
||||
rendered.string.should.containEql('isHeader is set');
|
||||
rendered.string.should.containEql(testUrl);
|
||||
rendered.string.should.containEql('Foo');
|
||||
});
|
||||
|
@ -144,5 +144,23 @@ describe('{{pagination}} helper with custom template', function () {
|
||||
// strip out carriage returns and compare.
|
||||
rendered.string.should.match(/Page 1 of 1/);
|
||||
rendered.string.should.containEql('Chaos is a ladder');
|
||||
rendered.string.should.not.containEql('isHeader is set');
|
||||
});
|
||||
|
||||
it('can pass attributes through', function () {
|
||||
var rendered = helpers.pagination.call({
|
||||
pagination: {page: 1, prev: null, next: null, limit: 15, total: 8, pages: 1},
|
||||
tag: {slug: 'slug'}
|
||||
}, {
|
||||
hash: {isHeader: true},
|
||||
data: {
|
||||
blog: {}
|
||||
}
|
||||
});
|
||||
should.exist(rendered);
|
||||
// strip out carriage returns and compare.
|
||||
rendered.string.should.match(/Page 1 of 1/);
|
||||
rendered.string.should.not.containEql('Chaos is a ladder');
|
||||
rendered.string.should.containEql('isHeader is set');
|
||||
});
|
||||
});
|
||||
|
@ -1,5 +1,7 @@
|
||||
{{@blog.title}}
|
||||
|
||||
{{#if isHeader}}isHeader is set{{/if}}
|
||||
|
||||
{{#foreach navigation}}
|
||||
<a href="{{url absolute="true"}}">{{label}}</a>
|
||||
{{/foreach}}
|
||||
|
@ -1,2 +1,5 @@
|
||||
{{@blog.title}}
|
||||
|
||||
{{#if isHeader}}isHeader is set{{/if}}
|
||||
|
||||
<span class="page-number">Page {{page}} of {{pages}}</span>
|
||||
|
Loading…
Reference in New Issue
Block a user