2019-04-22 18:31:56 +03:00
|
|
|
const _ = require('lodash');
|
2019-01-28 20:06:47 +03:00
|
|
|
const debug = require('ghost-ignition').debug('themes');
|
2020-11-25 15:33:44 +03:00
|
|
|
const {i18n: commonI18n} = require('../proxy');
|
2020-05-28 21:30:23 +03:00
|
|
|
const logging = require('../../../shared/logging');
|
2020-05-22 21:22:20 +03:00
|
|
|
const errors = require('@tryghost/errors');
|
2019-01-28 20:06:47 +03:00
|
|
|
const themeLoader = require('./loader');
|
|
|
|
const active = require('./active');
|
2019-07-01 17:56:23 +03:00
|
|
|
const activate = require('./activate');
|
2019-01-28 20:06:47 +03:00
|
|
|
const validate = require('./validate');
|
2020-03-19 17:07:20 +03:00
|
|
|
const i18n = require('./i18n');
|
2019-07-09 17:35:18 +03:00
|
|
|
const list = require('./list');
|
2019-06-19 12:30:28 +03:00
|
|
|
const settingsCache = require('../../../server/services/settings/cache');
|
2019-01-28 20:06:47 +03:00
|
|
|
const engineDefaults = require('./engines/defaults');
|
|
|
|
|
2017-02-22 02:26:19 +03:00
|
|
|
module.exports = {
|
2017-03-13 19:30:35 +03:00
|
|
|
// Init themes module
|
|
|
|
// TODO: move this once we're clear what needs to happen here
|
|
|
|
init: function initThemes() {
|
2020-04-29 18:44:27 +03:00
|
|
|
const activeThemeName = settingsCache.get('active_theme');
|
2017-03-13 23:13:17 +03:00
|
|
|
|
2021-01-04 07:26:22 +03:00
|
|
|
i18n.init(activeThemeName);
|
2020-03-19 17:07:20 +03:00
|
|
|
|
2017-03-13 19:30:35 +03:00
|
|
|
debug('init themes', activeThemeName);
|
|
|
|
// Just read the active theme for now
|
|
|
|
return themeLoader
|
|
|
|
.loadOneTheme(activeThemeName)
|
2017-03-13 23:13:17 +03:00
|
|
|
.then(function activeThemeHasLoaded(theme) {
|
|
|
|
// Validate
|
|
|
|
return validate
|
|
|
|
.check(theme)
|
2017-10-11 16:19:12 +03:00
|
|
|
.then(function validationSuccess(checkedTheme) {
|
2019-04-22 18:31:56 +03:00
|
|
|
if (!validate.canActivate(checkedTheme)) {
|
2020-05-22 21:22:20 +03:00
|
|
|
const checkError = new errors.ThemeValidationError({
|
|
|
|
message: commonI18n.t('errors.middleware.themehandler.invalidTheme', {theme: activeThemeName}),
|
2019-04-22 18:31:56 +03:00
|
|
|
errorDetails: Object.assign(
|
|
|
|
_.pick(checkedTheme, ['checkedVersion', 'name', 'path', 'version']), {
|
|
|
|
errors: checkedTheme.results.error
|
|
|
|
}
|
|
|
|
)
|
|
|
|
});
|
|
|
|
|
2020-05-22 21:22:20 +03:00
|
|
|
logging.error(checkError);
|
2017-05-31 19:42:42 +03:00
|
|
|
|
2019-07-01 17:56:23 +03:00
|
|
|
activate(theme, checkedTheme, checkError);
|
2019-04-22 18:31:56 +03:00
|
|
|
} else {
|
|
|
|
// CASE: inform that the theme has errors, but not fatal (theme still works)
|
|
|
|
if (checkedTheme.results.error.length) {
|
2020-05-22 21:22:20 +03:00
|
|
|
logging.warn(new errors.ThemeValidationError({
|
2019-04-22 18:31:56 +03:00
|
|
|
errorType: 'ThemeWorksButHasErrors',
|
2020-05-22 21:22:20 +03:00
|
|
|
message: commonI18n.t('errors.middleware.themehandler.themeHasErrors', {theme: activeThemeName}),
|
2019-04-22 18:31:56 +03:00
|
|
|
errorDetails: Object.assign(
|
|
|
|
_.pick(checkedTheme, ['checkedVersion', 'name', 'path', 'version']), {
|
|
|
|
errors: checkedTheme.results.error
|
|
|
|
}
|
|
|
|
)
|
|
|
|
}));
|
|
|
|
}
|
|
|
|
|
|
|
|
debug('Activating theme (method A on boot)', activeThemeName);
|
|
|
|
|
2019-07-01 17:56:23 +03:00
|
|
|
activate(theme, checkedTheme);
|
2019-04-22 18:31:56 +03:00
|
|
|
}
|
2017-03-13 23:13:17 +03:00
|
|
|
});
|
|
|
|
})
|
2020-05-22 21:22:20 +03:00
|
|
|
.catch(errors.NotFoundError, function (err) {
|
2017-05-31 19:42:42 +03:00
|
|
|
// CASE: active theme is missing, we don't want to exit because the admin panel will still work
|
2020-05-22 21:22:20 +03:00
|
|
|
err.message = commonI18n.t('errors.middleware.themehandler.missingTheme', {theme: activeThemeName});
|
|
|
|
logging.error(err);
|
2017-10-11 16:19:12 +03:00
|
|
|
})
|
|
|
|
.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!
|
2020-05-22 21:22:20 +03:00
|
|
|
logging.error(err);
|
2017-03-13 19:30:35 +03:00
|
|
|
});
|
|
|
|
},
|
2019-07-09 17:35:18 +03:00
|
|
|
getJSON: require('./to-json'),
|
2017-03-13 23:13:17 +03:00
|
|
|
getActive: active.get,
|
2019-01-28 20:06:47 +03:00
|
|
|
getApiVersion: function getApiVersion() {
|
|
|
|
if (this.getActive()) {
|
|
|
|
return this.getActive().engine('ghost-api');
|
|
|
|
} else {
|
|
|
|
return engineDefaults['ghost-api'];
|
|
|
|
}
|
|
|
|
},
|
2019-07-01 17:56:23 +03:00
|
|
|
activate: function (themeName) {
|
2019-07-09 17:35:18 +03:00
|
|
|
const loadedTheme = list.get(themeName);
|
2019-01-03 22:30:35 +03:00
|
|
|
|
2019-07-01 17:56:23 +03:00
|
|
|
if (!loadedTheme) {
|
2020-05-22 21:22:20 +03:00
|
|
|
return Promise.reject(new errors.ValidationError({
|
|
|
|
message: commonI18n.t('notices.data.validation.index.themeCannotBeActivated', {themeName: themeName}),
|
2019-07-01 17:56:23 +03:00
|
|
|
errorDetails: themeName
|
2017-10-11 16:19:12 +03:00
|
|
|
}));
|
|
|
|
}
|
2019-07-01 17:56:23 +03:00
|
|
|
|
|
|
|
return validate.checkSafe(loadedTheme)
|
|
|
|
.then((checkedTheme) => {
|
|
|
|
debug('Activating theme (method B on API "activate")', themeName);
|
|
|
|
activate(loadedTheme, checkedTheme);
|
|
|
|
|
|
|
|
return checkedTheme;
|
|
|
|
});
|
2017-03-21 12:03:09 +03:00
|
|
|
},
|
2019-07-09 17:35:18 +03:00
|
|
|
storage: require('./storage'),
|
2020-04-08 21:02:31 +03:00
|
|
|
middleware: require('./middleware'),
|
2021-02-22 20:30:25 +03:00
|
|
|
loadCoreHelpers: require('./handlebars/helpers').loadCoreHelpers,
|
|
|
|
/**
|
|
|
|
* Load all inactive themes
|
|
|
|
*/
|
|
|
|
loadInactiveThemes: async () => {
|
|
|
|
return await themeLoader.loadAllThemes();
|
|
|
|
}
|
2017-02-22 02:26:19 +03:00
|
|
|
};
|