2014-10-10 18:54:07 +04:00
|
|
|
// ### Pagination Helper
|
|
|
|
// `{{pagination}}`
|
|
|
|
// Outputs previous and next buttons, along with info about the current page
|
2022-04-05 19:38:46 +03:00
|
|
|
const {templates, hbs} = require('../services/handlebars');
|
2014-10-10 18:54:07 +04:00
|
|
|
|
2021-09-26 23:01:13 +03:00
|
|
|
const errors = require('@tryghost/errors');
|
|
|
|
const tpl = require('@tryghost/tpl');
|
2020-03-30 23:23:02 +03:00
|
|
|
const _ = require('lodash');
|
2021-09-23 22:46:22 +03:00
|
|
|
|
|
|
|
const messages = {
|
|
|
|
invalidData: 'The {{pagination}} helper was used outside of a paginated context. See https://ghost.org/docs/themes/helpers/pagination/.',
|
|
|
|
valuesMustBeDefined: 'All values must be defined for page, pages, limit and total',
|
|
|
|
nextPrevValuesMustBeNumeric: 'Invalid value, Next/Prev must be a number',
|
|
|
|
valuesMustBeNumeric: 'Invalid value, check page, pages, limit and total are numbers'
|
|
|
|
};
|
|
|
|
|
2020-03-30 23:23:02 +03:00
|
|
|
const createFrame = hbs.handlebars.createFrame;
|
|
|
|
|
|
|
|
module.exports = function pagination(options) {
|
2019-03-09 22:35:19 +03:00
|
|
|
options = options || {};
|
|
|
|
options.hash = options.hash || {};
|
|
|
|
options.data = options.data || {};
|
|
|
|
|
2014-10-10 18:54:07 +04:00
|
|
|
if (!_.isObject(this.pagination) || _.isFunction(this.pagination)) {
|
2016-10-06 15:27:35 +03:00
|
|
|
throw new errors.IncorrectUsageError({
|
2017-11-28 15:15:05 +03:00
|
|
|
level: 'normal',
|
2021-09-23 22:46:22 +03:00
|
|
|
message: tpl(messages.invalidData),
|
2021-01-19 23:59:45 +03:00
|
|
|
help: 'https://ghost.org/docs/themes/helpers/pagination/'
|
2016-10-06 15:27:35 +03:00
|
|
|
});
|
2014-10-10 18:54:07 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
if (_.isUndefined(this.pagination.page) || _.isUndefined(this.pagination.pages) ||
|
|
|
|
_.isUndefined(this.pagination.total) || _.isUndefined(this.pagination.limit)) {
|
2016-10-06 15:27:35 +03:00
|
|
|
throw new errors.IncorrectUsageError({
|
2021-09-23 22:46:22 +03:00
|
|
|
message: tpl(messages.valuesMustBeDefined)
|
2016-10-06 15:27:35 +03:00
|
|
|
});
|
2014-10-10 18:54:07 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
if ((!_.isNull(this.pagination.next) && !_.isNumber(this.pagination.next)) ||
|
|
|
|
(!_.isNull(this.pagination.prev) && !_.isNumber(this.pagination.prev))) {
|
2016-10-06 15:27:35 +03:00
|
|
|
throw new errors.IncorrectUsageError({
|
2021-09-23 22:46:22 +03:00
|
|
|
message: tpl(messages.nextPrevValuesMustBeNumeric)
|
2016-10-06 15:27:35 +03:00
|
|
|
});
|
2014-10-10 18:54:07 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
if (!_.isNumber(this.pagination.page) || !_.isNumber(this.pagination.pages) ||
|
|
|
|
!_.isNumber(this.pagination.total) || !_.isNumber(this.pagination.limit)) {
|
2021-09-23 22:46:22 +03:00
|
|
|
throw new errors.IncorrectUsageError({message: tpl(messages.valuesMustBeNumeric)});
|
2014-10-10 18:54:07 +04:00
|
|
|
}
|
2019-05-20 13:31:56 +03:00
|
|
|
|
|
|
|
// CASE: The pagination helper should have access to the pagination properties at the top level.
|
|
|
|
_.merge(this, this.pagination);
|
|
|
|
// CASE: The pagination helper will forward attributes passed to it.
|
|
|
|
_.merge(this, options.hash);
|
2019-03-09 22:35:19 +03:00
|
|
|
const data = createFrame(options.data);
|
2014-10-10 18:54:07 +04:00
|
|
|
|
2019-05-20 13:31:56 +03:00
|
|
|
return templates.execute('pagination', this, {data});
|
2014-10-10 18:54:07 +04:00
|
|
|
};
|