diff --git a/core/server/config/url.js b/core/server/config/url.js
index a34257c3dc..ece88367c0 100644
--- a/core/server/config/url.js
+++ b/core/server/config/url.js
@@ -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) {
diff --git a/core/server/helpers/ghost_head.js b/core/server/helpers/ghost_head.js
index 27f782e3f2..9b262e7a03 100644
--- a/core/server/helpers/ghost_head.js
+++ b/core/server/helpers/ghost_head.js
@@ -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 + '...');
diff --git a/core/server/helpers/image.js b/core/server/helpers/image.js
new file mode 100644
index 0000000000..7b14db0e28
--- /dev/null
+++ b/core/server/helpers/image.js
@@ -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;
diff --git a/core/server/helpers/index.js b/core/server/helpers/index.js
index 2b559e2fdd..1778924844 100644
--- a/core/server/helpers/index.js
+++ b/core/server/helpers/index.js
@@ -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);
diff --git a/core/test/unit/server_helpers/ghost_head_spec.js b/core/test/unit/server_helpers/ghost_head_spec.js
index 2e4e875e35..001f559323 100644
--- a/core/test/unit/server_helpers/ghost_head_spec.js
+++ b/core/test/unit/server_helpers/ghost_head_spec.js
@@ -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 () {
' \n' +
' \n' +
' \n' +
- ' \n' +
+ ' \n' +
' \n' +
' \n' +
' \n' +
@@ -85,15 +85,15 @@ describe('{{ghost_head}} helper', function () {
' \n' +
' \n' +
' \n' +
- ' \n \n' +
+ ' \n \n' +
' \n\n' +
' \n' +
' ');
@@ -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 () {
' \n' +
' \n' +
' \n' +
- ' \n' +
+ ' \n' +
' \n' +
' \n' +
' \n' +
@@ -138,15 +138,15 @@ describe('{{ghost_head}} helper', function () {
' \n' +
' \n' +
' \n' +
- ' \n \n' +
+ ' \n \n' +
' \n\n' +
' \n' +
' ');
@@ -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 () {
' \n' +
' \n' +
' \n' +
- ' \n' +
+ ' \n' +
' \n' +
' \n \n' +
' \n' +
' \n' +
' \n' +
' \n' +
- ' \n \n' +
+ ' \n \n' +
' \n\n' +
' \n' +
' ');
@@ -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'
}
};
diff --git a/core/test/unit/server_helpers/image_spec.js b/core/test/unit/server_helpers/image_spec.js
new file mode 100644
index 0000000000..d6fb40b1ea
--- /dev/null
+++ b/core/test/unit/server_helpers/image_spec.js
@@ -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);
+ });
+});