mirror of
https://github.com/TryGhost/Ghost.git
synced 2024-12-01 13:54:35 +03:00
Merge pull request #4332 from cobbspur/escape
Escape meta title and description
This commit is contained in:
commit
c0375d4087
@ -34,7 +34,8 @@ ghost_head = function (options) {
|
||||
ops = [],
|
||||
structuredData,
|
||||
coverImage, authorImage, keywords,
|
||||
schema;
|
||||
schema,
|
||||
title = hbs.handlebars.Utils.escapeExpression(blog.title);
|
||||
|
||||
trimmedVersion = trimmedVersion ? trimmedVersion.match(majorMinor)[0] : '?';
|
||||
// Push Async calls to an array of promises
|
||||
@ -49,13 +50,14 @@ ghost_head = function (options) {
|
||||
metaTitle = results[2].value(),
|
||||
publishedDate, modifiedDate,
|
||||
tags = tagsHelper.call(self.post, {hash: {autolink: 'false'}}).string.split(','),
|
||||
card = 'summary';
|
||||
card = 'summary',
|
||||
type, authorUrl;
|
||||
|
||||
if (!metaDescription) {
|
||||
metaDescription = excerpt.call(self.post, {hash: {words: '40'}}).string;
|
||||
}
|
||||
if (tags[0] !== '') {
|
||||
keywords = tagsHelper.call(self.post, {hash: {autolink: 'false', seperator: ', '}}).string;
|
||||
keywords = hbs.handlebars.Utils.escapeExpression(tagsHelper.call(self.post, {hash: {autolink: 'false', seperator: ', '}}).string);
|
||||
}
|
||||
head.push('<link rel="canonical" href="' + url + '" />');
|
||||
|
||||
@ -81,25 +83,30 @@ ghost_head = function (options) {
|
||||
if (self.post.image) {
|
||||
coverImage = self.post.image;
|
||||
// Test to see if image was linked by url or uploaded
|
||||
coverImage = coverImage.substring(0, 4) === 'http' ? coverImage : _.escape(blog.url) + coverImage;
|
||||
coverImage = coverImage.substring(0, 4) === 'http' ? coverImage : hbs.handlebars.Utils.escapeExpression(blog.url + coverImage);
|
||||
card = 'summary_large_image';
|
||||
}
|
||||
|
||||
if (self.post.author.image) {
|
||||
authorImage = self.post.author.image;
|
||||
// Test to see if image was linked by url or uploaded
|
||||
authorImage = authorImage.substring(0, 4) === 'http' ? authorImage : _.escape(blog.url) + authorImage;
|
||||
authorImage = authorImage.substring(0, 4) === 'http' ? authorImage : hbs.handlebars.Utils.escapeExpression(blog.url + authorImage);
|
||||
}
|
||||
|
||||
// escaped data
|
||||
metaTitle = hbs.handlebars.Utils.escapeExpression(metaTitle);
|
||||
metaDescription = hbs.handlebars.Utils.escapeExpression(metaDescription + '...');
|
||||
authorUrl = hbs.handlebars.Utils.escapeExpression(blog.url + '/author/' + self.post.author.slug);
|
||||
|
||||
schema = {
|
||||
'@context': 'http://schema.org',
|
||||
'@type': 'Article',
|
||||
publisher: _.escape(blog.title),
|
||||
publisher: title,
|
||||
author: {
|
||||
'@type': 'Person',
|
||||
name: self.post.author.name,
|
||||
image: authorImage,
|
||||
url: _.escape(blog.url) + '/author/' + self.post.author.slug,
|
||||
url: authorUrl,
|
||||
sameAs: self.post.author.website
|
||||
},
|
||||
headline: metaTitle,
|
||||
@ -112,10 +119,10 @@ ghost_head = function (options) {
|
||||
};
|
||||
|
||||
structuredData = {
|
||||
'og:site_name': _.escape(blog.title),
|
||||
'og:site_name': title,
|
||||
'og:type': 'article',
|
||||
'og:title': metaTitle,
|
||||
'og:description': metaDescription + '...',
|
||||
'og:description': metaDescription,
|
||||
'og:url': url,
|
||||
'og:image': coverImage,
|
||||
'article:published_time': publishedDate,
|
||||
@ -123,7 +130,7 @@ ghost_head = function (options) {
|
||||
'article:tag': tags,
|
||||
'twitter:card': card,
|
||||
'twitter:title': metaTitle,
|
||||
'twitter:description': metaDescription + '...',
|
||||
'twitter:description': metaDescription,
|
||||
'twitter:url': url,
|
||||
'twitter:image:src': coverImage
|
||||
};
|
||||
@ -132,16 +139,14 @@ ghost_head = function (options) {
|
||||
if (property === 'article:tag') {
|
||||
_.each(tags, function (tag) {
|
||||
if (tag !== '') {
|
||||
head.push('<meta property="' + property + '" content="' + tag.trim() + '" />');
|
||||
tag = hbs.handlebars.Utils.escapeExpression(tag.trim());
|
||||
head.push('<meta property="' + property + '" content="' + tag + '" />');
|
||||
}
|
||||
});
|
||||
head.push('');
|
||||
} else if (content !== null && content !== undefined) {
|
||||
if (property.substring(0, 7) === 'twitter') {
|
||||
head.push('<meta name="' + property + '" content="' + content + '" />');
|
||||
} else {
|
||||
head.push('<meta property="' + property + '" content="' + content + '" />');
|
||||
}
|
||||
type = property.substring(0, 7) === 'twitter' ? 'name' : 'property';
|
||||
head.push('<meta ' + type + '="' + property + '" content="' + content + '" />');
|
||||
}
|
||||
});
|
||||
head.push('');
|
||||
@ -150,7 +155,7 @@ ghost_head = function (options) {
|
||||
|
||||
head.push('<meta name="generator" content="Ghost ' + trimmedVersion + '" />');
|
||||
head.push('<link rel="alternate" type="application/rss+xml" title="' +
|
||||
_.escape(blog.title) + '" href="' + config.urlFor('rss') + '" />');
|
||||
title + '" href="' + config.urlFor('rss') + '" />');
|
||||
return filters.doFilter('ghost_head', head);
|
||||
}).then(function (head) {
|
||||
var headString = _.reduce(head, function (memo, item) { return memo + '\n ' + item; }, '');
|
||||
|
@ -94,7 +94,7 @@ describe('{{ghost_head}} helper', function () {
|
||||
'},\n "headline": "Welcome to Ghost",\n "url": "http://testurl.com/post/",\n' +
|
||||
' "datePublished": "' + post.published_at + '",\n "dateModified": "' + post.updated_at + '",\n' +
|
||||
' "image": "http://testurl.com/test-image.png",\n "keywords": "tag1, tag2, tag3",\n' +
|
||||
' "description": "blog description"\n}\n </script>\n\n' +
|
||||
' "description": "blog description..."\n}\n </script>\n\n' +
|
||||
' <meta name="generator" content="Ghost 0.3" />\n' +
|
||||
' <link rel="alternate" type="application/rss+xml" title="Ghost" href="/rss/" />');
|
||||
|
||||
@ -102,7 +102,60 @@ describe('{{ghost_head}} helper', function () {
|
||||
}).catch(done);
|
||||
});
|
||||
|
||||
it('returns structured without tags if there are no tags', function (done) {
|
||||
it('returns structured data if metaTitle and metaDescription have double quotes', function (done) {
|
||||
var post = {
|
||||
meta_description: 'blog "test" description',
|
||||
title: 'title',
|
||||
meta_title: 'Welcome to Ghost "test"',
|
||||
image: '/test-image.png',
|
||||
published_at: moment('2008-05-31T19:18:15').toISOString(),
|
||||
updated_at: moment('2014-10-06T15:23:54').toISOString(),
|
||||
tags: [{name: 'tag1'}, {name: 'tag2'}, {name: 'tag3'}],
|
||||
author: {
|
||||
name: 'Author name',
|
||||
url: 'http//:testauthorurl.com',
|
||||
slug: 'Author',
|
||||
image: '/test-author-image.png',
|
||||
website: 'http://authorwebsite.com'
|
||||
}
|
||||
};
|
||||
|
||||
helpers.ghost_head.call({relativeUrl: '/post/', version: '0.3.0', post: post}).then(function (rendered) {
|
||||
should.exist(rendered);
|
||||
rendered.string.should.equal('<link rel="canonical" href="http://testurl.com/post/" />\n \n' +
|
||||
' <meta property="og:site_name" content="Ghost" />\n' +
|
||||
' <meta property="og:type" content="article" />\n' +
|
||||
' <meta property="og:title" content="Welcome to Ghost "test"" />\n' +
|
||||
' <meta property="og:description" content="blog "test" description..." />\n' +
|
||||
' <meta property="og:url" content="http://testurl.com/post/" />\n' +
|
||||
' <meta property="og:image" content="http://testurl.com/test-image.png" />\n' +
|
||||
' <meta property="article:published_time" content="' + post.published_at + '" />\n' +
|
||||
' <meta property="article:modified_time" content="' + post.updated_at + '" />\n' +
|
||||
' <meta property="article:tag" content="tag1" />\n' +
|
||||
' <meta property="article:tag" content="tag2" />\n' +
|
||||
' <meta property="article:tag" content="tag3" />\n \n' +
|
||||
' <meta name="twitter:card" content="summary_large_image" />\n' +
|
||||
' <meta name="twitter:title" content="Welcome to Ghost "test"" />\n' +
|
||||
' <meta name="twitter:description" content="blog "test" description..." />\n' +
|
||||
' <meta name="twitter:url" content="http://testurl.com/post/" />\n' +
|
||||
' <meta name="twitter:image:src" content="http://testurl.com/test-image.png" />\n \n' +
|
||||
' <script type=\"application/ld+json\">\n{\n' +
|
||||
' "@context": "http://schema.org",\n "@type": "Article",\n "publisher": "Ghost",\n' +
|
||||
' "author": {\n "@type": "Person",\n "name": "Author name",\n ' +
|
||||
' \"image\": \"http://testurl.com/test-author-image.png\",\n ' +
|
||||
' "url": "http://testurl.com/author/Author",\n "sameAs": "http://authorwebsite.com"\n ' +
|
||||
'},\n "headline": "Welcome to Ghost "test"",\n "url": "http://testurl.com/post/",\n' +
|
||||
' "datePublished": "' + post.published_at + '",\n "dateModified": "' + post.updated_at + '",\n' +
|
||||
' "image": "http://testurl.com/test-image.png",\n "keywords": "tag1, tag2, tag3",\n' +
|
||||
' "description": "blog "test" description..."\n}\n </script>\n\n' +
|
||||
' <meta name="generator" content="Ghost 0.3" />\n' +
|
||||
' <link rel="alternate" type="application/rss+xml" title="Ghost" href="/rss/" />');
|
||||
|
||||
done();
|
||||
}).catch(done);
|
||||
});
|
||||
|
||||
it('returns structured data without tags if there are no tags', function (done) {
|
||||
var post = {
|
||||
meta_description: 'blog description',
|
||||
title: 'Welcome to Ghost',
|
||||
@ -143,7 +196,7 @@ describe('{{ghost_head}} helper', function () {
|
||||
'},\n "headline": "Welcome to Ghost",\n "url": "http://testurl.com/post/",\n' +
|
||||
' "datePublished": "' + post.published_at + '",\n "dateModified": "' + post.updated_at + '",\n' +
|
||||
' "image": "http://testurl.com/test-image.png",\n' +
|
||||
' "description": "blog description"\n}\n </script>\n\n' +
|
||||
' "description": "blog description..."\n}\n </script>\n\n' +
|
||||
' <meta name="generator" content="Ghost 0.3" />\n' +
|
||||
' <link rel="alternate" type="application/rss+xml" title="Ghost" href="/rss/" />');
|
||||
|
||||
@ -191,7 +244,7 @@ describe('{{ghost_head}} helper', function () {
|
||||
' "url": "http://testurl.com/author/Author",\n "sameAs": "http://authorwebsite.com"\n ' +
|
||||
'},\n "headline": "Welcome to Ghost",\n "url": "http://testurl.com/post/",\n' +
|
||||
' "datePublished": "' + post.published_at + '",\n "dateModified": "' + post.updated_at + '",\n' +
|
||||
' "keywords": "tag1, tag2, tag3",\n "description": "blog description"\n}\n </script>\n\n' +
|
||||
' "keywords": "tag1, tag2, tag3",\n "description": "blog description..."\n}\n </script>\n\n' +
|
||||
' <meta name="generator" content="Ghost 0.3" />\n' +
|
||||
' <link rel="alternate" type="application/rss+xml" title="Ghost" href="/rss/" />');
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user