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'),
|
2013-05-30 18:01:29 +04:00
|
|
|
|
when = require('when'),
|
2013-05-11 20:44:25 +04:00
|
|
|
|
express = require('express'),
|
|
|
|
|
path = require('path'),
|
|
|
|
|
hbs = require('express-hbs'),
|
|
|
|
|
_ = require('underscore'),
|
|
|
|
|
Polyglot = require('node-polyglot'),
|
2013-05-31 02:34:53 +04:00
|
|
|
|
|
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'),
|
2013-06-09 20:45:17 +04:00
|
|
|
|
|
|
|
|
|
requireTree = require('./shared/require-tree'),
|
|
|
|
|
themeDirectories = requireTree('content/themes'),
|
|
|
|
|
pluginDirectories = requireTree('content/plugins'),
|
|
|
|
|
|
2013-05-11 20:44:25 +04:00
|
|
|
|
Ghost,
|
2013-05-29 04:10:39 +04:00
|
|
|
|
instance,
|
2013-06-09 20:16:25 +04:00
|
|
|
|
defaults,
|
2013-05-11 20:44:25 +04:00
|
|
|
|
statuses;
|
|
|
|
|
|
2013-06-09 20:16:25 +04:00
|
|
|
|
// ## 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
|
2013-06-09 20:45:17 +04:00
|
|
|
|
instance.filterCallbacks = [];
|
2013-06-01 18:47:41 +04:00
|
|
|
|
|
|
|
|
|
// Holds the filter hooks (that are built in to Ghost Core)
|
2013-06-09 20:45:17 +04:00
|
|
|
|
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-06-09 20:45:17 +04:00
|
|
|
|
|
|
|
|
|
|
2013-05-11 20:44:25 +04:00
|
|
|
|
_.extend(instance, {
|
|
|
|
|
app: function () { return app; },
|
|
|
|
|
config: function () { return config; },
|
2013-06-09 20:45:17 +04:00
|
|
|
|
|
|
|
|
|
// 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; },
|
2013-05-31 09:58:20 +04:00
|
|
|
|
plugin: function () { return plugin; },
|
2013-06-09 20:45:17 +04:00
|
|
|
|
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 {
|
2013-05-27 23:27:41 +04:00
|
|
|
|
'activeTheme': __dirname + '/../content/' + config.themeDir + '/' + config.activeTheme + '/',
|
|
|
|
|
'adminViews': __dirname + '/admin/views/',
|
|
|
|
|
'frontendViews': __dirname + '/frontend/views/',
|
2013-06-09 20:45:17 +04:00
|
|
|
|
'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 () {
|
2013-06-15 03:39:27 +04:00
|
|
|
|
var settings = {},
|
|
|
|
|
self = this,
|
|
|
|
|
configDeferred = when.defer(),
|
|
|
|
|
configPromise = configDeferred.promise;
|
|
|
|
|
|
|
|
|
|
models.Settings.findAll().then(function (result) {
|
|
|
|
|
_.map(result.models, function (member) {
|
|
|
|
|
if (!settings.hasOwnProperty(member.attributes.key)) {
|
|
|
|
|
settings[member.attributes.key] = member.attributes.value;
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
configDeferred.resolve(settings);
|
|
|
|
|
});
|
|
|
|
|
return when.all([instance.dataProvider.init(), instance.getPaths(), configPromise]).then(function (results) {
|
|
|
|
|
self.globalConfig = results[2];
|
|
|
|
|
return;
|
|
|
|
|
});
|
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 {*}
|
|
|
|
|
*/
|
2013-05-25 20:48:15 +04:00
|
|
|
|
Ghost.prototype.registerTheme = function (name, fn) {
|
|
|
|
|
return this;
|
|
|
|
|
};
|
2013-05-11 20:44:25 +04:00
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @param {string} name
|
|
|
|
|
* @param {Function} fn
|
|
|
|
|
* @return {*}
|
|
|
|
|
*/
|
2013-05-25 20:48:15 +04:00
|
|
|
|
Ghost.prototype.registerPlugin = function (name, fn) {
|
|
|
|
|
return this;
|
|
|
|
|
};
|
2013-05-11 20:44:25 +04:00
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @param {string} name
|
2013-06-09 20:16:25 +04:00
|
|
|
|
* @param {integer} priority
|
2013-05-11 20:44:25 +04:00
|
|
|
|
* @param {Function} fn
|
|
|
|
|
*/
|
2013-06-09 20:16:25 +04:00
|
|
|
|
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
|
|
|
|
}
|
2013-06-09 20:16: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) {
|
2013-06-09 20:16:25 +04:00
|
|
|
|
var callbacks = this.filterCallbacks[name];
|
2013-05-11 20:44:25 +04:00
|
|
|
|
|
2013-06-09 20:16: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
|
|
|
|
}
|
2013-05-27 23:27:41 +04:00
|
|
|
|
|
2013-06-09 20:16: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();
|
|
|
|
|
};
|
|
|
|
|
};
|
|
|
|
|
|
2013-06-09 20:16:25 +04:00
|
|
|
|
// 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;
|
2013-06-15 03:39:27 +04:00
|
|
|
|
}());
|