0
Fork 0
mirror of https://github.com/TryGhost/Ghost.git synced 2025-03-11 02:12:21 -05:00

🐛 Fixed structured data issue for publisher logo (#11826)

closes #11304

- Google requires an `ImageObject` to be always returned for `publisher.logo` (https://developers.google.com/search/docs/data-types/article)
- The previous fix 3f5daa60c8 added a second nested `url` error and got therefore reverted with 7ac614030d
- This commit updates the image object generation fn to **always** return an `ImageObject` with minimum of `url` and `@type` properties. If dimensions are available, we'll pass those in there as well
This commit is contained in:
Aileen Nowak 2020-05-20 18:16:20 +12:00 committed by GitHub
parent 2d41e5cc88
commit 86ab62704b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 38 additions and 29 deletions

View file

@ -5,20 +5,20 @@ const _ = require('lodash');
function schemaImageObject(metaDataVal) { function schemaImageObject(metaDataVal) {
let imageObject; let imageObject;
if (!metaDataVal) { if (!metaDataVal || !metaDataVal.url) {
return null; return null;
} }
if (!metaDataVal.dimensions) {
return metaDataVal.url;
}
imageObject = { imageObject = {
'@type': 'ImageObject', '@type': 'ImageObject',
url: metaDataVal.url, url: metaDataVal.url
width: metaDataVal.dimensions.width,
height: metaDataVal.dimensions.height
}; };
if (metaDataVal.dimensions) {
imageObject.width = metaDataVal.dimensions.width;
imageObject.height = metaDataVal.dimensions.height;
}
return imageObject; return imageObject;
} }

View file

@ -430,7 +430,10 @@ describe('getSchema', function () {
author: { author: {
'@type': 'Person', '@type': 'Person',
description: 'My author bio.', description: 'My author bio.',
image: 'http://mysite.com/author/image/url/me.jpg', image: {
'@type': 'ImageObject',
url: 'http://mysite.com/author/image/url/me.jpg'
},
name: 'Post Author', name: 'Post Author',
sameAs: [ sameAs: [
'http://myblogsite.com/', 'http://myblogsite.com/',
@ -443,7 +446,10 @@ describe('getSchema', function () {
datePublished: '2015-12-25T05:35:01.234Z', datePublished: '2015-12-25T05:35:01.234Z',
description: 'Post meta description', description: 'Post meta description',
headline: 'Post Title', headline: 'Post Title',
image: 'http://mysite.com/content/image/mypostcoverimage.jpg', image: {
'@type': 'ImageObject',
url: 'http://mysite.com/content/image/mypostcoverimage.jpg'
},
keywords: 'one, two, tag', keywords: 'one, two, tag',
mainEntityOfPage: { mainEntityOfPage: {
'@type': 'WebPage', '@type': 'WebPage',
@ -453,7 +459,10 @@ describe('getSchema', function () {
'@type': 'Organization', '@type': 'Organization',
name: 'Site Title', name: 'Site Title',
url: 'http://mysite.com', url: 'http://mysite.com',
logo: 'http://mysite.com/author/image/url/logo.jpg' logo: {
'@type': 'ImageObject',
url: 'http://mysite.com/author/image/url/logo.jpg'
}
}, },
url: 'http://mysite.com/post/my-post-slug/' url: 'http://mysite.com/post/my-post-slug/'
}); });

View file

@ -371,7 +371,7 @@ describe('{{ghost_head}} helper', function () {
rendered.string.should.match(/"@type": "WebSite"/); rendered.string.should.match(/"@type": "WebSite"/);
rendered.string.should.match(/"publisher": {\n "@type": "Organization",\n "name": "Ghost",/); rendered.string.should.match(/"publisher": {\n "@type": "Organization",\n "name": "Ghost",/);
rendered.string.should.match(/"url": "http:\/\/localhost:65530\/"/); rendered.string.should.match(/"url": "http:\/\/localhost:65530\/"/);
rendered.string.should.match(/"image": "http:\/\/localhost:65530\/content\/images\/site-cover.png"/); rendered.string.should.match(/"image": {\n "@type": "ImageObject",\n "url": "http:\/\/localhost:65530\/content\/images\/site-cover.png"\n/);
rendered.string.should.match(/"description": "site description"/); rendered.string.should.match(/"description": "site description"/);
done(); done();
@ -419,7 +419,7 @@ describe('{{ghost_head}} helper', function () {
rendered.string.should.match(/"@type": "WebSite"/); rendered.string.should.match(/"@type": "WebSite"/);
rendered.string.should.match(/"publisher": {\n "@type": "Organization",\n "name": "Ghost",/); rendered.string.should.match(/"publisher": {\n "@type": "Organization",\n "name": "Ghost",/);
rendered.string.should.match(/"url": "http:\/\/localhost:65530\/"/); rendered.string.should.match(/"url": "http:\/\/localhost:65530\/"/);
rendered.string.should.match(/"image": "http:\/\/localhost:65530\/content\/images\/site-cover.png"/); rendered.string.should.match(/"image": {\n "@type": "ImageObject",\n "url": "http:\/\/localhost:65530\/content\/images\/site-cover.png"\n/);
rendered.string.should.match(/"description": "site SEO description"/); rendered.string.should.match(/"description": "site SEO description"/);
done(); done();
@ -467,8 +467,8 @@ describe('{{ghost_head}} helper', function () {
rendered.string.should.match(/"name": "Ghost"/); rendered.string.should.match(/"name": "Ghost"/);
rendered.string.should.match(/"url": "http:\/\/localhost:65530\/about\/"/); rendered.string.should.match(/"url": "http:\/\/localhost:65530\/about\/"/);
rendered.string.should.match(/"sameAs": \[\n "http:\/\/authorwebsite.com",\n "https:\/\/www.facebook.com\/testuser",\n "https:\/\/twitter.com\/testuser"\n \]/); rendered.string.should.match(/"sameAs": \[\n "http:\/\/authorwebsite.com",\n "https:\/\/www.facebook.com\/testuser",\n "https:\/\/twitter.com\/testuser"\n \]/);
rendered.string.should.match(/"image": "http:\/\/localhost:65530\/content\/images\/test-image-about.png"/); rendered.string.should.match(/"image": {\n "@type": "ImageObject",\n "url": "http:\/\/localhost:65530\/content\/images\/test-image-about.png"\n/);
rendered.string.should.match(/"image\": \"http:\/\/localhost:65530\/content\/images\/test-author-image.png\"/); rendered.string.should.match(/"image": {\n "@type": "ImageObject",\n "url": "http:\/\/localhost:65530\/content\/images\/test-author-image.png"\n/);
rendered.string.should.match(/"description": "all about our site"/); rendered.string.should.match(/"description": "all about our site"/);
done(); done();
@ -516,8 +516,8 @@ describe('{{ghost_head}} helper', function () {
rendered.string.should.match(/"name": "Ghost"/); rendered.string.should.match(/"name": "Ghost"/);
rendered.string.should.match(/"url": "http:\/\/localhost:65530\/about\/"/); rendered.string.should.match(/"url": "http:\/\/localhost:65530\/about\/"/);
rendered.string.should.match(/"sameAs": \[\n "http:\/\/authorwebsite.com",\n "https:\/\/www.facebook.com\/testuser",\n "https:\/\/twitter.com\/testuser"\n \]/); rendered.string.should.match(/"sameAs": \[\n "http:\/\/authorwebsite.com",\n "https:\/\/www.facebook.com\/testuser",\n "https:\/\/twitter.com\/testuser"\n \]/);
rendered.string.should.match(/"image": "http:\/\/localhost:65530\/content\/images\/test-image-about.png"/); rendered.string.should.match(/"image": {\n "@type": "ImageObject",\n "url": "http:\/\/localhost:65530\/content\/images\/test-image-about.png"/);
rendered.string.should.match(/"image\": \"http:\/\/localhost:65530\/content\/images\/test-author-image.png\"/); rendered.string.should.match(/"image": {\n "@type": "ImageObject",\n "url": "http:\/\/localhost:65530\/content\/images\/test-author-image.png"\n/);
rendered.string.should.match(/"description": "all about our site"/); rendered.string.should.match(/"description": "all about our site"/);
done(); done();
@ -574,7 +574,7 @@ describe('{{ghost_head}} helper', function () {
rendered.string.should.match(/"author": {/); rendered.string.should.match(/"author": {/);
rendered.string.should.match(/"@type": "Person"/); rendered.string.should.match(/"@type": "Person"/);
rendered.string.should.match(/"name": "Author name"/); rendered.string.should.match(/"name": "Author name"/);
rendered.string.should.match(/"image\": \"http:\/\/localhost:65530\/content\/images\/test-author-image.png\"/); rendered.string.should.match(/"image": {\n "@type": "ImageObject",\n "url": "http:\/\/localhost:65530\/content\/images\/test-author-image.png"\n/);
rendered.string.should.match(/"url": "https:\/\/mysite.com\/fakeauthor\/"/); rendered.string.should.match(/"url": "https:\/\/mysite.com\/fakeauthor\/"/);
rendered.string.should.match(/"sameAs": \[\n "http:\/\/authorwebsite.com",\n "https:\/\/www.facebook.com\/testuser",\n "https:\/\/twitter.com\/testuser"\n \]/); rendered.string.should.match(/"sameAs": \[\n "http:\/\/authorwebsite.com",\n "https:\/\/www.facebook.com\/testuser",\n "https:\/\/twitter.com\/testuser"\n \]/);
rendered.string.should.not.match(/"description": "Author bio"/); rendered.string.should.not.match(/"description": "Author bio"/);
@ -582,7 +582,7 @@ describe('{{ghost_head}} helper', function () {
rendered.string.should.match(/"url": "http:\/\/localhost:65530\/post\/"/); rendered.string.should.match(/"url": "http:\/\/localhost:65530\/post\/"/);
rendered.string.should.match(re3); rendered.string.should.match(re3);
rendered.string.should.match(re4); rendered.string.should.match(re4);
rendered.string.should.match(/"image": "http:\/\/localhost:65530\/content\/images\/test-image.png"/); rendered.string.should.match(/"image": {\n "@type": "ImageObject",\n "url": "http:\/\/localhost:65530\/content\/images\/test-image.png"\n/);
rendered.string.should.match(/"keywords": "tag1, tag2, tag3"/); rendered.string.should.match(/"keywords": "tag1, tag2, tag3"/);
rendered.string.should.match(/"description": "site description"/); rendered.string.should.match(/"description": "site description"/);
rendered.string.should.match(/"@context": "https:\/\/schema.org"/); rendered.string.should.match(/"@context": "https:\/\/schema.org"/);
@ -638,13 +638,13 @@ describe('{{ghost_head}} helper', function () {
rendered.string.should.match(/"author": {/); rendered.string.should.match(/"author": {/);
rendered.string.should.match(/"@type": "Person"/); rendered.string.should.match(/"@type": "Person"/);
rendered.string.should.match(/"name": "Author name"/); rendered.string.should.match(/"name": "Author name"/);
rendered.string.should.match(/"image\": \"http:\/\/localhost:65530\/content\/images\/test-author-image.png\"/); rendered.string.should.match(/"image": {\n "@type": "ImageObject",\n "url": "http:\/\/localhost:65530\/content\/images\/test-author-image.png"/);
rendered.string.should.match(/"url": "https:\/\/mysite.com\/fakeauthor\/"/); rendered.string.should.match(/"url": "https:\/\/mysite.com\/fakeauthor\/"/);
rendered.string.should.match(/"sameAs": \[\n "http:\/\/authorwebsite.com",\n "https:\/\/www.facebook.com\/testuser",\n "https:\/\/twitter.com\/testuser"\n \]/); rendered.string.should.match(/"sameAs": \[\n "http:\/\/authorwebsite.com",\n "https:\/\/www.facebook.com\/testuser",\n "https:\/\/twitter.com\/testuser"\n \]/);
rendered.string.should.not.match(/"description": "Author bio"/); rendered.string.should.not.match(/"description": "Author bio"/);
rendered.string.should.match(/"headline": "Welcome to Ghost"/); rendered.string.should.match(/"headline": "Welcome to Ghost"/);
rendered.string.should.match(/"url": "http:\/\/localhost:65530\/post\/"/); rendered.string.should.match(/"url": "http:\/\/localhost:65530\/post\/"/);
rendered.string.should.match(/"image": "http:\/\/localhost:65530\/content\/images\/test-image.png"/); rendered.string.should.match(/"image": {\n "@type": "ImageObject",\n "url": "http:\/\/localhost:65530\/content\/images\/test-image.png"/);
rendered.string.should.match(/"keywords": "tag1, tag2, tag3"/); rendered.string.should.match(/"keywords": "tag1, tag2, tag3"/);
rendered.string.should.match(/"description": "post custom excerpt"/); rendered.string.should.match(/"description": "post custom excerpt"/);
rendered.string.should.match(/"@context": "https:\/\/schema.org"/); rendered.string.should.match(/"@context": "https:\/\/schema.org"/);
@ -751,13 +751,13 @@ describe('{{ghost_head}} helper', function () {
rendered.string.should.match(/"author": {/); rendered.string.should.match(/"author": {/);
rendered.string.should.match(/"@type": "Person"/); rendered.string.should.match(/"@type": "Person"/);
rendered.string.should.match(/"name": "Author name"/); rendered.string.should.match(/"name": "Author name"/);
rendered.string.should.match(/"image\": \"http:\/\/localhost:65530\/content\/images\/test-author-image.png\"/); rendered.string.should.match(/"image": {\n "@type": "ImageObject",\n "url": "http:\/\/localhost:65530\/content\/images\/test-author-image.png"/);
rendered.string.should.match(/"url": "https:\/\/mysite.com\/fakeauthor\/"/); rendered.string.should.match(/"url": "https:\/\/mysite.com\/fakeauthor\/"/);
rendered.string.should.match(/"sameAs": \[\n "http:\/\/authorwebsite.com",\n "https:\/\/www.facebook.com\/testuser",\n "https:\/\/twitter.com\/testuser"\n \]/); rendered.string.should.match(/"sameAs": \[\n "http:\/\/authorwebsite.com",\n "https:\/\/www.facebook.com\/testuser",\n "https:\/\/twitter.com\/testuser"\n \]/);
rendered.string.should.not.match(/"description": "Author bio"/); rendered.string.should.not.match(/"description": "Author bio"/);
rendered.string.should.match(/"headline": "Welcome to Ghost"/); rendered.string.should.match(/"headline": "Welcome to Ghost"/);
rendered.string.should.match(/"url": "http:\/\/localhost:65530\/post\/"/); rendered.string.should.match(/"url": "http:\/\/localhost:65530\/post\/"/);
rendered.string.should.match(/"image": "http:\/\/localhost:65530\/content\/images\/test-image.png"/); rendered.string.should.match(/"image": {\n "@type": "ImageObject",\n "url": "http:\/\/localhost:65530\/content\/images\/test-image.png"/);
rendered.string.should.match(/"keywords": "tag1, tag2, tag3"/); rendered.string.should.match(/"keywords": "tag1, tag2, tag3"/);
rendered.string.should.match(/"description": "site description"/); rendered.string.should.match(/"description": "site description"/);
rendered.string.should.match(/"@context": "https:\/\/schema.org"/); rendered.string.should.match(/"@context": "https:\/\/schema.org"/);
@ -813,13 +813,13 @@ describe('{{ghost_head}} helper', function () {
rendered.string.should.match(/"author": {/); rendered.string.should.match(/"author": {/);
rendered.string.should.match(/"@type": "Person"/); rendered.string.should.match(/"@type": "Person"/);
rendered.string.should.match(/"name": "Author name"/); rendered.string.should.match(/"name": "Author name"/);
rendered.string.should.match(/"image\": \"http:\/\/localhost:65530\/content\/images\/test-author-image.png\"/); rendered.string.should.match(/"image": {\n "@type": "ImageObject",\n "url": "http:\/\/localhost:65530\/content\/images\/test-author-image.png"/);
rendered.string.should.match(/"url": "https:\/\/mysite.com\/fakeauthor\/"/); rendered.string.should.match(/"url": "https:\/\/mysite.com\/fakeauthor\/"/);
rendered.string.should.match(/"sameAs": \[\n "http:\/\/authorwebsite.com",\n "https:\/\/www.facebook.com\/testuser",\n "https:\/\/twitter.com\/testuser"\n \]/); rendered.string.should.match(/"sameAs": \[\n "http:\/\/authorwebsite.com",\n "https:\/\/www.facebook.com\/testuser",\n "https:\/\/twitter.com\/testuser"\n \]/);
rendered.string.should.match(/"headline": "Welcome to Ghost "test""/); rendered.string.should.match(/"headline": "Welcome to Ghost "test""/);
rendered.string.should.match(/"url": "http:\/\/localhost:65530\/post\/"/); rendered.string.should.match(/"url": "http:\/\/localhost:65530\/post\/"/);
rendered.string.should.match(/"@context": "https:\/\/schema.org"/); rendered.string.should.match(/"@context": "https:\/\/schema.org"/);
rendered.string.should.match(/"image": "http:\/\/localhost:65530\/content\/images\/test-image.png"/); rendered.string.should.match(/"image": {\n "@type": "ImageObject",\n "url": "http:\/\/localhost:65530\/content\/images\/test-image.png"/);
rendered.string.should.match(/"keywords": "tag1, tag2, tag3"/); rendered.string.should.match(/"keywords": "tag1, tag2, tag3"/);
rendered.string.should.match(/"description": "site "test" description"/); rendered.string.should.match(/"description": "site "test" description"/);
rendered.string.should.match(/"@context": "https:\/\/schema.org"/); rendered.string.should.match(/"@context": "https:\/\/schema.org"/);
@ -870,13 +870,13 @@ describe('{{ghost_head}} helper', function () {
rendered.string.should.match(/"author": {/); rendered.string.should.match(/"author": {/);
rendered.string.should.match(/"@type": "Person"/); rendered.string.should.match(/"@type": "Person"/);
rendered.string.should.match(/"name": "Author name"/); rendered.string.should.match(/"name": "Author name"/);
rendered.string.should.match(/"image\": \"http:\/\/localhost:65530\/content\/images\/test-author-image.png\"/); rendered.string.should.match(/"image": {\n "@type": "ImageObject",\n "url": "http:\/\/localhost:65530\/content\/images\/test-author-image.png"/);
rendered.string.should.match(/"url": "https:\/\/mysite.com\/fakeauthor\/"/); rendered.string.should.match(/"url": "https:\/\/mysite.com\/fakeauthor\/"/);
rendered.string.should.match(/"sameAs": \[\n "http:\/\/authorwebsite.com",\n "https:\/\/www.facebook.com\/testuser",\n "https:\/\/twitter.com\/testuser"\n \]/); rendered.string.should.match(/"sameAs": \[\n "http:\/\/authorwebsite.com",\n "https:\/\/www.facebook.com\/testuser",\n "https:\/\/twitter.com\/testuser"\n \]/);
rendered.string.should.match(/"headline": "Welcome to Ghost"/); rendered.string.should.match(/"headline": "Welcome to Ghost"/);
rendered.string.should.match(/"url": "http:\/\/localhost:65530\/post\/"/); rendered.string.should.match(/"url": "http:\/\/localhost:65530\/post\/"/);
rendered.string.should.match(/"@context": "https:\/\/schema.org"/); rendered.string.should.match(/"@context": "https:\/\/schema.org"/);
rendered.string.should.match(/"image": "http:\/\/localhost:65530\/content\/images\/test-image.png"/); rendered.string.should.match(/"image": {\n "@type": "ImageObject",\n "url": "http:\/\/localhost:65530\/content\/images\/test-image.png"/);
rendered.string.should.not.match(/"keywords":/); rendered.string.should.not.match(/"keywords":/);
rendered.string.should.match(/"description": "site description"/); rendered.string.should.match(/"description": "site description"/);
rendered.string.should.match(/"@context": "https:\/\/schema.org"/); rendered.string.should.match(/"@context": "https:\/\/schema.org"/);
@ -1077,7 +1077,7 @@ describe('{{ghost_head}} helper', function () {
rendered.string.should.match(/"@type": "Series"/); rendered.string.should.match(/"@type": "Series"/);
rendered.string.should.match(/"publisher": {\n "@type": "Organization",\n "name": "Ghost",/); rendered.string.should.match(/"publisher": {\n "@type": "Organization",\n "name": "Ghost",/);
rendered.string.should.match(/"url": "http:\/\/localhost:65530\/tag\/tagtitle\/"/); rendered.string.should.match(/"url": "http:\/\/localhost:65530\/tag\/tagtitle\/"/);
rendered.string.should.match(/"image": "http:\/\/localhost:65530\/content\/images\/tag-image.png"/); rendered.string.should.match(/"image": {\n "@type": "ImageObject",\n "url": "http:\/\/localhost:65530\/content\/images\/tag-image.png"/);
rendered.string.should.match(/"name": "tagtitle"/); rendered.string.should.match(/"name": "tagtitle"/);
rendered.string.should.match(/"description": "tag meta description"/); rendered.string.should.match(/"description": "tag meta description"/);
@ -1120,7 +1120,7 @@ describe('{{ghost_head}} helper', function () {
rendered.string.should.match(/"@type": "Series"/); rendered.string.should.match(/"@type": "Series"/);
rendered.string.should.match(/"publisher": {\n "@type": "Organization",\n "name": "Ghost",/); rendered.string.should.match(/"publisher": {\n "@type": "Organization",\n "name": "Ghost",/);
rendered.string.should.match(/"url": "http:\/\/localhost:65530\/tag\/tagtitle\/"/); rendered.string.should.match(/"url": "http:\/\/localhost:65530\/tag\/tagtitle\/"/);
rendered.string.should.match(/"image": "http:\/\/localhost:65530\/content\/images\/tag-image.png"/); rendered.string.should.match(/"image": {\n "@type": "ImageObject",\n "url": "http:\/\/localhost:65530\/content\/images\/tag-image.png"/);
rendered.string.should.match(/"name": "tagtitle"/); rendered.string.should.match(/"name": "tagtitle"/);
done(); done();
@ -1210,7 +1210,7 @@ describe('{{ghost_head}} helper', function () {
rendered.string.should.match(/"@type": "Person"/); rendered.string.should.match(/"@type": "Person"/);
rendered.string.should.match(/"sameAs": \[\n "http:\/\/authorwebsite.com",\n "https:\/\/www.facebook.com\/testuser",\n "https:\/\/twitter.com\/testuser"\n \]/); rendered.string.should.match(/"sameAs": \[\n "http:\/\/authorwebsite.com",\n "https:\/\/www.facebook.com\/testuser",\n "https:\/\/twitter.com\/testuser"\n \]/);
rendered.string.should.match(/"url": "https:\/\/mysite.com\/fakeauthor\/"/); rendered.string.should.match(/"url": "https:\/\/mysite.com\/fakeauthor\/"/);
rendered.string.should.match(/"image": "http:\/\/localhost:65530\/content\/images\/author-cover-image.png"/); rendered.string.should.match(/"image": {\n "@type": "ImageObject",\n "url": "http:\/\/localhost:65530\/content\/images\/author-cover-image.png"/);
rendered.string.should.match(/"name": "Author name"/); rendered.string.should.match(/"name": "Author name"/);
done(); done();