diff --git a/core/server/helpers/prev_next.js b/core/server/helpers/prev_next.js index 3fc2b04468..f0bcf70347 100644 --- a/core/server/helpers/prev_next.js +++ b/core/server/helpers/prev_next.js @@ -77,7 +77,8 @@ fetch = function fetch(options, data) { module.exports = function prevNext(options) { options = options || {}; - var data = createFrame(options.data); + const data = createFrame(options.data); + const context = options.data.root.context; // Guard against incorrect usage of the helpers if (!options.fn || !options.inverse) { @@ -86,8 +87,12 @@ module.exports = function prevNext(options) { return Promise.resolve(); } - // Guard against trying to execute prev/next on previews, pages, or other resources - if (!isPost(this) || this.status !== 'published' || this.page) { + if (context.includes('preview')) { + return Promise.resolve(options.inverse(this, {data: data})); + } + + // Guard against trying to execute prev/next on pages, or other resources + if (!isPost(this) || this.page) { return Promise.resolve(options.inverse(this, {data: data})); } diff --git a/core/server/services/routing/PreviewRouter.js b/core/server/services/routing/PreviewRouter.js index d1bbbf5c40..f47fbc498c 100644 --- a/core/server/services/routing/PreviewRouter.js +++ b/core/server/services/routing/PreviewRouter.js @@ -22,7 +22,8 @@ class PreviewRouter extends ParentRouter { _prepareContext(req, res, next) { res.routerOptions = { type: 'entry', - query: this.RESOURCE_CONFIG + query: this.RESOURCE_CONFIG, + context: ['preview'] }; next(); diff --git a/core/server/services/routing/helpers/context.js b/core/server/services/routing/helpers/context.js index 512cc1f2fb..8e25bb4891 100644 --- a/core/server/services/routing/helpers/context.js +++ b/core/server/services/routing/helpers/context.js @@ -18,8 +18,7 @@ const labs = require('../../labs'), subscribePattern = new RegExp('^\\/subscribe\\/'), // routeKeywords.amp: 'amp' ampPattern = new RegExp('\\/amp\\/$'), - homePattern = new RegExp('^\\/$'), - previewPattern = new RegExp('^\\/p\\/'); + homePattern = new RegExp('^\\/$'); function setResponseContext(req, res, data) { var pageParam = req.params && req.params.page !== undefined ? parseInt(req.params.page, 10) : 1; @@ -47,21 +46,31 @@ function setResponseContext(req, res, data) { res.locals.context.push('amp'); } - if (previewPattern.test(res.locals.relativeUrl)) { - res.locals.context.push('preview'); - } - // Each page can only have at most one of these if (res.routerOptions && res.routerOptions.context) { res.locals.context = res.locals.context.concat(res.routerOptions.context); - } else if (privatePattern.test(res.locals.relativeUrl)) { - res.locals.context.push('private'); - } else if (subscribePattern.test(res.locals.relativeUrl) && labs.isSet('subscribers') === true) { - res.locals.context.push('subscribe'); - } else if (data && data.post && data.post.page) { - res.locals.context.push('page'); + } + + if (privatePattern.test(res.locals.relativeUrl)) { + if (!res.locals.context.includes('private')) { + res.locals.context.push('private'); + } + } + + if (subscribePattern.test(res.locals.relativeUrl) && labs.isSet('subscribers') === true) { + if (!res.locals.context.includes('subscribe')) { + res.locals.context.push('subscribe'); + } + } + + if (data && data.post && data.post.page) { + if (!res.locals.context.includes('page')) { + res.locals.context.push('page'); + } } else if (data && data.post) { - res.locals.context.push('post'); + if (!res.locals.context.includes('post')) { + res.locals.context.push('post'); + } } } diff --git a/core/test/unit/helpers/next_post_spec.js b/core/test/unit/helpers/next_post_spec.js index 1dc89ccdd1..cd547cecb9 100644 --- a/core/test/unit/helpers/next_post_spec.js +++ b/core/test/unit/helpers/next_post_spec.js @@ -14,7 +14,14 @@ describe('{{next_post}} helper', function () { var browsePostStub; beforeEach(function () { - locals = {root: {_locals: {apiVersion: 'v0.1'}}}; + locals = { + root: { + _locals: { + apiVersion: 'v0.1' + }, + context: ['post'] + } + }; }); afterEach(function () { @@ -130,6 +137,15 @@ describe('{{next_post}} helper', function () { describe('for page', function () { beforeEach(function () { + locals = { + root: { + _locals: { + apiVersion: 'v0.1' + }, + context: ['page'] + } + }; + browsePostStub = sandbox.stub(api['v0.1'].posts, 'browse').callsFake(function (options) { if (options.filter.indexOf('published_at:>') > -1) { return Promise.resolve({posts: [{slug: '/previous/', title: 'post 1'}]}); @@ -165,6 +181,15 @@ describe('{{next_post}} helper', function () { describe('for unpublished post', function () { beforeEach(function () { + locals = { + root: { + _locals: { + apiVersion: 'v0.1' + }, + context: ['preview', 'post'] + } + }; + browsePostStub = sandbox.stub(api['v0.1'].posts, 'browse').callsFake(function (options) { if (options.filter.indexOf('published_at:>') > -1) { return Promise.resolve({posts: [{slug: '/next/', title: 'post 3'}]}); @@ -406,7 +431,7 @@ describe('{{next_post}} helper', function () { it('should show warning for call without any options', function (done) { var fn = sinon.spy(), inverse = sinon.spy(), - optionsData = {name: 'next_post'}; + optionsData = {name: 'next_post', data: {root: {}}}; helpers.next_post .call( diff --git a/core/test/unit/helpers/prev_post_spec.js b/core/test/unit/helpers/prev_post_spec.js index 365cf01b46..4b3b8f3cf4 100644 --- a/core/test/unit/helpers/prev_post_spec.js +++ b/core/test/unit/helpers/prev_post_spec.js @@ -14,7 +14,14 @@ describe('{{prev_post}} helper', function () { let locals; beforeEach(function () { - locals = {root: {_locals: {apiVersion: 'v0.1'}}}; + locals = { + root: { + _locals: { + apiVersion: 'v0.1' + }, + context: ['post'] + } + }; }); afterEach(function () { @@ -130,6 +137,15 @@ describe('{{prev_post}} helper', function () { describe('for page', function () { beforeEach(function () { + locals = { + root: { + _locals: { + apiVersion: 'v0.1' + }, + context: ['page'] + } + }; + browsePostStub = sandbox.stub(api['v0.1'].posts, 'browse').callsFake(function (options) { if (options.filter.indexOf('published_at:<=') > -1) { return Promise.resolve({posts: [{slug: '/previous/', title: 'post 1'}]}); @@ -165,6 +181,15 @@ describe('{{prev_post}} helper', function () { describe('for unpublished post', function () { beforeEach(function () { + locals = { + root: { + _locals: { + apiVersion: 'v0.1' + }, + context: ['preview', 'post'] + } + }; + browsePostStub = sandbox.stub(api['v0.1'].posts, 'browse').callsFake(function (options) { if (options.filter.indexOf('published_at:<=') > -1) { return Promise.resolve({posts: [{slug: '/previous/', title: 'post 1'}]}); @@ -406,7 +431,7 @@ describe('{{prev_post}} helper', function () { it('should show warning for call without any options', function (done) { var fn = sinon.spy(), inverse = sinon.spy(), - optionsData = {name: 'prev_post'}; + optionsData = {name: 'prev_post', data: {root: {}}}; helpers.prev_post .call(