Ghost/core/ghost.js

247 lines
7.5 KiB
JavaScript
Raw Normal View History

2013-05-11 20:44:25 +04:00
// # Ghost Module
// Defines core methods required to build the frontend
2013-05-16 14:29:02 +04:00
/*global module, require, __dirname */
2013-05-11 20:44:25 +04:00
(function () {
"use strict";
// ## Setup Prerequisites
var config = require('./../config'),
when = require('when'),
2013-05-11 20:44:25 +04:00
express = require('express'),
errors = require('../core/shared/errorHandling'),
2013-05-11 20:44:25 +04:00
path = require('path'),
hbs = require('express-hbs'),
_ = require('underscore'),
Polyglot = require('node-polyglot'),
2013-06-01 18:47:41 +04:00
models = require('./shared/models'),
2013-05-29 04:10:39 +04:00
ExampleFilter = require('../content/plugins/exampleFilters'),
requireTree = require('./shared/require-tree'),
themeDirectories = requireTree(path.resolve(__dirname + '../../content/themes')),
pluginDirectories = requireTree(path.resolve(__dirname + '../../content/plugins')),
2013-05-11 20:44:25 +04:00
Ghost,
2013-05-29 04:10:39 +04:00
instance,
defaults,
2013-05-11 20:44:25 +04:00
statuses;
// ## Default values
/**
* A hash of default values to use instead of 'magic' numbers/strings.
* @type {Object}
*/
defaults = {
filterPriority: 5,
maxPriority: 9
};
2013-05-30 02:49:49 +04:00
2013-05-11 20:44:25 +04:00
// ## Article Statuses
/**
* A list of atricle status types
* @type {Object}
*/
statuses = {
'draft': 'draft',
'complete': 'complete',
'approved': 'approved',
'scheduled': 'scheduled',
'published': 'published'
};
// ## Module Methods
/**
* @method Ghost
* @returns {*}
* @constructor
*/
Ghost = function () {
var app,
2013-05-29 04:10:39 +04:00
plugin,
2013-05-11 20:44:25 +04:00
polyglot;
if (!instance) {
instance = this;
2013-06-01 18:47:41 +04:00
// Holds the filters
instance.filterCallbacks = [];
2013-06-01 18:47:41 +04:00
// Holds the filter hooks (that are built in to Ghost Core)
instance.filters = [];
// Holds the theme directories temporarily
instance.themeDirectories = {};
// Holds the plugin directories temporarily
instance.pluginDirectories = {};
2013-06-01 18:47:41 +04:00
2013-05-29 04:10:39 +04:00
plugin = new ExampleFilter(instance).init();
2013-05-11 20:44:25 +04:00
app = express();
polyglot = new Polyglot();
// functionality
// load Plugins...
// var f = new FancyFirstChar(ghost).init();
2013-05-11 20:44:25 +04:00
_.extend(instance, {
app: function () { return app; },
config: function () { return config; },
// there's no management here to be sure this has loaded
globals: function () { return instance.globalConfig; },
2013-06-01 18:47:41 +04:00
dataProvider: models,
2013-05-11 20:44:25 +04:00
statuses: function () { return statuses; },
polyglot: function () { return polyglot; },
plugin: function () { return plugin; },
getPaths: function () {
return when.all([themeDirectories, pluginDirectories]).then(function (paths) {
instance.themeDirectories = paths[0];
instance.pluginDirectories = paths[1];
return;
});
},
2013-05-11 20:44:25 +04:00
paths: function () {
return {
'activeTheme': __dirname + '/../content/' + config.themeDir + '/' + config.activeTheme + '/',
'adminViews': __dirname + '/admin/views/',
'frontendViews': __dirname + '/frontend/views/',
'lang': __dirname + '/lang/',
'availableThemes': instance.themeDirectories,
'availablePlugins': instance.pluginDirectories
2013-05-11 20:44:25 +04:00
};
}
});
}
return instance;
};
2013-06-01 18:47:41 +04:00
Ghost.prototype.init = function () {
var self = this;
return when.join(instance.dataProvider.init(), instance.getPaths()).then(function () {
// TODO: this should use api.browse
return models.Settings.findAll().then(function (result) {
var settings = {};
_.map(result.models, function (member) {
if (!settings.hasOwnProperty(member.attributes.key)) {
settings[member.attributes.key] = member.attributes.value;
}
});
self.globalConfig = settings;
}, errors.logAndThrowError);
}, errors.logAndThrowError);
2013-05-30 13:41:25 +04:00
};
2013-05-11 20:44:25 +04:00
/**
* @param {string} name
* @param {Function} fn
* @return {method} hbs.registerHelper
*/
Ghost.prototype.registerThemeHelper = function (name, fn) {
hbs.registerHelper(name, fn);
};
/**
* @param {string} name
* @param {Function} fn
* @return {*}
*/
Ghost.prototype.registerTheme = function (name, fn) {
return this;
};
2013-05-11 20:44:25 +04:00
/**
* @param {string} name
* @param {Function} fn
* @return {*}
*/
Ghost.prototype.registerPlugin = function (name, fn) {
return this;
};
2013-05-11 20:44:25 +04:00
/**
* @param {string} name
* @param {integer} priority
2013-05-11 20:44:25 +04:00
* @param {Function} fn
*/
Ghost.prototype.registerFilter = function (name, priority, fn) {
// Curry the priority optional parameter to a default of 5
if (_.isFunction(priority)) {
fn = priority;
priority = defaults.filterPriority;
2013-05-11 20:44:25 +04:00
}
this.filterCallbacks[name] = this.filterCallbacks[name] || {};
this.filterCallbacks[name][priority] = this.filterCallbacks[name][priority] || [];
this.filterCallbacks[name][priority].push(fn);
2013-05-11 20:44:25 +04:00
};
/**
* @param {string} name [description]
* @param {*} args
* @param {Function} callback
* @return {method} callback
*/
Ghost.prototype.doFilter = function (name, args, callback) {
var callbacks = this.filterCallbacks[name];
2013-05-11 20:44:25 +04:00
// Bug out early if no callbacks by that name
if (!callbacks) {
return callback(args);
2013-05-11 20:44:25 +04:00
}
_.times(defaults.maxPriority + 1, function (priority) {
// Bug out if no handlers on this priority
if (!_.isArray(callbacks[priority])) {
return;
}
// Call each handler for this priority level
_.each(callbacks[priority], function (filterHandler) {
args = filterHandler(args);
});
});
2013-05-11 20:44:25 +04:00
callback(args);
};
/**
* Initialise Theme
*
* @todo Tod (?) Old comment
* @param {Object} app
*/
Ghost.prototype.initTheme = function (app) {
var self = this;
return function initTheme(req, res, next) {
app.set('view engine', 'hbs');
if (/(^\/ghost$|^\/ghost\/)/.test(req.url) === false) {
app.engine('hbs', hbs.express3(
{partialsDir: self.paths().activeTheme + 'partials'}
));
app.set('views', self.paths().activeTheme);
} else {
2013-05-12 17:40:59 +04:00
app.engine('hbs', hbs.express3({partialsDir: self.paths().adminViews + 'partials'}));
2013-05-11 20:44:25 +04:00
app.set('views', self.paths().adminViews);
app.use('/core/admin/assets', express['static'](path.join(__dirname, '/admin/assets')));
}
app.use(express['static'](self.paths().activeTheme));
app.use('/content/images', express['static'](path.join(__dirname, '/../content/images')));
next();
};
};
// TODO: Expose the defaults for other people to see/manipulate as a static value?
// Ghost.defaults = defaults;
2013-05-11 20:44:25 +04:00
module.exports = Ghost;
}());