Skip to content

Commit

Permalink
feat(config): Add 404 page options. (#406)
Browse files Browse the repository at this point in the history
This feature add the notFoundPage options to customize the default 404 page
with a markdown file. It also support the localisation.
  • Loading branch information
Romakita authored and QingWei-Li committed Mar 3, 2018
1 parent 0933445 commit 9b3b445
Show file tree
Hide file tree
Showing 5 changed files with 189 additions and 49 deletions.
31 changes: 31 additions & 0 deletions docs/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -435,3 +435,34 @@ window.$docsify = {
]
};
```


## notFoundPage

* type: `Boolean` | `String` | `Object`

Load the `_404.md` file:
```js
window.$docsify = {
notFoundPage: true
};
```

Load the customised path of the 404 page:
```js
window.$docsify = {
notFoundPage: 'my404.md'
};
```

Load the right 404 page according to the localisation:
```js
window.$docsify = {
notFoundPage: {
'/': '_404.md',
'/de': 'de/_404.md',
}
};
```
> Note: The options with fallbackLanguages didn't work with the `notFoundPage` options.
29 changes: 29 additions & 0 deletions docs/de-de/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -419,3 +419,32 @@ window.$docsify = {
fallbackLanguages: ['fr', 'de']
};
```

## notFoundPage

* type: `Boolean` | `String` | `Object`

Load the `_404.md` file:
```js
window.$docsify = {
notFoundPage: true
};
```

Load the customised path of the 404 page:
```js
window.$docsify = {
notFoundPage: 'my404.md'
};
```

Load the right 404 page according to the localisation:
```js
window.$docsify = {
notFoundPage: {
'/': '_404.md',
'/de': 'de/_404.md',
}
};
```
> Note: The options with fallbackLanguages didn't work with the `notFoundPage` options.
31 changes: 31 additions & 0 deletions docs/zh-cn/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -431,3 +431,34 @@ window.$docsify = {
fallbackLanguages: ['fr', 'de']
};
```

## notFoundPage

* type: `Boolean` | `String` | `Object`

Load the `_404.md` file:
```js
window.$docsify = {
notFoundPage: true
};
```

Load the customised path of the 404 page:
```js
window.$docsify = {
notFoundPage: 'my404.md'
};
```

Load the right 404 page according to the localisation:
```js
window.$docsify = {
notFoundPage: {
'/': '_404.md',
'/de': 'de/_404.md',
}
};
```
> Note: The options with fallbackLanguages didn't work with the `notFoundPage` options.

144 changes: 97 additions & 47 deletions src/core/fetch/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,44 +19,35 @@ function loadNested (path, qs, file, next, vm, first) {

export function fetchMixin (proto) {
let last
proto._fetch = function (cb = noop) {
const { path, query } = this.route
const qs = stringifyQuery(query, ['id'])
const { loadNavbar, loadSidebar, requestHeaders, fallbackLanguages } = this.config
// Abort last request
last && last.abort && last.abort()

const file = this.router.getFile(path)
last = get(file + qs, true, requestHeaders)

// Current page is html
this.isHTML = /\.html$/g.test(file)

const getFallBackPage = (file) => {
if (!fallbackLanguages) {
return false
}

const local = file.split('/')[1]

if (fallbackLanguages.indexOf(local) === -1) {
return false
}

file = file.replace(new RegExp(`^/${local}`), '')
const abort = () => last && last.abort && last.abort()
const request = (url, hasbar, requestHeaders) => {
abort()
last = get(url, true, requestHeaders)
return last
}

return get(file + qs, true, requestHeaders)
.then(
(text, opt) => {
this._renderMain(text, opt, loadSideAndNav)
},
_ => {
return this._renderMain(null, {}, loadSideAndNav)
}
)
const get404Path = (path, config) => {
const { notFoundPage, ext } = config
const defaultPath = '_404' + (ext || '.md')

switch (typeof notFoundPage) {
case 'boolean':
return defaultPath
case 'string':
return notFoundPage
case 'object':
const key = Object
.keys(notFoundPage)
.sort((a, b) => b.length - a.length)
.find((key) => path.match(new RegExp('^' + key)))

return key && notFoundPage[key] || defaultPath
}
}

const loadSideAndNav = () => {
proto._loadSideAndNav = function (path, qs, loadSidebar, cb) {
return () => {
if (!loadSidebar) return cb()

const fn = result => {
Expand All @@ -67,28 +58,39 @@ export function fetchMixin (proto) {
// Load sidebar
loadNested(path, qs, loadSidebar, fn, this, true)
}
}

proto._fetch = function (cb = noop) {
const { path, query } = this.route
const qs = stringifyQuery(query, ['id'])
const { loadNavbar, requestHeaders, loadSidebar } = this.config
// Abort last request

const file = this.router.getFile(path)
const req = request(file + qs, true, requestHeaders)

// Current page is html
this.isHTML = /\.html$/g.test(file)

// Load main content
last
req
.then(
(text, opt) => {
this._renderMain(text, opt, loadSideAndNav)
},
(text, opt) => this._renderMain(text, opt, this._loadSideAndNav(path, qs, loadSidebar, cb)),
_ => {
return getFallBackPage(file) || this._renderMain(null, {}, loadSideAndNav)
this._fetchFallbackPage(file, qs, cb) || this._fetch404(file, qs, cb)
}
)

// Load nav
loadNavbar &&
loadNested(
path,
qs,
loadNavbar,
text => this._renderNav(text),
this,
true
)
loadNested(
path,
qs,
loadNavbar,
text => this._renderNav(text),
this,
true
)
}

proto._fetchCover = function () {
Expand Down Expand Up @@ -141,6 +143,54 @@ export function fetchMixin (proto) {
})
}
}

proto._fetchFallbackPage = function (path, qs, cb = noop) {
const { requestHeaders, fallbackLanguages, loadSidebar } = this.config

if (!fallbackLanguages) {
return false
}

const local = path.split('/')[1]

if (fallbackLanguages.indexOf(local) === -1) {
return false
}
const newPath = path.replace(new RegExp(`^/${local}`), '')
const req = request(newPath + qs, true, requestHeaders)

req.then(
(text, opt) => this._renderMain(text, opt, this._loadSideAndNav(path, qs, loadSidebar, cb)),
() => this._fetch404(path, qs, cb)
)

return true
}
/**
* Load the 404 page
* @param path
* @param qs
* @param cb
* @returns {*}
* @private
*/
proto._fetch404 = function (path, qs, cb = noop) {
const { loadSidebar, requestHeaders, notFoundPage } = this.config

const fnLoadSideAndNav = this._loadSideAndNav(path, qs, loadSidebar, cb)

if (notFoundPage) {
request(get404Path(path, this.config), true, requestHeaders)
.then(
(text, opt) => this._renderMain(text, opt, fnLoadSideAndNav),
() => this._renderMain(null, {}, fnLoadSideAndNav)
)
return true
}

this._renderMain(null, {}, fnLoadSideAndNav)
return false
}
}

export function initFetch (vm) {
Expand Down
3 changes: 1 addition & 2 deletions src/core/render/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,7 @@ function formatUpdated (html, updated, fn) {

function renderMain (html) {
if (!html) {
// TODO: Custom 404 page
html = 'not found'
html = '<h1>404 - Not found</h1>'
}

this._renderTo('.markdown-section', html)
Expand Down

0 comments on commit 9b3b445

Please sign in to comment.