From d43d3b6a96f72f808f9acd6cb4ef8792dec57418 Mon Sep 17 00:00:00 2001 From: ULIVZ <472590061@qq.com> Date: Fri, 8 Feb 2019 22:13:26 +0800 Subject: [PATCH 1/2] feat($core): handle redirect for clean urls --- packages/@vuepress/core/lib/app/app.js | 12 +---- packages/@vuepress/core/lib/app/redirect.js | 57 +++++++++++++++++++++ 2 files changed, 59 insertions(+), 10 deletions(-) create mode 100644 packages/@vuepress/core/lib/app/redirect.js diff --git a/packages/@vuepress/core/lib/app/app.js b/packages/@vuepress/core/lib/app/app.js index 1adc33e3f3..a0432331e6 100644 --- a/packages/@vuepress/core/lib/app/app.js +++ b/packages/@vuepress/core/lib/app/app.js @@ -8,6 +8,7 @@ import appEnhancers from '@internal/app-enhancers' import globalUIComponents from '@internal/global-ui' import ClientComputedMixin from '@transform/ClientComputedMixin' import VuePress from './plugins/VuePress' +import handleRedirect from './redirect.js' // built-in components import Content from './components/Content.js' @@ -74,16 +75,7 @@ export function createApp (isServer) { } }) - // redirect /foo to /foo/ - router.beforeEach((to, from, next) => { - if (!/(\/|\.html)$/.test(to.path)) { - next(Object.assign({}, to, { - path: to.path + '/' - })) - } else { - next() - } - }) + handleRedirect(router) const options = {} diff --git a/packages/@vuepress/core/lib/app/redirect.js b/packages/@vuepress/core/lib/app/redirect.js new file mode 100644 index 0000000000..1305771734 --- /dev/null +++ b/packages/@vuepress/core/lib/app/redirect.js @@ -0,0 +1,57 @@ +// In VuePress, we have following convention about routing: +// +// - `/foo/` means source file is `/foo/{README|index}.md` +// - `/foo.html` means your source file is `/foo.md` +// +// The original design of VuePress relied on above two styles +// of routing, especially the routing calculations involved in +// default theme. so we can't easily modify `/foo.html` directly +// to `/foo` (i.e. remove html suffix) +// +// This "temporary" utility handles redirect of clean urls, with +// this utility, you'll get: +// +// For unknown request `/foo` +// - redirect to `/foo.html` if it exists +// - redirect to `/foo/` if it exists +// +// For unknown request `/foo/` +// - redirect to `/foo.html` if it exists + +export default function handleRedirect (router) { + router.beforeEach((to, from, next) => { + if (isRouteExists(router, to.path)) { + next() + } else { + // For unknown request `/foo` + // redirect to /foo/ if exists + // redirect to /foo.html if exists + if (!/(\/|\.html)$/.test(to.path)) { + const endingSlashUrl = to.path + '/' + const endingHtmlUrl = to.path + '.html' + if (isRouteExists(router, endingHtmlUrl)) { + next(endingHtmlUrl) + } else if (isRouteExists(router, endingSlashUrl)) { + next(endingSlashUrl) + } else { + next() + } + // For unknown request `/foo/` + // redirect to /foo.html if exists + } else if (/\/$/.test(to.path)) { + const endingHtmlUrl = to.path.replace(/\/$/, '') + '.html' + if (isRouteExists(router, endingHtmlUrl)) { + next(endingHtmlUrl) + } else { + next() + } + } else { + next() + } + } + }) +} + +function isRouteExists (router, path) { + return router.options.routes.filter(route => route.path === path).length > 0 +} From 6fc435a26bb4c9c2167c2eb895b466219e4ea9d0 Mon Sep 17 00:00:00 2001 From: ULIVZ <472590061@qq.com> Date: Fri, 8 Feb 2019 22:40:17 +0800 Subject: [PATCH 2/2] chore: tweaks --- packages/@vuepress/core/lib/app/app.js | 4 ++-- packages/@vuepress/core/lib/app/redirect.js | 11 ++++------- 2 files changed, 6 insertions(+), 9 deletions(-) diff --git a/packages/@vuepress/core/lib/app/app.js b/packages/@vuepress/core/lib/app/app.js index a0432331e6..ea650dbce4 100644 --- a/packages/@vuepress/core/lib/app/app.js +++ b/packages/@vuepress/core/lib/app/app.js @@ -8,7 +8,7 @@ import appEnhancers from '@internal/app-enhancers' import globalUIComponents from '@internal/global-ui' import ClientComputedMixin from '@transform/ClientComputedMixin' import VuePress from './plugins/VuePress' -import handleRedirect from './redirect.js' +import { handleRedirectForCleanUrls } from './redirect.js' // built-in components import Content from './components/Content.js' @@ -75,7 +75,7 @@ export function createApp (isServer) { } }) - handleRedirect(router) + handleRedirectForCleanUrls(router) const options = {} diff --git a/packages/@vuepress/core/lib/app/redirect.js b/packages/@vuepress/core/lib/app/redirect.js index 1305771734..4c99d5b6f9 100644 --- a/packages/@vuepress/core/lib/app/redirect.js +++ b/packages/@vuepress/core/lib/app/redirect.js @@ -4,7 +4,7 @@ // - `/foo.html` means your source file is `/foo.md` // // The original design of VuePress relied on above two styles -// of routing, especially the routing calculations involved in +// of routing, especially the calculation involved of routes at // default theme. so we can't easily modify `/foo.html` directly // to `/foo` (i.e. remove html suffix) // @@ -17,15 +17,14 @@ // // For unknown request `/foo/` // - redirect to `/foo.html` if it exists +// +// If all the above redirect rules don't exist, you'll get a 404 -export default function handleRedirect (router) { +export function handleRedirectForCleanUrls (router) { router.beforeEach((to, from, next) => { if (isRouteExists(router, to.path)) { next() } else { - // For unknown request `/foo` - // redirect to /foo/ if exists - // redirect to /foo.html if exists if (!/(\/|\.html)$/.test(to.path)) { const endingSlashUrl = to.path + '/' const endingHtmlUrl = to.path + '.html' @@ -36,8 +35,6 @@ export default function handleRedirect (router) { } else { next() } - // For unknown request `/foo/` - // redirect to /foo.html if exists } else if (/\/$/.test(to.path)) { const endingHtmlUrl = to.path.replace(/\/$/, '') + '.html' if (isRouteExists(router, endingHtmlUrl)) {