mirror of
https://github.com/TryGhost/Ghost.git
synced 2025-04-08 02:52:39 -05:00
🐛 Fixed missing @page
object in themes when rendering custom routed page (#17693)
closes https://github.com/TryGhost/Ghost/issues/17681 - updated `prepareContextResource()` to make sure `show_title_and_feature_image` is always removed from pages - updated `formatResponse.entries()` to apply the same `@page` local behaviour when it's passed a `data.page` object to account for custom routed pages
This commit is contained in:
parent
6c481b74a9
commit
1ebdac3997
7 changed files with 60 additions and 6 deletions
|
@ -3,6 +3,10 @@ function isPost(jsonData) {
|
|||
Object.prototype.hasOwnProperty.call(jsonData, 'title') && Object.prototype.hasOwnProperty.call(jsonData, 'slug');
|
||||
}
|
||||
|
||||
function isPage(jsonData = {}) {
|
||||
return Object.prototype.hasOwnProperty.call(jsonData, 'show_title_and_feature_image');
|
||||
}
|
||||
|
||||
function isTag(jsonData) {
|
||||
return Object.prototype.hasOwnProperty.call(jsonData, 'name') && Object.prototype.hasOwnProperty.call(jsonData, 'slug') &&
|
||||
Object.prototype.hasOwnProperty.call(jsonData, 'description') && Object.prototype.hasOwnProperty.call(jsonData, 'feature_image');
|
||||
|
@ -20,6 +24,7 @@ function isNav(jsonData) {
|
|||
|
||||
module.exports = {
|
||||
isPost,
|
||||
isPage,
|
||||
isTag,
|
||||
isUser,
|
||||
isNav
|
||||
|
|
|
@ -26,10 +26,10 @@ module.exports = {
|
|||
if (resource.feature_image_caption) {
|
||||
resource.feature_image_caption = new SafeString(resource.feature_image_caption);
|
||||
}
|
||||
});
|
||||
|
||||
// some properties are extracted to local template data to force one way of using it
|
||||
delete data.show_title_and_feature_image;
|
||||
// some properties are extracted to local template data to force one way of using it
|
||||
delete resource.show_title_and_feature_image;
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
|
|
|
@ -1,13 +1,14 @@
|
|||
const _ = require('lodash');
|
||||
const hbs = require('../theme-engine/engine');
|
||||
const {prepareContextResource} = require('../proxy');
|
||||
const {isPage} = require('../data/checks');
|
||||
|
||||
/**
|
||||
* @description Formats API response into handlebars/theme format.
|
||||
*
|
||||
* @return {Object} containing page variables
|
||||
*/
|
||||
function formatPageResponse(result, pageAsPost = false) {
|
||||
function formatPageResponse(result, pageAsPost = false, locals = {}) {
|
||||
const response = {};
|
||||
|
||||
if (result.posts) {
|
||||
|
@ -19,6 +20,28 @@ function formatPageResponse(result, pageAsPost = false) {
|
|||
response.pagination = result.meta.pagination;
|
||||
}
|
||||
|
||||
// when a custom routed page is loaded it can have an associated page object,
|
||||
// in that case we want to make sure @page is still available and matches the
|
||||
// selected page properties
|
||||
if (isPage(result.data?.page?.[0])) {
|
||||
const page = result.data?.page?.[0];
|
||||
|
||||
// build up @page data for use in templates
|
||||
// - done here rather than `update-local-template-options` middleware because
|
||||
// we need access to the rendered entry's data which isn't available in middleware
|
||||
const pageData = {
|
||||
show_title_and_feature_image: page.show_title_and_feature_image
|
||||
};
|
||||
|
||||
// merge @page into local template options
|
||||
const localTemplateOptions = hbs.getLocalTemplateOptions(locals);
|
||||
hbs.updateLocalTemplateOptions(locals, _.merge({}, localTemplateOptions, {
|
||||
data: {
|
||||
page: pageData
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
_.each(result.data, function (data, name) {
|
||||
prepareContextResource(data);
|
||||
|
||||
|
|
|
@ -14,6 +14,6 @@ module.exports = function renderEntries(req, res) {
|
|||
return function renderEntriesClosure(result) {
|
||||
// Format data 2
|
||||
// Render
|
||||
return renderer(req, res, formatResponse.entries(result));
|
||||
return renderer(req, res, formatResponse.entries(result, false, res.locals));
|
||||
};
|
||||
};
|
||||
|
|
|
@ -65,7 +65,7 @@ module.exports = function staticController(req, res, next) {
|
|||
// This flag solves the confusion about whether the output contains a post or page object by duplicating the objects
|
||||
// This is not ideal, but will solve some long standing pain points with dynamic routing until we can overhaul it
|
||||
const duplicatePagesAsPosts = true;
|
||||
renderer.renderer(req, res, renderer.formatResponse.entries(response, duplicatePagesAsPosts));
|
||||
renderer.renderer(req, res, renderer.formatResponse.entries(response, duplicatePagesAsPosts, res.locals));
|
||||
})
|
||||
.catch(renderer.handleError(next));
|
||||
};
|
||||
|
|
|
@ -5,6 +5,7 @@ describe('Checks', function () {
|
|||
it('methods', function () {
|
||||
Object.keys(checks).should.eql([
|
||||
'isPost',
|
||||
'isPage',
|
||||
'isTag',
|
||||
'isUser',
|
||||
'isNav'
|
||||
|
@ -17,6 +18,14 @@ describe('Checks', function () {
|
|||
checks.isPost({title: 'Test', slug: 'test', html: ''}).should.eql(true);
|
||||
});
|
||||
|
||||
it('isPage', function () {
|
||||
checks.isPage(undefined).should.eql(false);
|
||||
checks.isPage({}).should.eql(false);
|
||||
checks.isPage({title: 'Test'}).should.eql(false);
|
||||
checks.isPage({title: 'Test', show_title_and_feature_image: false}).should.eql(true);
|
||||
checks.isPage({title: 'Test', show_title_and_feature_image: true}).should.eql(true);
|
||||
});
|
||||
|
||||
it('isTag', function () {
|
||||
checks.isTag({}).should.eql(false);
|
||||
checks.isTag({name: 'Test'}).should.eql(false);
|
||||
|
|
|
@ -151,5 +151,22 @@ describe('Unit - services/routing/helpers/format-response', function () {
|
|||
formatted.featured_multiple[0].feature_image_caption.should.be.an.instanceof(SafeString);
|
||||
formatted.featured_multiple[1].feature_image_caption.should.be.an.instanceof(SafeString);
|
||||
});
|
||||
|
||||
it('should set @page when data.page is present (e.g. custom routing)', function () {
|
||||
const data = {
|
||||
posts,
|
||||
data: {
|
||||
page: [pages[1]]
|
||||
}
|
||||
};
|
||||
const locals = {};
|
||||
|
||||
const formatted = helpers.formatResponse.entries(data, true, locals);
|
||||
formatted.page.should.not.have.property('show_title_and_feature_image');
|
||||
|
||||
locals.should.be.an.Object().with.properties('_templateOptions');
|
||||
locals._templateOptions.data.should.be.an.Object().with.properties('page');
|
||||
locals._templateOptions.data.page.show_title_and_feature_image.should.be.false();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
Loading…
Add table
Reference in a new issue