Moved activate from themes to the bridge
refs: https://github.com/TryGhost/Ghost/commit/bf0823c9a2ddbc93ad0ddcec36eed130c8c5a203
- continuing the work of splitting up the theme service into logical components
Theme activations are a trickier piece of the theme split puzzle because they are called from the API and theme service on boot in different ways.
Activations require a theme to have been validated at different levels. Validations are also tricky - do they belong to the theme engine, or the theme service?
There are then several different flows for activations:
- On Boot
- API "activate" call
- API override on upload or install via setFromZip, which is a method in the storage layer
These calls all have quite different logical flows at the moment, and need to be unified
For now, I've moved the existing "activate" function onto the bridge. This allows the theme service to be split from the frontend, and refactoring can start from there.
I hope to move this so there is less code in the actual bridge very soon, but my goal is not to require any server packages in the frontend part of this
I think ideally:
- all activation code, including validation, should probably be part of the theme engine
- the theme engine should offer 3 methods: getActive() canActivate() and activate()
- the theme service is then only responsible for loading themes in and out of storage, JSON responses for the API, and handing themes to the frontend via the bridge at the appropriate moment
2021-04-27 14:49:48 +03:00
|
|
|
/**
|
|
|
|
* The Bridge
|
|
|
|
*
|
|
|
|
* The bridge is responsible for handing communication from the server to the frontend.
|
|
|
|
* Data should only be flowing server -> frontend.
|
|
|
|
* As the architecture improves, the number of cross requires here should go down
|
2021-09-23 19:36:32 +03:00
|
|
|
* Eventually, the aim is to make this a component that is initialized on boot and is either handed to or actively creates the frontend, if the frontend is desired.
|
Moved activate from themes to the bridge
refs: https://github.com/TryGhost/Ghost/commit/bf0823c9a2ddbc93ad0ddcec36eed130c8c5a203
- continuing the work of splitting up the theme service into logical components
Theme activations are a trickier piece of the theme split puzzle because they are called from the API and theme service on boot in different ways.
Activations require a theme to have been validated at different levels. Validations are also tricky - do they belong to the theme engine, or the theme service?
There are then several different flows for activations:
- On Boot
- API "activate" call
- API override on upload or install via setFromZip, which is a method in the storage layer
These calls all have quite different logical flows at the moment, and need to be unified
For now, I've moved the existing "activate" function onto the bridge. This allows the theme service to be split from the frontend, and refactoring can start from there.
I hope to move this so there is less code in the actual bridge very soon, but my goal is not to require any server packages in the frontend part of this
I think ideally:
- all activation code, including validation, should probably be part of the theme engine
- the theme engine should offer 3 methods: getActive() canActivate() and activate()
- the theme service is then only responsible for loading themes in and out of storage, JSON responses for the API, and handing themes to the frontend via the bridge at the appropriate moment
2021-04-27 14:49:48 +03:00
|
|
|
*
|
|
|
|
* This file is a great place for all the cross-component event handling in lieu of refactoring
|
2021-09-30 17:43:37 +03:00
|
|
|
* NOTE: You may require anything from shared, the frontend or server here - it is the one place (other than boot) that is allowed :)
|
Moved activate from themes to the bridge
refs: https://github.com/TryGhost/Ghost/commit/bf0823c9a2ddbc93ad0ddcec36eed130c8c5a203
- continuing the work of splitting up the theme service into logical components
Theme activations are a trickier piece of the theme split puzzle because they are called from the API and theme service on boot in different ways.
Activations require a theme to have been validated at different levels. Validations are also tricky - do they belong to the theme engine, or the theme service?
There are then several different flows for activations:
- On Boot
- API "activate" call
- API override on upload or install via setFromZip, which is a method in the storage layer
These calls all have quite different logical flows at the moment, and need to be unified
For now, I've moved the existing "activate" function onto the bridge. This allows the theme service to be split from the frontend, and refactoring can start from there.
I hope to move this so there is less code in the actual bridge very soon, but my goal is not to require any server packages in the frontend part of this
I think ideally:
- all activation code, including validation, should probably be part of the theme engine
- the theme engine should offer 3 methods: getActive() canActivate() and activate()
- the theme service is then only responsible for loading themes in and out of storage, JSON responses for the API, and handing themes to the frontend via the bridge at the appropriate moment
2021-04-27 14:49:48 +03:00
|
|
|
*/
|
2021-07-06 13:02:37 +03:00
|
|
|
|
|
|
|
const debug = require('@tryghost/debug')('bridge');
|
Moved activate from themes to the bridge
refs: https://github.com/TryGhost/Ghost/commit/bf0823c9a2ddbc93ad0ddcec36eed130c8c5a203
- continuing the work of splitting up the theme service into logical components
Theme activations are a trickier piece of the theme split puzzle because they are called from the API and theme service on boot in different ways.
Activations require a theme to have been validated at different levels. Validations are also tricky - do they belong to the theme engine, or the theme service?
There are then several different flows for activations:
- On Boot
- API "activate" call
- API override on upload or install via setFromZip, which is a method in the storage layer
These calls all have quite different logical flows at the moment, and need to be unified
For now, I've moved the existing "activate" function onto the bridge. This allows the theme service to be split from the frontend, and refactoring can start from there.
I hope to move this so there is less code in the actual bridge very soon, but my goal is not to require any server packages in the frontend part of this
I think ideally:
- all activation code, including validation, should probably be part of the theme engine
- the theme engine should offer 3 methods: getActive() canActivate() and activate()
- the theme service is then only responsible for loading themes in and out of storage, JSON responses for the API, and handing themes to the frontend via the bridge at the appropriate moment
2021-04-27 14:49:48 +03:00
|
|
|
const errors = require('@tryghost/errors');
|
2021-06-15 17:36:27 +03:00
|
|
|
const logging = require('@tryghost/logging');
|
2021-06-24 22:01:29 +03:00
|
|
|
const tpl = require('@tryghost/tpl');
|
2021-04-26 16:38:57 +03:00
|
|
|
const themeEngine = require('./frontend/services/theme-engine');
|
2021-11-23 15:47:46 +03:00
|
|
|
const cardAssetService = require('./frontend/services/card-assets');
|
2021-10-18 21:01:38 +03:00
|
|
|
const routerManager = require('./frontend/services/routing').routerManager;
|
2021-06-30 16:56:57 +03:00
|
|
|
const settingsCache = require('./shared/settings-cache');
|
2021-04-23 16:19:18 +03:00
|
|
|
|
2021-07-07 17:49:45 +03:00
|
|
|
// Listen to settings.lang.edited, similar to the member service and models/base/listeners
|
|
|
|
const events = require('./server/lib/common/events');
|
|
|
|
|
2021-06-24 22:01:29 +03:00
|
|
|
const messages = {
|
|
|
|
activateFailed: 'Unable to activate the theme "{theme}".'
|
|
|
|
};
|
|
|
|
|
2021-04-23 16:19:18 +03:00
|
|
|
class Bridge {
|
2021-11-22 13:51:23 +03:00
|
|
|
init() {
|
2021-04-26 13:53:15 +03:00
|
|
|
/**
|
|
|
|
* When locale changes, we reload theme translations
|
2021-06-09 18:32:48 +03:00
|
|
|
* @deprecated: the term "lang" was deprecated in favor of "locale" publicly in 4.0
|
2021-04-26 13:53:15 +03:00
|
|
|
*/
|
2021-05-04 18:49:35 +03:00
|
|
|
events.on('settings.lang.edited', (model) => {
|
2021-07-06 13:38:52 +03:00
|
|
|
debug('Active theme init18n');
|
2021-05-04 18:49:35 +03:00
|
|
|
this.getActiveTheme().initI18n({locale: model.get('value')});
|
2021-04-26 13:53:15 +03:00
|
|
|
});
|
2021-10-14 20:10:36 +03:00
|
|
|
|
|
|
|
// NOTE: eventually this event should somehow be listened on and handled by the URL Service
|
|
|
|
// for now this eliminates the need for the frontend routing to listen to
|
|
|
|
// server events
|
|
|
|
events.on('settings.timezone.edited', (model) => {
|
2021-10-18 21:01:38 +03:00
|
|
|
routerManager.handleTimezoneEdit(model);
|
2021-10-14 20:10:36 +03:00
|
|
|
});
|
2021-04-23 16:19:18 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
getActiveTheme() {
|
|
|
|
return themeEngine.getActive();
|
|
|
|
}
|
|
|
|
|
2021-11-23 20:02:09 +03:00
|
|
|
async activateTheme(loadedTheme, checkedTheme) {
|
2021-05-04 18:49:35 +03:00
|
|
|
let settings = {
|
|
|
|
locale: settingsCache.get('lang')
|
|
|
|
};
|
Moved activate from themes to the bridge
refs: https://github.com/TryGhost/Ghost/commit/bf0823c9a2ddbc93ad0ddcec36eed130c8c5a203
- continuing the work of splitting up the theme service into logical components
Theme activations are a trickier piece of the theme split puzzle because they are called from the API and theme service on boot in different ways.
Activations require a theme to have been validated at different levels. Validations are also tricky - do they belong to the theme engine, or the theme service?
There are then several different flows for activations:
- On Boot
- API "activate" call
- API override on upload or install via setFromZip, which is a method in the storage layer
These calls all have quite different logical flows at the moment, and need to be unified
For now, I've moved the existing "activate" function onto the bridge. This allows the theme service to be split from the frontend, and refactoring can start from there.
I hope to move this so there is less code in the actual bridge very soon, but my goal is not to require any server packages in the frontend part of this
I think ideally:
- all activation code, including validation, should probably be part of the theme engine
- the theme engine should offer 3 methods: getActive() canActivate() and activate()
- the theme service is then only responsible for loading themes in and out of storage, JSON responses for the API, and handing themes to the frontend via the bridge at the appropriate moment
2021-04-27 14:49:48 +03:00
|
|
|
// 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 {
|
|
|
|
let previousGhostAPI;
|
|
|
|
|
|
|
|
if (this.getActiveTheme()) {
|
|
|
|
previousGhostAPI = this.getActiveTheme().engine('ghost-api');
|
|
|
|
}
|
|
|
|
|
2021-09-23 19:39:43 +03:00
|
|
|
themeEngine.setActive(settings, loadedTheme, checkedTheme);
|
Moved activate from themes to the bridge
refs: https://github.com/TryGhost/Ghost/commit/bf0823c9a2ddbc93ad0ddcec36eed130c8c5a203
- continuing the work of splitting up the theme service into logical components
Theme activations are a trickier piece of the theme split puzzle because they are called from the API and theme service on boot in different ways.
Activations require a theme to have been validated at different levels. Validations are also tricky - do they belong to the theme engine, or the theme service?
There are then several different flows for activations:
- On Boot
- API "activate" call
- API override on upload or install via setFromZip, which is a method in the storage layer
These calls all have quite different logical flows at the moment, and need to be unified
For now, I've moved the existing "activate" function onto the bridge. This allows the theme service to be split from the frontend, and refactoring can start from there.
I hope to move this so there is less code in the actual bridge very soon, but my goal is not to require any server packages in the frontend part of this
I think ideally:
- all activation code, including validation, should probably be part of the theme engine
- the theme engine should offer 3 methods: getActive() canActivate() and activate()
- the theme service is then only responsible for loading themes in and out of storage, JSON responses for the API, and handing themes to the frontend via the bridge at the appropriate moment
2021-04-27 14:49:48 +03:00
|
|
|
const currentGhostAPI = this.getActiveTheme().engine('ghost-api');
|
|
|
|
|
|
|
|
if (previousGhostAPI !== undefined && (previousGhostAPI !== currentGhostAPI)) {
|
|
|
|
events.emit('services.themes.api.changed');
|
2021-11-23 20:02:09 +03:00
|
|
|
await this.reloadFrontend();
|
Moved activate from themes to the bridge
refs: https://github.com/TryGhost/Ghost/commit/bf0823c9a2ddbc93ad0ddcec36eed130c8c5a203
- continuing the work of splitting up the theme service into logical components
Theme activations are a trickier piece of the theme split puzzle because they are called from the API and theme service on boot in different ways.
Activations require a theme to have been validated at different levels. Validations are also tricky - do they belong to the theme engine, or the theme service?
There are then several different flows for activations:
- On Boot
- API "activate" call
- API override on upload or install via setFromZip, which is a method in the storage layer
These calls all have quite different logical flows at the moment, and need to be unified
For now, I've moved the existing "activate" function onto the bridge. This allows the theme service to be split from the frontend, and refactoring can start from there.
I hope to move this so there is less code in the actual bridge very soon, but my goal is not to require any server packages in the frontend part of this
I think ideally:
- all activation code, including validation, should probably be part of the theme engine
- the theme engine should offer 3 methods: getActive() canActivate() and activate()
- the theme service is then only responsible for loading themes in and out of storage, JSON responses for the API, and handing themes to the frontend via the bridge at the appropriate moment
2021-04-27 14:49:48 +03:00
|
|
|
}
|
2021-11-23 20:00:59 +03:00
|
|
|
|
|
|
|
const cardAssetConfig = this.getCardAssetConfig();
|
|
|
|
debug('reload card assets config', cardAssetConfig);
|
2021-11-23 20:02:09 +03:00
|
|
|
await cardAssetService.load(cardAssetConfig);
|
Moved activate from themes to the bridge
refs: https://github.com/TryGhost/Ghost/commit/bf0823c9a2ddbc93ad0ddcec36eed130c8c5a203
- continuing the work of splitting up the theme service into logical components
Theme activations are a trickier piece of the theme split puzzle because they are called from the API and theme service on boot in different ways.
Activations require a theme to have been validated at different levels. Validations are also tricky - do they belong to the theme engine, or the theme service?
There are then several different flows for activations:
- On Boot
- API "activate" call
- API override on upload or install via setFromZip, which is a method in the storage layer
These calls all have quite different logical flows at the moment, and need to be unified
For now, I've moved the existing "activate" function onto the bridge. This allows the theme service to be split from the frontend, and refactoring can start from there.
I hope to move this so there is less code in the actual bridge very soon, but my goal is not to require any server packages in the frontend part of this
I think ideally:
- all activation code, including validation, should probably be part of the theme engine
- the theme engine should offer 3 methods: getActive() canActivate() and activate()
- the theme service is then only responsible for loading themes in and out of storage, JSON responses for the API, and handing themes to the frontend via the bridge at the appropriate moment
2021-04-27 14:49:48 +03:00
|
|
|
} catch (err) {
|
|
|
|
logging.error(new errors.InternalServerError({
|
2021-06-24 22:01:29 +03:00
|
|
|
message: tpl(messages.activateFailed, {theme: loadedTheme.name}),
|
Moved activate from themes to the bridge
refs: https://github.com/TryGhost/Ghost/commit/bf0823c9a2ddbc93ad0ddcec36eed130c8c5a203
- continuing the work of splitting up the theme service into logical components
Theme activations are a trickier piece of the theme split puzzle because they are called from the API and theme service on boot in different ways.
Activations require a theme to have been validated at different levels. Validations are also tricky - do they belong to the theme engine, or the theme service?
There are then several different flows for activations:
- On Boot
- API "activate" call
- API override on upload or install via setFromZip, which is a method in the storage layer
These calls all have quite different logical flows at the moment, and need to be unified
For now, I've moved the existing "activate" function onto the bridge. This allows the theme service to be split from the frontend, and refactoring can start from there.
I hope to move this so there is less code in the actual bridge very soon, but my goal is not to require any server packages in the frontend part of this
I think ideally:
- all activation code, including validation, should probably be part of the theme engine
- the theme engine should offer 3 methods: getActive() canActivate() and activate()
- the theme service is then only responsible for loading themes in and out of storage, JSON responses for the API, and handing themes to the frontend via the bridge at the appropriate moment
2021-04-27 14:49:48 +03:00
|
|
|
err: err
|
|
|
|
}));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-04-23 16:19:18 +03:00
|
|
|
getFrontendApiVersion() {
|
2022-02-17 20:51:11 +03:00
|
|
|
// @NOTE: we've pinned the frontend to canary in a step towards removing API versions
|
|
|
|
return 'canary';
|
2021-04-23 16:19:18 +03:00
|
|
|
}
|
2021-06-27 15:38:48 +03:00
|
|
|
|
2021-10-13 10:45:56 +03:00
|
|
|
getCardAssetConfig() {
|
|
|
|
if (this.getActiveTheme()) {
|
|
|
|
return this.getActiveTheme().config('card_assets');
|
|
|
|
} else {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-11-23 20:02:09 +03:00
|
|
|
async reloadFrontend() {
|
2021-06-27 15:38:48 +03:00
|
|
|
const apiVersion = this.getFrontendApiVersion();
|
2021-10-13 10:45:56 +03:00
|
|
|
|
2021-07-06 13:02:37 +03:00
|
|
|
debug('reload frontend', apiVersion);
|
2021-10-21 21:43:48 +03:00
|
|
|
const siteApp = require('./frontend/web/site');
|
2021-11-23 20:02:09 +03:00
|
|
|
await siteApp.reload({apiVersion});
|
2021-06-27 15:38:48 +03:00
|
|
|
}
|
2021-04-23 16:19:18 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
const bridge = new Bridge();
|
|
|
|
|
|
|
|
module.exports = bridge;
|