mirror of
https://github.com/TryGhost/Ghost.git
synced 2025-02-10 23:36:14 -05:00
refs https://github.com/TryGhost/Toolbox/issues/127 - Wasn't able to find any references to the "originalValue" field in permalinks, so removed it to keep the code clean and readable
160 lines
5.1 KiB
JavaScript
160 lines
5.1 KiB
JavaScript
const debug = require('@tryghost/debug')('routing:collection-router');
|
|
const urlUtils = require('../../../shared/url-utils');
|
|
const ParentRouter = require('./ParentRouter');
|
|
|
|
const controllers = require('./controllers');
|
|
const middlewares = require('./middlewares');
|
|
const RSSRouter = require('./RSSRouter');
|
|
|
|
/**
|
|
* @description Collection Router for post resource.
|
|
*
|
|
* Fundamental router to define where resources live and how their url structure is.
|
|
*/
|
|
class CollectionRouter extends ParentRouter {
|
|
constructor(mainRoute, object, RESOURCE_CONFIG, routerCreated) {
|
|
super('CollectionRouter');
|
|
|
|
this.RESOURCE_CONFIG = RESOURCE_CONFIG.QUERY.post;
|
|
|
|
this.routerName = mainRoute === '/' ? 'index' : mainRoute.replace(/\//g, '');
|
|
|
|
// NOTE: this.route === index/parent route e.g. /, /podcast/, /magic/
|
|
this.route = {
|
|
value: mainRoute
|
|
};
|
|
|
|
this.rss = object.rss !== false;
|
|
|
|
this.permalinks = {
|
|
value: object.permalink
|
|
};
|
|
|
|
// @NOTE: see helpers/templates - we use unshift to prepend the templates
|
|
this.templates = (object.templates || []).reverse();
|
|
|
|
this.filter = object.filter;
|
|
this.data = object.data || {query: {}, router: {}};
|
|
this.order = object.order;
|
|
this.limit = object.limit;
|
|
|
|
this.permalinks.getValue = (options) => {
|
|
options = options || {};
|
|
|
|
// @NOTE: url options are only required when registering urls in express.
|
|
// e.g. the UrlService will access the routes and doesn't want to know about possible url options
|
|
if (options.withUrlOptions) {
|
|
return urlUtils.urlJoin(this.permalinks.value, '/:options(edit)?/');
|
|
}
|
|
|
|
return this.permalinks.value;
|
|
};
|
|
|
|
this.context = [this.routerName];
|
|
this.routerCreated = routerCreated;
|
|
|
|
debug(this.name, this.route, this.permalinks);
|
|
|
|
this._registerRoutes();
|
|
}
|
|
|
|
/**
|
|
* @description Register all routes of this router.
|
|
* @private
|
|
*/
|
|
_registerRoutes() {
|
|
// REGISTER: context middleware for this collection
|
|
this.router().use(this._prepareEntriesContext.bind(this));
|
|
|
|
// REGISTER: collection route e.g. /, /podcast/
|
|
this.mountRoute(this.route.value, controllers.collection);
|
|
|
|
// REGISTER: enable pagination by default
|
|
this.router().param('page', middlewares.pageParam);
|
|
this.mountRoute(urlUtils.urlJoin(this.route.value, 'page', ':page(\\d+)'), controllers.collection);
|
|
|
|
// REGISTER: is rss enabled?
|
|
if (this.rss) {
|
|
this.rssRouter = new RSSRouter();
|
|
this.mountRouter(this.route.value, this.rssRouter.router());
|
|
}
|
|
|
|
// REGISTER: context middleware for entries
|
|
this.router().use(this._prepareEntryContext.bind(this));
|
|
|
|
// REGISTER: page/post resource redirects
|
|
this.router().param('slug', this._respectDominantRouter.bind(this));
|
|
|
|
// REGISTER: permalinks e.g. /:slug/, /podcast/:slug
|
|
this.mountRoute(this.permalinks.getValue({withUrlOptions: true}), controllers.entry);
|
|
|
|
this.routerCreated(this);
|
|
}
|
|
|
|
/**
|
|
* @description Prepare index context for further middlewares/controllers.
|
|
*/
|
|
_prepareEntriesContext(req, res, next) {
|
|
res.routerOptions = {
|
|
type: 'collection',
|
|
filter: this.filter,
|
|
limit: this.limit,
|
|
order: this.order,
|
|
permalinks: this.permalinks.getValue({withUrlOptions: true}),
|
|
resourceType: this.getResourceType(),
|
|
query: this.RESOURCE_CONFIG,
|
|
context: this.context,
|
|
frontPageTemplate: 'home',
|
|
templates: this.templates,
|
|
identifier: this.identifier,
|
|
name: this.routerName,
|
|
data: this.data.query
|
|
};
|
|
|
|
next();
|
|
}
|
|
|
|
/**
|
|
* @description Prepare entry context for further middlewares/controllers.
|
|
*/
|
|
_prepareEntryContext(req, res, next) {
|
|
res.routerOptions.context = ['post'];
|
|
res.routerOptions.type = 'entry';
|
|
next();
|
|
}
|
|
|
|
/**
|
|
* @description Get resource type of this router (always "posts")
|
|
* @returns {string}
|
|
*/
|
|
getResourceType() {
|
|
// @TODO: resourceAlias can be removed? We removed it. Looks like a last left over. Needs double checking.
|
|
return this.RESOURCE_CONFIG.resourceAlias || this.RESOURCE_CONFIG.resource;
|
|
}
|
|
|
|
/**
|
|
* @description Get index route e.g. /, /blog/
|
|
* @param {Object} options
|
|
* @returns {String}
|
|
*/
|
|
getRoute(options) {
|
|
options = options || {};
|
|
|
|
return urlUtils.createUrl(this.route.value, options.absolute, options.secure);
|
|
}
|
|
|
|
/**
|
|
* @description Generate rss url.
|
|
* @param {Object} options
|
|
* @returns {String}
|
|
*/
|
|
getRssUrl(options) {
|
|
if (!this.rss) {
|
|
return null;
|
|
}
|
|
|
|
return urlUtils.createUrl(urlUtils.urlJoin(this.route.value, this.rssRouter.route.value), options.absolute, options.secure);
|
|
}
|
|
}
|
|
|
|
module.exports = CollectionRouter;
|