Ghost/core/ghost.js
Jacob Gable a63690a471 Fix relative paths for deployment
In order to run with forever / supervisorctl, the relative paths need to
be converted to full ones based on the __dirname.
2013-06-15 10:54:49 -05:00

248 lines
7.5 KiB
JavaScript
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// # Ghost Module
// Defines core methods required to build the frontend
/*global module, require, __dirname */
(function () {
"use strict";
// ## Setup Prerequisites
var config = require('./../config'),
when = require('when'),
express = require('express'),
path = require('path'),
hbs = require('express-hbs'),
_ = require('underscore'),
Polyglot = require('node-polyglot'),
models = require('./shared/models'),
ExampleFilter = require('../content/plugins/exampleFilters'),
requireTree = require('./shared/require-tree'),
themeDirectories = requireTree(path.resolve(__dirname + '../../content/themes')),
pluginDirectories = requireTree(path.resolve(__dirname + '../../content/plugins')),
Ghost,
instance,
defaults,
statuses;
// ## Default values
/**
* A hash of default values to use instead of 'magic' numbers/strings.
* @type {Object}
*/
defaults = {
filterPriority: 5,
maxPriority: 9
};
// ## 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,
plugin,
polyglot;
if (!instance) {
instance = this;
// Holds the filters
instance.filterCallbacks = [];
// 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 = {};
plugin = new ExampleFilter(instance).init();
app = express();
polyglot = new Polyglot();
// functionality
// load Plugins...
// var f = new FancyFirstChar(ghost).init();
_.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; },
dataProvider: models,
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;
});
},
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
};
}
});
}
return instance;
};
Ghost.prototype.init = function () {
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;
});
};
/**
* @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;
};
/**
* @param {string} name
* @param {Function} fn
* @return {*}
*/
Ghost.prototype.registerPlugin = function (name, fn) {
return this;
};
/**
* @param {string} name
* @param {integer} priority
* @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;
}
this.filterCallbacks[name] = this.filterCallbacks[name] || {};
this.filterCallbacks[name][priority] = this.filterCallbacks[name][priority] || [];
this.filterCallbacks[name][priority].push(fn);
};
/**
* @param {string} name [description]
* @param {*} args
* @param {Function} callback
* @return {method} callback
*/
Ghost.prototype.doFilter = function (name, args, callback) {
var callbacks = this.filterCallbacks[name];
// Bug out early if no callbacks by that name
if (!callbacks) {
return callback(args);
}
_.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);
});
});
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 {
app.engine('hbs', hbs.express3({partialsDir: self.paths().adminViews + 'partials'}));
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;
module.exports = Ghost;
}());