Fixed frontend rendering of page resource

refs https://github.com/TryGhost/Toolbox/issues/332

- After removing the concept of a boolean "page: true" from the page/post resources frontend resource rendering didn't have enough information to pick the correct template
- Resolved this issue through passing of additional "context" to the template picker. Something nicer should be worked on in the future, as context pattern feels dirty here.
This commit is contained in:
Naz 2022-05-16 20:39:47 +08:00 committed by naz
parent 44c72ddd81
commit 0c097f6532
6 changed files with 35 additions and 18 deletions

View File

@ -10,11 +10,11 @@ module.exports = function body_class(options) { // eslint-disable-line camelcase
const context = options.data.root.context || []; const context = options.data.root.context || [];
const obj = this.post || this.page; const obj = this.post || this.page;
const tags = obj && obj.tags ? obj.tags : []; const tags = obj && obj.tags ? obj.tags : [];
const isPage = !!(obj && obj.page); const isPage = !!(this.page);
if (context.includes('home')) { if (context.includes('home')) {
classes.push('home-template'); classes.push('home-template');
} else if (context.includes('post') && obj) { } else if (context.includes('post') && obj && !isPage) {
classes.push('post-template'); classes.push('post-template');
} else if (context.includes('page') && obj && isPage) { } else if (context.includes('page') && obj && isPage) {
classes.push('page-template'); classes.push('page-template');

View File

@ -46,12 +46,18 @@ function formatPageResponse(result) {
* *
* @return {Object} containing page variables * @return {Object} containing page variables
*/ */
function formatResponse(post) { function formatResponse(post, context) {
prepareContextResource(post); prepareContextResource(post);
return { let entry = {
post: post post: post
}; };
if (context?.includes('page')) {
entry.page = post;
}
return entry;
} }
module.exports = { module.exports = {

View File

@ -13,6 +13,6 @@ module.exports = function renderEntry(req, res) {
return function renderEntryClosure(entry) { return function renderEntryClosure(entry) {
// Format data 2 - 1 is in preview/entry // Format data 2 - 1 is in preview/entry
// Render // Render
return renderer(req, res, formatResponse.entry(entry)); return renderer(req, res, formatResponse.entry(entry, res.routerOptions?.context));
}; };
}; };

View File

@ -82,11 +82,11 @@ _private.getEntriesTemplateHierarchy = function getEntriesTemplateHierarchy(rout
* @param {Object} postObject * @param {Object} postObject
* @returns {String[]} * @returns {String[]}
*/ */
_private.getEntryTemplateHierarchy = function getEntryTemplateHierarchy(postObject) { _private.getEntryTemplateHierarchy = function getEntryTemplateHierarchy(postObject, context) {
const templateList = ['post']; const templateList = ['post'];
let slugTemplate = 'post-' + postObject.slug; let slugTemplate = 'post-' + postObject.slug;
if (postObject.page) { if (context === 'page') {
templateList.unshift('page'); templateList.unshift('page');
slugTemplate = 'page-' + postObject.slug; slugTemplate = 'page-' + postObject.slug;
} }
@ -141,8 +141,14 @@ _private.pickTemplate = function pickTemplate(templateList, fallback) {
return template; return template;
}; };
_private.getTemplateForEntry = function getTemplateForEntry(postObject) { /**
const templateList = _private.getEntryTemplateHierarchy(postObject); *
* @param {Object} entry
* @param {('post'|'page')} context
* @returns
*/
_private.getTemplateForEntry = function getTemplateForEntry(entry, context) {
const templateList = _private.getEntryTemplateHierarchy(entry, context);
const fallback = templateList[templateList.length - 1]; const fallback = templateList[templateList.length - 1];
return _private.pickTemplate(templateList, fallback); return _private.pickTemplate(templateList, fallback);
}; };
@ -184,7 +190,11 @@ module.exports.setTemplate = function setTemplate(req, res, data) {
} else if (res.routerOptions.type === 'custom') { } else if (res.routerOptions.type === 'custom') {
res._template = _private.pickTemplate(res.routerOptions.templates, res.routerOptions.defaultTemplate); res._template = _private.pickTemplate(res.routerOptions.templates, res.routerOptions.defaultTemplate);
} else if (res.routerOptions.type === 'entry') { } else if (res.routerOptions.type === 'entry') {
res._template = _private.getTemplateForEntry(data.post); if (res.routerOptions?.context?.includes('page')) {
res._template = _private.getTemplateForEntry(data.page, 'page');
} else {
res._template = _private.getTemplateForEntry(data.post, 'post');
}
} else { } else {
res._template = 'index'; res._template = 'index';
} }

View File

@ -145,7 +145,11 @@ describe('{{body_class}} helper', function () {
it('a static page with custom template (is now the same as one without)', function () { it('a static page with custom template (is now the same as one without)', function () {
const rendered = callBodyClassWithContext( const rendered = callBodyClassWithContext(
['page'], ['page'],
{relativeUrl: '/about', post: {page: true, slug: 'about'}} {
relativeUrl: '/about',
post: {slug: 'about'},
page: {slug: 'about'}
}
); );
rendered.string.should.equal('page-template page-about'); rendered.string.should.equal('page-template page-about');

View File

@ -130,7 +130,7 @@ describe('templates', function () {
it('will fall back to post even if no index.hbs', function () { it('will fall back to post even if no index.hbs', function () {
hasTemplateStub.returns(false); hasTemplateStub.returns(false);
const view = _private.getTemplateForEntry({page: 1}); const view = _private.getTemplateForEntry({title: 'hey'}, 'page');
should.exist(view); should.exist(view);
view.should.eql('post'); view.should.eql('post');
}); });
@ -166,18 +166,16 @@ describe('templates', function () {
it('page without custom slug template', function () { it('page without custom slug template', function () {
const view = _private.getTemplateForEntry({ const view = _private.getTemplateForEntry({
page: 1,
slug: 'contact' slug: 'contact'
}); }, 'page');
should.exist(view); should.exist(view);
view.should.eql('page'); view.should.eql('page');
}); });
it('page with custom slug template', function () { it('page with custom slug template', function () {
const view = _private.getTemplateForEntry({ const view = _private.getTemplateForEntry({
page: 1,
slug: 'about' slug: 'about'
}); }, 'page');
should.exist(view); should.exist(view);
view.should.eql('page-about'); view.should.eql('page-about');
}); });
@ -219,9 +217,8 @@ describe('templates', function () {
hasTemplateStub.withArgs('custom-about').returns(false); hasTemplateStub.withArgs('custom-about').returns(false);
const view = _private.getTemplateForEntry({ const view = _private.getTemplateForEntry({
page: 1,
custom_template: 'custom-about' custom_template: 'custom-about'
}); }, 'page');
should.exist(view); should.exist(view);
view.should.eql('page'); view.should.eql('page');
}); });