// ### Pagination Helper // `{{pagination}}` // Outputs previous and next buttons, along with info about the current page const {templates, hbs} = require('../services/handlebars'); const errors = require('@tryghost/errors'); const tpl = require('@tryghost/tpl'); const _ = require('lodash'); 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' }; const createFrame = hbs.handlebars.createFrame; module.exports = function pagination(options) { options = options || {}; options.hash = options.hash || {}; options.data = options.data || {}; if (!_.isObject(this.pagination) || _.isFunction(this.pagination)) { throw new errors.IncorrectUsageError({ level: 'normal', message: tpl(messages.invalidData), help: 'https://ghost.org/docs/themes/helpers/pagination/' }); } if (_.isUndefined(this.pagination.page) || _.isUndefined(this.pagination.pages) || _.isUndefined(this.pagination.total) || _.isUndefined(this.pagination.limit)) { throw new errors.IncorrectUsageError({ message: tpl(messages.valuesMustBeDefined) }); } if ((!_.isNull(this.pagination.next) && !_.isNumber(this.pagination.next)) || (!_.isNull(this.pagination.prev) && !_.isNumber(this.pagination.prev))) { throw new errors.IncorrectUsageError({ message: tpl(messages.nextPrevValuesMustBeNumeric) }); } if (!_.isNumber(this.pagination.page) || !_.isNumber(this.pagination.pages) || !_.isNumber(this.pagination.total) || !_.isNumber(this.pagination.limit)) { throw new errors.IncorrectUsageError({message: tpl(messages.valuesMustBeNumeric)}); } // 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); const data = createFrame(options.data); return templates.execute('pagination', this, {data}); };