Ghost/core/server/services/themes/index.js
2017-12-14 03:01:23 +01:00

96 lines
4.4 KiB
JavaScript

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')
};