Skip to content

Commit

Permalink
Get helper
Browse files Browse the repository at this point in the history
closes TryGhost#4439

- adds get helper + tests
  • Loading branch information
ErisDS committed Sep 18, 2015
1 parent c57edd6 commit 3594729
Show file tree
Hide file tree
Showing 4 changed files with 172 additions and 0 deletions.
106 changes: 106 additions & 0 deletions core/server/helpers/get.js
@@ -0,0 +1,106 @@
// # Get Helper
// Usage: `{{#get "posts" limit="5"}}`, `{{#get "tags" limit="all"}}`
// Fetches data from the API

var _ = require('lodash'),
hbs = require('express-hbs'),
errors = require('../errors'),
api = require('../api'),
jsonpath = require('jsonpath'),

resources = ['posts', 'tags', 'users'],
pathAliases = {
'post.tags': 'post.tags[*].slug',
'post.author': 'post.author.slug'
},
get;

function doBrowse(context, options) {
var browse = true;
if (options.limit && options.limit === 1) {
browse = false;
}

if (options.id || options.slug) {
browse = false;
}

return browse;
}

function resolvePaths(data, value) {
var regex = /\{\{(.*?)\}\}/g;

value = value.replace(regex, function (match, path) {
var result;

// Handle tag, author and role aliases
path = pathAliases[path] ? pathAliases[path] : path;

result = jsonpath.query(data, path);

if (_.isArray(result)) {
result = result.join(',');
}

return result;
});

return value;
}

function parseOptions(data, options) {
options = _.omit(options.hash, 'context');
if (_.isArray(options.tag)) {
options.tag = _.pluck(options.tag, 'slug').join(',');
}

if (_.isString(options.filter)) {
options.filter = resolvePaths(data, options.filter);
}

return options;
}

get = function get(context, options) {
options = options || {};
options.hash = options.hash || {};

var self = this,
data,
apiOptions,
apiMethod;

if (!_.contains(resources, context)) {
errors.logWarn('Invalid resource given to get helper');
return;
}

if (options.data) {
data = hbs.handlebars.createFrame(options.data);
}

// Determine if this is a read or browse
apiMethod = doBrowse(context, options) ? api[context].browse : api[context].read;
// Parse the options we're going to pass to the API
apiOptions = parseOptions(this, options);

return apiMethod(apiOptions).then(function success(result) {
var data = _.merge(self, result);
if (_.isEmpty(result[context])) {
return options.inverse(self);
}

return options.fn(data, {
data: data,
blockParams: [result[context]]
});
}).catch(function error(err) {
if (data) {
data.error = err.message;
}
return options.inverse(self, {data: data});
});
};

module.exports = get;
2 changes: 2 additions & 0 deletions core/server/helpers/index.js
Expand Up @@ -21,6 +21,7 @@ coreHelpers.date = require('./date');
coreHelpers.encode = require('./encode');
coreHelpers.excerpt = require('./excerpt');
coreHelpers.foreach = require('./foreach');
coreHelpers.get = require('./get');
coreHelpers.ghost_foot = require('./ghost_foot');
coreHelpers.ghost_head = require('./ghost_head');
coreHelpers.image = require('./image');
Expand Down Expand Up @@ -117,6 +118,7 @@ registerHelpers = function (adminHbs) {
registerAsyncThemeHelper('post_class', coreHelpers.post_class);
registerAsyncThemeHelper('next_post', coreHelpers.next_post);
registerAsyncThemeHelper('prev_post', coreHelpers.prev_post);
registerAsyncThemeHelper('get', coreHelpers.get);

// Register admin helpers
registerAdminHelper('asset', coreHelpers.asset);
Expand Down
63 changes: 63 additions & 0 deletions core/test/unit/server_helpers/get_spec.js
@@ -0,0 +1,63 @@
/*globals describe, before, beforeEach, afterEach, it*/
/*jshint expr:true*/
var should = require('should'),
sinon = require('sinon'),
hbs = require('express-hbs'),
Promise = require('bluebird'),
utils = require('./utils'),

// Stuff we are testing
handlebars = hbs.handlebars,
helpers = require('../../../server/helpers'),
api = require('../../../server/api');

describe('{{#get}} helper', function () {
var sandbox;

before(function () {
utils.loadHelpers();
});

beforeEach(function () {
sandbox = sinon.sandbox.create();
});

afterEach(function () {
sandbox.restore();
});

it('has loaded get block helper', function () {
should.exist(handlebars.helpers.get);
});

describe('posts', function () {
var testPostsObj = {
posts: [
{id: 1}
]
};
beforeEach(function () {
sandbox.stub(api.posts, 'browse', function () {
return Promise.resolve(testPostsObj);
});
});

it('should handle default posts call', function (done) {
var fn = sinon.spy(),
inverse = sinon.spy();

helpers.get.call(
{},
'posts',
{hash: {}, fn: fn, inverse: inverse}
).then(function () {
fn.called.should.be.true;
fn.firstCall.args[0].should.be.an.Object;
fn.firstCall.args[0].should.eql(testPostsObj);
inverse.called.should.be.false;

done();
}).catch(done);
});
});
});
1 change: 1 addition & 0 deletions package.json
Expand Up @@ -45,6 +45,7 @@
"html-to-text": "1.3.0",
"intl": "1.0.0",
"intl-messageformat": "1.1.0",
"jsonpath": "0.1.8",
"knex": "0.7.3",
"lodash": "3.10.0",
"moment": "2.10.3",
Expand Down

0 comments on commit 3594729

Please sign in to comment.