From 5102637b8e23c0d33704406003a2a81d08752f37 Mon Sep 17 00:00:00 2001 From: cobbspur Date: Wed, 30 Mar 2016 10:41:41 +0100 Subject: [PATCH] Add structured data to static pages refs #6534 - adds structured data on static pages - selects post context object for static pages - updates tests --- core/server/data/meta/author_image.js | 8 +-- core/server/data/meta/context_object.js | 13 ++++ core/server/data/meta/cover_image.js | 6 +- core/server/data/meta/schema.js | 2 +- core/server/helpers/ghost_head.js | 2 +- .../test/unit/metadata/context_object_spec.js | 49 ++++++++++++++ .../unit/server_helpers/ghost_head_spec.js | 65 +++++++++++++++++-- 7 files changed, 132 insertions(+), 13 deletions(-) create mode 100644 core/server/data/meta/context_object.js create mode 100644 core/test/unit/metadata/context_object_spec.js diff --git a/core/server/data/meta/author_image.js b/core/server/data/meta/author_image.js index 0d057a941b..b55c8a6912 100644 --- a/core/server/data/meta/author_image.js +++ b/core/server/data/meta/author_image.js @@ -1,11 +1,11 @@ -var config = require('../../config'); +var config = require('../../config'), + getContextObject = require('./context_object.js'); function getAuthorImage(data, absolute) { var context = data.context ? data.context[0] : null, - blog = config.theme, - contextObject = data[context] || blog; + contextObject = getContextObject(data, context); - if (context === 'post' && contextObject.author && contextObject.author.image) { + if ((context === 'post' || context === 'page') && contextObject.author && contextObject.author.image) { return config.urlFor('image', {image: contextObject.author.image}, absolute); } return null; diff --git a/core/server/data/meta/context_object.js b/core/server/data/meta/context_object.js new file mode 100644 index 0000000000..5bbf9adf2e --- /dev/null +++ b/core/server/data/meta/context_object.js @@ -0,0 +1,13 @@ +var config = require('../../config'); + +function getContextObject(data, context) { + var blog = config.theme, + contextObject; + + context = context === 'page' ? 'post' : context; + contextObject = data[context] || blog; + + return contextObject; +} + +module.exports = getContextObject; diff --git a/core/server/data/meta/cover_image.js b/core/server/data/meta/cover_image.js index 203fc9d0b4..9748825cdd 100644 --- a/core/server/data/meta/cover_image.js +++ b/core/server/data/meta/cover_image.js @@ -1,9 +1,9 @@ -var config = require('../../config'); +var config = require('../../config'), + getContextObject = require('./context_object.js'); function getCoverImage(data) { var context = data.context ? data.context[0] : null, - blog = config.theme, - contextObject = data[context] || blog; + contextObject = getContextObject(data, context); if (context === 'home' || context === 'author') { if (contextObject.cover) { diff --git a/core/server/data/meta/schema.js b/core/server/data/meta/schema.js index 4f59b90dd7..83ee689205 100644 --- a/core/server/data/meta/schema.js +++ b/core/server/data/meta/schema.js @@ -97,7 +97,7 @@ function getAuthorSchema(metaData, data) { function getSchema(metaData, data) { if (!config.isPrivacyDisabled('useStructuredData')) { var context = data.context ? data.context[0] : null; - if (context === 'post') { + if (context === 'post' || context === 'page') { return getPostSchema(metaData, data); } else if (context === 'home') { return getHomeSchema(metaData); diff --git a/core/server/helpers/ghost_head.js b/core/server/helpers/ghost_head.js index dd25452424..ccf086c722 100644 --- a/core/server/helpers/ghost_head.js +++ b/core/server/helpers/ghost_head.js @@ -98,7 +98,7 @@ function ghost_head(options) { escapeExpression(metaData.nextUrl) + '" />'); } - if (context !== 'paged' && context !== 'page' && useStructuredData) { + if (context !== 'paged' && useStructuredData) { head.push(''); head.push.apply(head, finaliseStructuredData(metaData)); head.push(''); diff --git a/core/test/unit/metadata/context_object_spec.js b/core/test/unit/metadata/context_object_spec.js new file mode 100644 index 0000000000..66266bac18 --- /dev/null +++ b/core/test/unit/metadata/context_object_spec.js @@ -0,0 +1,49 @@ +/*globals describe, it, before, after */ +var should = require('should'), + getContextObject = require('../../../server/data/meta/context_object.js'), + configUtils = require('../../utils/configUtils'); + +describe('getContextObject', function () { + var data, context, contextObject; + + it('should be a function', function () { + should.exist(getContextObject); + }); + + it('should return post context object for a post', function () { + data = {post: {id: 2}}; + context = 'post'; + contextObject = getContextObject(data, context); + + should.exist(contextObject); + contextObject.should.eql(data.post); + }); + + it('should return post context object for a static page', function () { + data = {post: {id: 2}}; + context = 'page'; + contextObject = getContextObject(data, context); + + should.exist(contextObject); + contextObject.should.eql(data.post); + }); + + describe('override blog', function () { + before(function () { + configUtils.set({theme: {foo: 'bar'}}); + }); + + after(function () { + configUtils.restore(); + }); + + it('should return blog context object for unknown context', function () { + data = {post: {id: 2}}; + context = 'unknown'; + contextObject = getContextObject(data, context); + + should.exist(contextObject); + contextObject.should.have.property('foo', 'bar'); + }); + }); +}); diff --git a/core/test/unit/server_helpers/ghost_head_spec.js b/core/test/unit/server_helpers/ghost_head_spec.js index 1dc3a610c0..b18b848ebb 100644 --- a/core/test/unit/server_helpers/ghost_head_spec.js +++ b/core/test/unit/server_helpers/ghost_head_spec.js @@ -110,6 +110,57 @@ describe('{{ghost_head}} helper', function () { }).catch(done); }); + it('returns structured data on static page', function (done) { + var post = { + meta_description: 'all about our blog', + title: 'About', + image: '/content/images/test-image-about.png', + published_at: moment('2008-05-31T19:18:15').toISOString(), + updated_at: moment('2014-10-06T15:23:54').toISOString(), + page: true, + author: { + name: 'Author name', + url: 'http://testauthorurl.com', + slug: 'Author', + image: '/content/images/test-author-image.png', + website: 'http://authorwebsite.com', + bio: 'Author bio' + } + }; + + helpers.ghost_head.call( + {safeVersion: '0.3', relativeUrl: '/about/', context: ['page'], post: post}, + {data: {root: {context: ['page']}}} + ).then(function (rendered) { + should.exist(rendered); + rendered.string.should.match(//); + rendered.string.should.match(//); + rendered.string.should.match(//); + rendered.string.should.match(//); + rendered.string.should.match(//); + rendered.string.should.match(//); + rendered.string.should.match(//); + rendered.string.should.match(//); + rendered.string.should.match(//); + rendered.string.should.match(//); + rendered.string.should.match(//); + rendered.string.should.match(//); + rendered.string.should.match(//); + rendered.string.should.match(//); + rendered.string.should.match(//); + rendered.string.should.match(/