Ghost/core/frontend/services/theme-engine/active.js
Hannah Wolfe 362140b31e
Removed passing of error to active theme
refs:  076ad99593

- as of 076ad99593 we no longer use the error property of the active theme anywhere
- cleaning up and removing this usage reduces the code pathways and makes the init fn a bit clearer
2021-07-07 14:38:08 +01:00

150 lines
4.5 KiB
JavaScript

/**
* # Active Theme
*
* This file defines a class of active theme, and also controls the getting and setting a single instance, as there
* can only ever be one active theme. Unlike a singleton, the active theme can change, however only in a controlled way.
*
* There are several different patterns available for keeping data private. Elsewhere in Ghost we use the
* naming convention of the _ prefix. Even though this has the downside of not being truly private, it is still one
* of the preferred options for keeping data private with the new class syntax, therefore I have kept it.
*
* No properties marked with an _ should be used directly.
*
*/
const join = require('path').join;
const _ = require('lodash');
const themeConfig = require('./config');
const themeEngines = require('./engines');
const config = require('../../../shared/config');
const engine = require('./engine');
const themeI18n = require('./i18n');
// Current instance of ActiveTheme
let currentActiveTheme;
class ActiveTheme {
/**
* @TODO this API needs to be simpler, but for now should work!
* @param {object} settings
* @param {string} settings.locale - the active locale for i18n
* @param {object} loadedTheme - the loaded theme object from the theme list
* @param {object} checkedTheme - the result of gscan.format for the theme we're activating
*/
constructor(settings, loadedTheme, checkedTheme) {
// Assign some data, mark it all as pseudo-private
this._name = loadedTheme.name;
this._path = loadedTheme.path;
this._mounted = false;
// We get passed in a locale
this._locale = settings.locale || 'en';
// @TODO: get gscan to return validated, useful package.json fields for us!
this._packageInfo = loadedTheme['package.json'];
this._partials = checkedTheme.partials;
// all custom .hbs templates (e.g. custom-about)
this._customTemplates = checkedTheme.templates.custom;
// all .hbs templates
this._templates = checkedTheme.templates.all;
// Create a theme config object
this._config = themeConfig.create(this._packageInfo);
// Create a theme engines object
this._engines = themeEngines.create(this._packageInfo);
this.initI18n();
}
get name() {
return this._name;
}
get customTemplates() {
return this._customTemplates;
}
get path() {
return this._path;
}
get partialsPath() {
return this._partials.length > 0 ? join(this.path, 'partials') : null;
}
get mounted() {
return this._mounted;
}
get error() {
return this._error;
}
hasTemplate(templateName) {
return this._templates.indexOf(templateName) > -1;
}
updateTemplateOptions(options) {
engine.updateTemplateOptions(_.merge({}, engine.getTemplateOptions(), options));
}
config(key) {
return this._config[key];
}
engine(key) {
return this._engines[key];
}
/**
*
* @param {object} options
* @param {string} [options.activeTheme]
* @param {string} [options.locale]
*/
initI18n(options = {}) {
options.activeTheme = options.activeTheme || this._name;
options.locale = options.locale || this._locale;
themeI18n.init(options);
}
mount(siteApp) {
// reset the asset hash
// @TODO: set this on the theme instead of globally, or use proper file-based hash
config.set('assetHash', null);
// clear the view cache
siteApp.cache = {};
// Set the views and engine
siteApp.set('views', this.path);
siteApp.engine('hbs', engine.configure(this.partialsPath));
this._mounted = true;
}
}
module.exports = {
get() {
return currentActiveTheme;
},
/**
* Set theme
*
* At this point we trust that the theme has been validated.
* Any handling for invalid themes should happen before we get here
*
* @param {object} settings
* @param {string} settings.locale - the active locale for i18n
* @param {object} loadedTheme - the loaded theme object from the theme list
* @param {object} checkedTheme - the result of gscan.format for the theme we're activating
* @return {ActiveTheme}
*/
set(settings, loadedTheme, checkedTheme) {
currentActiveTheme = new ActiveTheme(settings, loadedTheme, checkedTheme);
return currentActiveTheme;
}
};