Created image helper with absolute url option
closes #4231 - Adds {{image}} helper - Adds image_spec test unit - Updated {{ghost_head}} to use image helper
This commit is contained in:
parent
f6eccf4bd1
commit
4a56d10c86
@ -101,8 +101,8 @@ function urlPathForPost(post, permalinks) {
|
||||
// This is probably not the right place for this, but it's the best place for now
|
||||
function urlFor(context, data, absolute) {
|
||||
var urlPath = '/',
|
||||
secure,
|
||||
knownObjects = ['post', 'tag', 'author'],
|
||||
secure, imagePathRe,
|
||||
knownObjects = ['post', 'tag', 'author', 'image'],
|
||||
|
||||
// this will become really big
|
||||
knownPaths = {
|
||||
@ -133,6 +133,11 @@ function urlFor(context, data, absolute) {
|
||||
} else if (context === 'author' && data.author) {
|
||||
urlPath = '/author/' + data.author.slug + '/';
|
||||
secure = data.author.secure;
|
||||
} else if (context === 'image' && data.image) {
|
||||
urlPath = data.image;
|
||||
imagePathRe = new RegExp('^' + ghostConfig.paths.subdir + '/' + ghostConfig.paths.imagesRelPath);
|
||||
absolute = imagePathRe.test(data.image) ? absolute : false;
|
||||
secure = data.image.secure;
|
||||
}
|
||||
// other objects are recognised but not yet supported
|
||||
} else if (_.isString(context) && _.indexOf(_.keys(knownPaths), context) !== -1) {
|
||||
|
@ -19,6 +19,7 @@ var hbs = require('express-hbs'),
|
||||
meta_title = require('./meta_title'),
|
||||
excerpt = require('./excerpt'),
|
||||
tagsHelper = require('./tags'),
|
||||
imageHelper = require('./image'),
|
||||
ghost_head;
|
||||
|
||||
ghost_head = function (options) {
|
||||
@ -42,12 +43,21 @@ ghost_head = function (options) {
|
||||
ops.push(urlHelper.call(self, {hash: {absolute: true}}));
|
||||
ops.push(meta_description.call(self));
|
||||
ops.push(meta_title.call(self));
|
||||
if (self.post) {
|
||||
ops.push(imageHelper.call(self.post, {hash: {absolute:true}}));
|
||||
|
||||
if (self.post.author) {
|
||||
ops.push(imageHelper.call(self.post.author, {hash: {absolute:true}}));
|
||||
}
|
||||
}
|
||||
|
||||
// Resolves promises then push pushes meta data into ghost_head
|
||||
return Promise.settle(ops).then(function (results) {
|
||||
var url = results[0].value(),
|
||||
metaDescription = results[1].value(),
|
||||
metaTitle = results[2].value(),
|
||||
coverImage = results.length > 3 ? results[3].value() : null,
|
||||
authorImage = results.length > 4 ? results[4].value() : null,
|
||||
publishedDate, modifiedDate,
|
||||
tags = tagsHelper.call(self.post, {hash: {autolink: 'false'}}).string.split(','),
|
||||
card = 'summary',
|
||||
@ -80,19 +90,10 @@ ghost_head = function (options) {
|
||||
publishedDate = moment(self.post.published_at).toISOString();
|
||||
modifiedDate = moment(self.post.updated_at).toISOString();
|
||||
|
||||
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 : hbs.handlebars.Utils.escapeExpression(blog.url + coverImage);
|
||||
if (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 : hbs.handlebars.Utils.escapeExpression(blog.url + authorImage);
|
||||
}
|
||||
|
||||
// escaped data
|
||||
metaTitle = hbs.handlebars.Utils.escapeExpression(metaTitle);
|
||||
metaDescription = hbs.handlebars.Utils.escapeExpression(metaDescription + '...');
|
||||
|
20
core/server/helpers/image.js
Normal file
20
core/server/helpers/image.js
Normal file
@ -0,0 +1,20 @@
|
||||
|
||||
// Usage: `{{image}}`, `{{image absolute="true"}}`
|
||||
//
|
||||
// Returns the URL for the current object scope i.e. If inside a post scope will return image permalink
|
||||
// `absolute` flag outputs absolute URL, else URL is relative.
|
||||
|
||||
var Promise = require('bluebird'),
|
||||
config = require('../config'),
|
||||
image;
|
||||
|
||||
image = function (options) {
|
||||
var absolute = options && options.hash.absolute;
|
||||
if (this.image) {
|
||||
return Promise.resolve(config.urlFor('image', {image: this.image}, absolute));
|
||||
} else {
|
||||
return Promise.resolve();
|
||||
}
|
||||
};
|
||||
|
||||
module.exports = image;
|
@ -40,6 +40,7 @@ coreHelpers.post_class = require('./post_class');
|
||||
coreHelpers.tags = require('./tags');
|
||||
coreHelpers.title = require('./title');
|
||||
coreHelpers.url = require('./url');
|
||||
coreHelpers.image = require('./image');
|
||||
|
||||
coreHelpers.ghost_script_tags = require('./ghost_script_tags');
|
||||
|
||||
@ -146,6 +147,7 @@ registerHelpers = function (adminHbs) {
|
||||
registerAsyncThemeHelper('meta_title', coreHelpers.meta_title);
|
||||
registerAsyncThemeHelper('post_class', coreHelpers.post_class);
|
||||
registerAsyncThemeHelper('url', coreHelpers.url);
|
||||
registerAsyncThemeHelper('image', coreHelpers.image);
|
||||
|
||||
// Register admin helpers
|
||||
registerAdminHelper('ghost_script_tags', coreHelpers.ghost_script_tags);
|
||||
|
@ -54,7 +54,7 @@ describe('{{ghost_head}} helper', function () {
|
||||
var post = {
|
||||
meta_description: 'blog description',
|
||||
title: 'Welcome to Ghost',
|
||||
image: '/test-image.png',
|
||||
image: '/content/images/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'}],
|
||||
@ -62,7 +62,7 @@ describe('{{ghost_head}} helper', function () {
|
||||
name: 'Author name',
|
||||
url: 'http//:testauthorurl.com',
|
||||
slug: 'Author',
|
||||
image: '/test-author-image.png',
|
||||
image: '/content/images/test-author-image.png',
|
||||
website: 'http://authorwebsite.com'
|
||||
}
|
||||
};
|
||||
@ -75,7 +75,7 @@ describe('{{ghost_head}} helper', function () {
|
||||
' <meta property="og:title" content="Welcome to Ghost" />\n' +
|
||||
' <meta property="og:description" content="blog 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="og:image" content="http://testurl.com/content/images/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' +
|
||||
@ -85,15 +85,15 @@ describe('{{ghost_head}} helper', function () {
|
||||
' <meta name="twitter:title" content="Welcome to Ghost" />\n' +
|
||||
' <meta name="twitter:description" content="blog 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' +
|
||||
' <meta name="twitter:image:src" content="http://testurl.com/content/images/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 ' +
|
||||
' \"image\": \"http://testurl.com/content/images/test-author-image.png\",\n ' +
|
||||
' "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' +
|
||||
' "image": "http://testurl.com/test-image.png",\n "keywords": "tag1, tag2, tag3",\n' +
|
||||
' "image": "http://testurl.com/content/images/test-image.png",\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/" />');
|
||||
@ -107,7 +107,7 @@ describe('{{ghost_head}} helper', function () {
|
||||
meta_description: 'blog "test" description',
|
||||
title: 'title',
|
||||
meta_title: 'Welcome to Ghost "test"',
|
||||
image: '/test-image.png',
|
||||
image: '/content/images/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'}],
|
||||
@ -115,7 +115,7 @@ describe('{{ghost_head}} helper', function () {
|
||||
name: 'Author name',
|
||||
url: 'http//:testauthorurl.com',
|
||||
slug: 'Author',
|
||||
image: '/test-author-image.png',
|
||||
image: '/content/images/test-author-image.png',
|
||||
website: 'http://authorwebsite.com'
|
||||
}
|
||||
};
|
||||
@ -128,7 +128,7 @@ describe('{{ghost_head}} helper', function () {
|
||||
' <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="og:image" content="http://testurl.com/content/images/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' +
|
||||
@ -138,15 +138,15 @@ describe('{{ghost_head}} helper', function () {
|
||||
' <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' +
|
||||
' <meta name="twitter:image:src" content="http://testurl.com/content/images/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 ' +
|
||||
' \"image\": \"http://testurl.com/content/images/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' +
|
||||
' "image": "http://testurl.com/content/images/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/" />');
|
||||
@ -159,7 +159,7 @@ describe('{{ghost_head}} helper', function () {
|
||||
var post = {
|
||||
meta_description: 'blog description',
|
||||
title: 'Welcome to Ghost',
|
||||
image: '/test-image.png',
|
||||
image: '/content/images/test-image.png',
|
||||
published_at: moment('2008-05-31T19:18:15').toISOString(),
|
||||
updated_at: moment('2014-10-06T15:23:54').toISOString(),
|
||||
tags: [],
|
||||
@ -167,7 +167,7 @@ describe('{{ghost_head}} helper', function () {
|
||||
name: 'Author name',
|
||||
url: 'http//:testauthorurl.com',
|
||||
slug: 'Author',
|
||||
image: '/test-author-image.png',
|
||||
image: '/content/images/test-author-image.png',
|
||||
website: 'http://authorwebsite.com'
|
||||
}
|
||||
};
|
||||
@ -180,22 +180,22 @@ describe('{{ghost_head}} helper', function () {
|
||||
' <meta property="og:title" content="Welcome to Ghost" />\n' +
|
||||
' <meta property="og:description" content="blog 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="og:image" content="http://testurl.com/content/images/test-image.png" />\n' +
|
||||
' <meta property="article:published_time" content="' + post.published_at + '" />\n' +
|
||||
' <meta property="article:modified_time" content="' + post.updated_at + '" />\n \n' +
|
||||
' <meta name="twitter:card" content="summary_large_image" />\n' +
|
||||
' <meta name="twitter:title" content="Welcome to Ghost" />\n' +
|
||||
' <meta name="twitter:description" content="blog 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' +
|
||||
' <meta name="twitter:image:src" content="http://testurl.com/content/images/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 ' +
|
||||
' \"image\": \"http://testurl.com/content/images/test-author-image.png\",\n ' +
|
||||
' "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' +
|
||||
' "image": "http://testurl.com/test-image.png",\n' +
|
||||
' "image": "http://testurl.com/content/images/test-image.png",\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/" />');
|
||||
@ -204,7 +204,7 @@ describe('{{ghost_head}} helper', function () {
|
||||
}).catch(done);
|
||||
});
|
||||
|
||||
it('returns structured data on post page without author image and post cover image', function (done) {
|
||||
it('returns structured data on post page with null author image and post cover image', function (done) {
|
||||
var post = {
|
||||
meta_description: 'blog description',
|
||||
title: 'Welcome to Ghost',
|
||||
@ -262,7 +262,7 @@ describe('{{ghost_head}} helper', function () {
|
||||
var post = {
|
||||
meta_description: 'blog description',
|
||||
title: 'Welcome to Ghost',
|
||||
image: '/test-image.png',
|
||||
image: 'content/images/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'}],
|
||||
@ -270,7 +270,7 @@ describe('{{ghost_head}} helper', function () {
|
||||
name: 'Author name',
|
||||
url: 'http//:testauthorurl.com',
|
||||
slug: 'Author',
|
||||
image: '/test-author-image.png',
|
||||
image: 'content/images/test-author-image.png',
|
||||
website: 'http://authorwebsite.com'
|
||||
}
|
||||
};
|
||||
|
69
core/test/unit/server_helpers/image_spec.js
Normal file
69
core/test/unit/server_helpers/image_spec.js
Normal file
@ -0,0 +1,69 @@
|
||||
/*globals describe, before, afterEach, after, it*/
|
||||
/*jshint expr:true*/
|
||||
var should = require('should'),
|
||||
sinon = require('sinon'),
|
||||
hbs = require('express-hbs'),
|
||||
utils = require('./utils'),
|
||||
|
||||
// Stuff we are testing
|
||||
handlebars = hbs.handlebars,
|
||||
helpers = require('../../../server/helpers');
|
||||
|
||||
describe('{{image}} helper', function () {
|
||||
var sandbox;
|
||||
|
||||
before(function () {
|
||||
sandbox = sinon.sandbox.create();
|
||||
utils.overrideConfig({url: 'http://testurl.com/'});
|
||||
utils.loadHelpers();
|
||||
});
|
||||
|
||||
afterEach(function () {
|
||||
sandbox.restore();
|
||||
});
|
||||
|
||||
after(function () {
|
||||
utils.restoreConfig();
|
||||
});
|
||||
|
||||
it('has loaded image helper', function () {
|
||||
should.exist(handlebars.helpers.image);
|
||||
});
|
||||
|
||||
it('should output relative url of image', function (done) {
|
||||
helpers.image.call({
|
||||
image: '/content/images/image-relative-url.png',
|
||||
author: {
|
||||
image: '/content/images/author-image-relatve-url.png'
|
||||
}
|
||||
}).then(function (rendered) {
|
||||
should.exist(rendered);
|
||||
rendered.should.equal('/content/images/image-relative-url.png');
|
||||
done();
|
||||
}).catch(done);
|
||||
});
|
||||
|
||||
it('should output absolute url of image if the option is present ', function (done) {
|
||||
helpers.image.call({image: '/content/images/image-relative-url.png',
|
||||
author: {image: '/content/images/author-image-relatve-url.png'}},
|
||||
{hash: {absolute: 'true'}}).then(function (rendered) {
|
||||
should.exist(rendered);
|
||||
rendered.should.equal('http://testurl.com/content/images/image-relative-url.png');
|
||||
done();
|
||||
}).catch(done);
|
||||
});
|
||||
|
||||
it('should have no output if there is no image ', function (done) {
|
||||
helpers.image.call({image: null}, {hash: {absolute: 'true'}}).then(function (rendered) {
|
||||
should.not.exist(rendered);
|
||||
done();
|
||||
}).catch(done);
|
||||
});
|
||||
|
||||
it('should have no output if there is no image property ', function (done) {
|
||||
helpers.image.call({}, {hash: {absolute: 'true'}}).then(function (rendered) {
|
||||
should.not.exist(rendered);
|
||||
done();
|
||||
}).catch(done);
|
||||
});
|
||||
});
|
Loading…
Reference in New Issue
Block a user