Ghost/core/frontend/services/routing/StaticRoutesRouter.js
Hannah Wolfe 4f9b72ff43
Renamed middlewares to middleware consistently
- This is a minor bugbare, but it will affect some configuration I'm about to do for c8
- I've been wanting to do it for ages, middleware is plural all on it's own so it's an odd affectation in our codebase
- This also only exists in 2 places, everywhere else we use "middleware"
- Sadly it did result in a lot of churn as I did a full find and replace, but consistency is king!
2021-11-16 15:51:47 +00:00

143 lines
4.6 KiB
JavaScript

const debug = require('@tryghost/debug')('routing:static-routes-router');
const errors = require('@tryghost/errors');
const urlUtils = require('../../../shared/url-utils');
const RSSRouter = require('./RSSRouter');
const controllers = require('./controllers');
const middleware = require('./middleware');
const ParentRouter = require('./ParentRouter');
/**
* @description Template routes allow you to map individual URLs to specific template files within a Ghost theme
*/
class StaticRoutesRouter extends ParentRouter {
constructor(mainRoute, object, routerCreated) {
super('StaticRoutesRouter');
this.route = {value: mainRoute};
this.templates = object.templates || [];
this.data = object.data || {query: {}, router: {}};
this.routerName = mainRoute === '/' ? 'index' : mainRoute.replace(/\//g, '');
this.routerCreated = routerCreated;
debug(this.route.value, this.templates);
// CASE 1: Route is channel (controller: channel) - a stream of posts
// CASE 2: Route is just a static page e.g. landing page
if (this.isChannel(object)) {
this.templates = this.templates.reverse();
this.rss = object.rss !== false;
this.filter = object.filter;
this.limit = object.limit;
this.order = object.order;
this.controller = object.controller;
debug(this.route.value, this.templates, this.filter, this.data);
this._registerChannelRoutes();
} else {
this.contentType = object.content_type;
debug(this.route.value, this.templates);
this._registerStaticRoute();
}
}
/**
* @description Register all channel routes of this router (...if the router is a channel)
* @private
*/
_registerChannelRoutes() {
// REGISTER: prepare context object
this.router().use(this._prepareChannelContext.bind(this));
// REGISTER: is rss enabled?
if (this.rss) {
this.rssRouter = new RSSRouter();
this.mountRouter(this.route.value, this.rssRouter.router());
}
// REGISTER: channel route
this.mountRoute(this.route.value, controllers[this.controller]);
// REGISTER: pagination
this.router().param('page', middleware.pageParam);
this.mountRoute(urlUtils.urlJoin(this.route.value, 'page', ':page(\\d+)'), controllers[this.controller]);
this.routerCreated(this);
}
/**
* @description Prepare channel context for further middleware/controllers.
* @param {Object} req
* @param {Object} res
* @param {Function} next
* @private
*/
_prepareChannelContext(req, res, next) {
res.routerOptions = {
type: this.controller,
name: this.routerName,
context: [this.routerName],
filter: this.filter,
limit: this.limit,
order: this.order,
data: this.data.query,
templates: this.templates
};
next();
}
/**
* @description Register all static routes of this router (...if the router is just a static route)
* @private
*/
_registerStaticRoute() {
// REGISTER: prepare context object
this.router().use(this._prepareStaticRouteContext.bind(this));
// REGISTER: static route
this.mountRoute(this.route.value, controllers.static);
this.routerCreated(this);
}
/**
* @description Prepare static route context for further middleware/controllers.
* @param {Object} req
* @param {Object} res
* @param {Function} next
* @private
*/
_prepareStaticRouteContext(req, res, next) {
res.routerOptions = {
type: 'custom',
templates: this.templates,
defaultTemplate: () => {
throw new errors.IncorrectUsageError({
message: `Missing template ${res.routerOptions.templates.map(x => `${x}.hbs`).join(', ')} for route "${req.originalUrl}".`
});
},
data: this.data.query,
context: [this.routerName],
contentType: this.contentType
};
next();
}
/**
* @description Helper function to figure out if this router is a channel.
* @param {Object} object
* @returns {boolean}
*/
isChannel(object) {
if (object && object.controller && object.controller === 'channel') {
return true;
}
return this.controller === 'channel';
}
}
module.exports = StaticRoutesRouter;