From 2ad608e0cb99b97003404adfe52d82cac1a0e3b2 Mon Sep 17 00:00:00 2001 From: Katie Fenn Date: Fri, 30 Jan 2015 22:20:47 +0000 Subject: [PATCH] issue#4519 - Added configurable route keywords - Replaced instances of hard-coded keywords with config - Added keywords to frontend tests stub config --- core/server/api/index.js | 11 +++++++++- core/server/config/index.js | 5 +++++ core/server/config/url.js | 4 ++-- core/server/controllers/frontend.js | 28 +++++++++++++----------- core/server/helpers/meta_description.js | 7 +++--- core/server/helpers/meta_title.js | 7 +++--- core/server/helpers/page_url.js | 6 ++--- core/server/routes/frontend.js | 18 +++++++-------- core/test/unit/frontend_spec.js | 29 ++++++++++++++++++++++--- 9 files changed, 77 insertions(+), 38 deletions(-) diff --git a/core/server/api/index.js b/core/server/api/index.js index 00e3cd590d74..c5046eaa43e2 100644 --- a/core/server/api/index.js +++ b/core/server/api/index.js @@ -80,7 +80,16 @@ cacheInvalidationHeader = function (req, result) { // Don't set x-cache-invalidate header for drafts if (hasStatusChanged || wasDeleted || wasPublishedUpdated) { - cacheInvalidate = '/, /page/*, /rss/, /rss/*, /tag/*, /author/*, /sitemap-*.xml'; + cacheInvalidate = [ + '/', + '/' + config.routeKeywords.page + '/*', + '/rss/', + '/rss/*', + '/' + config.routeKeywords.tag + '/*', + '/' + config.routeKeywords.author + '/*', + '/sitemap-*.xml' + ].join(', '); + if (id && post.slug && post.url) { cacheInvalidate += ', ' + post.url; } diff --git a/core/server/config/index.js b/core/server/config/index.js index a6be1155e0ee..48541ff70a29 100644 --- a/core/server/config/index.js +++ b/core/server/config/index.js @@ -177,6 +177,11 @@ ConfigManager.prototype.set = function (config) { // normalise the URL by removing any trailing slash url: this._config.url ? this._config.url.replace(/\/$/, '') : '' }, + routeKeywords: { + tag: 'tag', + author: 'author', + page: 'page' + }, slugs: { // Used by generateSlug to generate slugs for posts, tags, users, .. // reserved slugs are reserved but can be extended/removed by apps diff --git a/core/server/config/url.js b/core/server/config/url.js index 0d78b58660a8..277a3cea14da 100644 --- a/core/server/config/url.js +++ b/core/server/config/url.js @@ -128,10 +128,10 @@ function urlFor(context, data, absolute) { urlPath = data.post.url; secure = data.secure; } else if (context === 'tag' && data.tag) { - urlPath = '/tag/' + data.tag.slug + '/'; + urlPath = '/' + ghostConfig.routeKeywords.tag + '/' + data.tag.slug + '/'; secure = data.tag.secure; } else if (context === 'author' && data.author) { - urlPath = '/author/' + data.author.slug + '/'; + urlPath = '/' + ghostConfig.routeKeywords.author + '/' + data.author.slug + '/'; secure = data.author.secure; } else if (context === 'image' && data.image) { urlPath = data.image; diff --git a/core/server/controllers/frontend.js b/core/server/controllers/frontend.js index 4a60cf778b7a..1e5d9987b75f 100644 --- a/core/server/controllers/frontend.js +++ b/core/server/controllers/frontend.js @@ -69,23 +69,25 @@ function handleError(next) { function setResponseContext(req, res, data) { var contexts = [], - pageParam = req.params.page !== undefined ? parseInt(req.params.page, 10) : 1; + pageParam = req.params.page !== undefined ? parseInt(req.params.page, 10) : 1, + tagPattern = new RegExp('^\\/' + config.routeKeywords.tag + '\\/'), + authorPattern = new RegExp('^\\/' + config.routeKeywords.author + '\\/'); // paged context if (!isNaN(pageParam) && pageParam > 1) { contexts.push('paged'); } - if (req.route.path === '/page/:page/') { + if (req.route.path === '/' + config.routeKeywords.page + '/:page/') { contexts.push('index'); } else if (req.route.path === '/') { contexts.push('home'); contexts.push('index'); } else if (/\/rss\/(:page\/)?$/.test(req.route.path)) { contexts.push('rss'); - } else if (/^\/tag\//.test(req.route.path)) { + } else if (tagPattern.test(req.route.path)) { contexts.push('tag'); - } else if (/^\/author\//.test(req.route.path)) { + } else if (authorPattern.test(req.route.path)) { contexts.push('author'); } else if (data && data.post && data.post.page) { contexts.push('page'); @@ -170,7 +172,7 @@ frontendControllers = { // Get url for tag page function tagUrl(tag, page) { - var url = config.paths.subdir + '/tag/' + tag + '/'; + var url = config.paths.subdir + '/' + config.routeKeywords.tag + '/' + tag + '/'; if (page && page > 1) { url += 'page/' + page + '/'; @@ -225,10 +227,10 @@ frontendControllers = { // Get url for tag page function authorUrl(author, page) { - var url = config.paths.subdir + '/author/' + author + '/'; + var url = config.paths.subdir + '/' + config.routeKeywords.author + '/' + author + '/'; if (page && page > 1) { - url += 'page/' + page + '/'; + url += config.routeKeywords.page + '/' + page + '/'; } return url; @@ -416,11 +418,11 @@ frontendControllers = { } function isTag() { - return req.route.path.indexOf('/tag/') !== -1; + return req.route.path.indexOf('/' + config.routeKeywords.tag + '/') !== -1; } function isAuthor() { - return req.route.path.indexOf('/author/') !== -1; + return req.route.path.indexOf('/' + config.routeKeywords.author + '/') !== -1; } // Initialize RSS @@ -429,9 +431,9 @@ frontendControllers = { baseUrl = config.paths.subdir; if (isTag()) { - baseUrl += '/tag/' + slugParam + '/rss/'; + baseUrl += '/' + config.routeKeywords.tag + '/' + slugParam + '/rss/'; } else if (isAuthor()) { - baseUrl += '/author/' + slugParam + '/rss/'; + baseUrl += '/' + config.routeKeywords.author + '/' + slugParam + '/rss/'; } else { baseUrl += '/rss/'; } @@ -470,14 +472,14 @@ frontendControllers = { if (isTag()) { if (page.meta.filters.tags) { title = page.meta.filters.tags[0].name + ' - ' + title; - feedUrl = siteUrl + 'tag/' + page.meta.filters.tags[0].slug + '/rss/'; + feedUrl = siteUrl + config.routeKeywords.tag + '/' + page.meta.filters.tags[0].slug + '/rss/'; } } if (isAuthor()) { if (page.meta.filters.author) { title = page.meta.filters.author.name + ' - ' + title; - feedUrl = siteUrl + 'author/' + page.meta.filters.author.slug + '/rss/'; + feedUrl = siteUrl + config.routeKeywords.author + '/' + page.meta.filters.author.slug + '/rss/'; } } diff --git a/core/server/helpers/meta_description.js b/core/server/helpers/meta_description.js index af8ee5ab9e4d..ef89825cca4d 100644 --- a/core/server/helpers/meta_description.js +++ b/core/server/helpers/meta_description.js @@ -13,16 +13,17 @@ var _ = require('lodash'), meta_description = function () { var description, - blog; + blog, + pagePattern = new RegExp('\\/page\\/'); if (_.isString(this.relativeUrl)) { blog = config.theme; if (!this.relativeUrl || this.relativeUrl === '/' || this.relativeUrl === '') { description = blog.description; } else if (this.author) { - description = /\/page\//.test(this.relativeUrl) ? '' : this.author.bio; + description = pagePattern.test(this.relativeUrl) ? '' : this.author.bio; } else if (this.tag) { - if (/\/page\//.test(this.relativeUrl)) { + if (pagePattern.test(this.relativeUrl)) { description = ''; } else { description = _.isEmpty(this.tag.meta_description) ? '' : this.tag.meta_description; diff --git a/core/server/helpers/meta_title.js b/core/server/helpers/meta_title.js index c3bc20b1947c..6ca424a2dd39 100644 --- a/core/server/helpers/meta_title.js +++ b/core/server/helpers/meta_title.js @@ -16,13 +16,12 @@ meta_title = function (options) { var title = '', blog, page, - pageString = ''; + pageString = '', + pagePattern = new RegExp('\\/' + config.routeKeywords.page + '\\/(\\d+)'); if (_.isString(this.relativeUrl)) { blog = config.theme; - - page = this.relativeUrl.match(/\/page\/(\d+)/); - + page = this.relativeUrl.match(pagePattern); if (page) { pageString = ' - Page ' + page[1]; } diff --git a/core/server/helpers/page_url.js b/core/server/helpers/page_url.js index 9a6e0b5ed0d3..9e452442347c 100644 --- a/core/server/helpers/page_url.js +++ b/core/server/helpers/page_url.js @@ -19,15 +19,15 @@ page_url = function (context, block) { var url = config.paths.subdir; if (this.tagSlug !== undefined) { - url += '/tag/' + this.tagSlug; + url += '/' + config.routeKeywords.tag + '/' + this.tagSlug; } if (this.authorSlug !== undefined) { - url += '/author/' + this.authorSlug; + url += '/' + config.routeKeywords.author + '/' + this.authorSlug; } if (context > 1) { - url += '/page/' + context; + url += '/' + config.routeKeywords.page + '/' + context; } url += '/'; diff --git a/core/server/routes/frontend.js b/core/server/routes/frontend.js index efd1df53089e..a2ae12c4c400 100644 --- a/core/server/routes/frontend.js +++ b/core/server/routes/frontend.js @@ -37,19 +37,19 @@ frontendRoutes = function () { }); // Tags - router.get('/tag/:slug/rss/', frontend.rss); - router.get('/tag/:slug/rss/:page/', frontend.rss); - router.get('/tag/:slug/page/:page/', frontend.tag); - router.get('/tag/:slug/', frontend.tag); + router.get('/' + config.routeKeywords.tag + '/:slug/rss/', frontend.rss); + router.get('/' + config.routeKeywords.tag + '/:slug/rss/:page/', frontend.rss); + router.get('/' + config.routeKeywords.tag + '/:slug/' + config.routeKeywords.page + '/:page/', frontend.tag); + router.get('/' + config.routeKeywords.tag + '/:slug/', frontend.tag); // Authors - router.get('/author/:slug/rss/', frontend.rss); - router.get('/author/:slug/rss/:page/', frontend.rss); - router.get('/author/:slug/page/:page/', frontend.author); - router.get('/author/:slug/', frontend.author); + router.get('/' + config.routeKeywords.author + '/:slug/rss/', frontend.rss); + router.get('/' + config.routeKeywords.author + '/:slug/rss/:page/', frontend.rss); + router.get('/' + config.routeKeywords.author + '/:slug/' + config.routeKeywords.page + '/:page/', frontend.author); + router.get('/' + config.routeKeywords.author + '/:slug/', frontend.author); // Default - router.get('/page/:page/', frontend.homepage); + router.get('/' + config.routeKeywords.page + '/:page/', frontend.homepage); router.get('/', frontend.homepage); router.get('*', frontend.single); diff --git a/core/test/unit/frontend_spec.js b/core/test/unit/frontend_spec.js index 9e8ff9e70da1..ce89651cb6f5 100644 --- a/core/test/unit/frontend_spec.js +++ b/core/test/unit/frontend_spec.js @@ -204,6 +204,11 @@ describe('Frontend Controller', function () { 'tag.hbs': '/content/themes/casper/tag.hbs' } } + }, + routeKeywords: { + page: 'page', + tag: 'tag', + author: 'author' } }); }); @@ -257,6 +262,11 @@ describe('Frontend Controller', function () { 'tag.hbs': '/content/themes/casper/tag.hbs' } } + }, + routeKeywords: { + page: 'page', + tag: 'tag', + author: 'author' } }); @@ -359,6 +369,11 @@ describe('Frontend Controller', function () { 'tag.hbs': '/content/themes/casper/tag.hbs' } } + }, + routeKeywords: { + page: 'page', + tag: 'tag', + author: 'author' } }); }); @@ -450,7 +465,8 @@ describe('Frontend Controller', function () { it('Redirects to base tag page if page number is 0 with subdirectory', function () { frontend.__set__('config', { - paths: {subdir: '/blog'} + paths: {subdir: '/blog'}, + routeKeywords: {tag: 'tag'} }); var req = {params: {page: 0, slug: 'pumpkin'}}; @@ -464,7 +480,8 @@ describe('Frontend Controller', function () { it('Redirects to base tag page if page number is 1 with subdirectory', function () { frontend.__set__('config', { - paths: {subdir: '/blog'} + paths: {subdir: '/blog'}, + routeKeywords: {tag: 'tag'} }); var req = {params: {page: 1, slug: 'pumpkin'}}; @@ -489,7 +506,8 @@ describe('Frontend Controller', function () { it('Redirects to last page if page number too big with subdirectory', function (done) { frontend.__set__('config', { - paths: {subdir: '/blog'} + paths: {subdir: '/blog'}, + routeKeywords: {tag: 'tag'} }); var req = {params: {page: 4, slug: 'pumpkin'}}; @@ -583,6 +601,11 @@ describe('Frontend Controller', function () { 'post.hbs': '/content/themes/casper/post.hbs' } } + }, + routeKeywords: { + page: 'page', + tag: 'tag', + author: 'author' } }); });