var debug = require('ghost-ignition').debug('themes'), common = require('../lib/common'), themeLoader = require('./loader'), active = require('./active'), validate = require('./validate'), Storage = require('./Storage'), settingsCache = require('../settings/cache'), themeStorage; // @TODO: reduce the amount of things we expose to the outside world // Make this a nice clean sensible API we can all understand! module.exports = { // Init themes module // TODO: move this once we're clear what needs to happen here init: function initThemes() { var activeThemeName = settingsCache.get('active_theme'), self = this; debug('init themes', activeThemeName); // Register a listener for server-start to load all themes common.events.on('server:start', function readAllThemesOnServerStart() { themeLoader.loadAllThemes(); }); // Just read the active theme for now return themeLoader .loadOneTheme(activeThemeName) .then(function activeThemeHasLoaded(theme) { // Validate return validate .check(theme) .then(function validationSuccess(checkedTheme) { // CASE: inform that the theme has errors, but not fatal (theme still works) if (checkedTheme.results.error.length) { common.logging.warn(new common.errors.ThemeValidationError({ errorType: 'ThemeWorksButHasErrors', message: common.i18n.t('errors.middleware.themehandler.themeHasErrors', {theme: activeThemeName}), errorDetails: JSON.stringify(checkedTheme.results.error, null, '\t') })); } debug('Activating theme (method A on boot)', activeThemeName); self.activate(theme, checkedTheme); }) .catch(function validationFailure(err) { if (err.errorDetails) { common.logging.error(new common.errors.ThemeValidationError({ message: common.i18n.t('errors.middleware.themehandler.invalidTheme', {theme: activeThemeName}), errorDetails: JSON.stringify(err.errorDetails, null, '\t') })); } // CASE: we have to remember to show errors on blog // `err.context` remembers the theme inside this property self.activate(theme, err.context, err); }); }) .catch(common.errors.NotFoundError, function (err) { // CASE: active theme is missing, we don't want to exit because the admin panel will still work err.message = common.i18n.t('errors.middleware.themehandler.missingTheme', {theme: activeThemeName}); common.logging.error(err); }) .catch(function (err) { // CASE: theme threw an odd error, we don't want to exit because the admin panel will still work // This is the absolute catch-all, at this point, we do not know what went wrong! common.logging.error(err); }); }, // Load themes, soon to be removed and exposed via specific function. loadAll: themeLoader.loadAllThemes, loadOne: themeLoader.loadOneTheme, get storage() { themeStorage = themeStorage || new Storage(); return themeStorage; }, list: require('./list'), validate: validate, toJSON: require('./to-json'), getActive: active.get, activate: function activate(loadedTheme, checkedTheme, error) { // no need to check the score, activation should be used in combination with validate.check // Use the two theme objects to set the current active theme try { active.set(loadedTheme, checkedTheme, error); } catch (err) { common.logging.error(new common.errors.InternalServerError({ message: common.i18n.t('errors.middleware.themehandler.activateFailed', {theme: loadedTheme.name}), err: err })); } }, middleware: require('./middleware') };