diff --git a/app.js b/app.js index beada1612..ecce40197 100644 --- a/app.js +++ b/app.js @@ -4,7 +4,7 @@ var fs = require('fs') http.createServer(function (req, res) { serveStatic('.')(req, res, function () { - res.writeHead(404, { 'Content-Type': 'text/html' }) + res.writeHead(200, { 'Content-Type': 'text/html' }) res.end(fs.readFileSync('dev.html')) }) }).listen(3000, '0.0.0.0') diff --git a/dev.html b/dev.html index 63cecbe34..51099d77c 100644 --- a/dev.html +++ b/dev.html @@ -30,7 +30,15 @@ loadSidebar: true, name: 'docsify', subMaxLevel: 2, - mergeNavbar: true + mergeNavbar: true, + formatUpdated: '{MM}/{DD} {HH}:{mm}', + plugins: [ + function(hook) { + hook.beforeEach(function (html) { + return html += '> Last modified {docsify-updated}' + }) + } + ] } diff --git a/docs/configuration.md b/docs/configuration.md index 946ac2050..aef9879bd 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -315,3 +315,18 @@ window.$docsify = { mergeNavbar: true } ``` + +## format-updated +We can display the file update date through **{docsify-updated}** variable. And format it by `formatUpdated`. +See https://github.com/lukeed/tinydate#patterns +```js +window.$docsify = { + formatUpdated: '{MM}/{DD} {HH}:{mm}', + + formatUpdated: function (time) { + // ... + + return time + } +} +``` diff --git a/docs/de-de/configuration.md b/docs/de-de/configuration.md index 19ec077d6..12495290e 100644 --- a/docs/de-de/configuration.md +++ b/docs/de-de/configuration.md @@ -314,4 +314,19 @@ Navbar will be merged with the sidebar on smaller screens. window.$docsify = { mergeNavbar: true } -``` \ No newline at end of file +``` + +## format-updated +We can display the file update date through **{docsify-updated}** variable. And format it by `formatUpdated`. +See https://github.com/lukeed/tinydate#patterns +```js +window.$docsify = { + formatUpdated: '{MM}/{DD} {HH}:{mm}', + + formatUpdated: function (time) { + // ... + + return time + } +} +``` diff --git a/docs/index.html b/docs/index.html index e2bef93f1..04a620c40 100644 --- a/docs/index.html +++ b/docs/index.html @@ -34,6 +34,7 @@ loadNavbar: true, mergeNavbar: true, maxLevel: 4, + subMaxLevel: 2, name: 'docsify', search: { noData: { @@ -48,7 +49,14 @@ '/': 'Search' } }, - subMaxLevel: 2 + formatUpdated: '{MM}/{DD} {HH}:{mm}', + plugins: [ + function(hook) { + hook.beforeEach(function (html) { + return html += '> Last modified {docsify-updated}' + }) + } + ] } diff --git a/docs/zh-cn/configuration.md b/docs/zh-cn/configuration.md index 028a8e1cb..39388d820 100644 --- a/docs/zh-cn/configuration.md +++ b/docs/zh-cn/configuration.md @@ -326,3 +326,17 @@ window.$docsify = { } ``` +## format-updated +我们可以显示文档更新日期通过 **{docsify-updated}** 变量. 并且格式化日期通过 `formatUpdated`. +参考 https://github.com/lukeed/tinydate#patterns +```js +window.$docsify = { + formatUpdated: '{MM}/{DD} {HH}:{mm}', + + formatUpdated: function (time) { + // ... + + return time + } +} +``` \ No newline at end of file diff --git a/package.json b/package.json index 33fde579b..4af0b3741 100644 --- a/package.json +++ b/package.json @@ -28,6 +28,7 @@ "dependencies": { "marked": "^0.3.6", "prismjs": "^1.6.0", + "tinydate": "^1.0.0", "zoom-image": "^0.1.4" }, "devDependencies": { diff --git a/src/core/config.js b/src/core/config.js index 771e46d1e..ecec037e2 100644 --- a/src/core/config.js +++ b/src/core/config.js @@ -18,7 +18,8 @@ const config = merge({ executeScript: null, noEmoji: false, ga: '', - mergeNavbar: false + mergeNavbar: false, + formatUpdated: '' }, window.$docsify) const script = document.currentScript || diff --git a/src/core/fetch/ajax.js b/src/core/fetch/ajax.js index d9644a9a1..1824cc459 100644 --- a/src/core/fetch/ajax.js +++ b/src/core/fetch/ajax.js @@ -14,9 +14,10 @@ export function get (url, hasBar = false) { const on = function () { xhr.addEventListener.apply(xhr, arguments) } + const cached = cache[url] - if (cache[url]) { - return { then: cb => cb(cache[url]), abort: noop } + if (cached) { + return { then: cb => cb(cached.content, cached.opt), abort: noop } } xhr.open('GET', url) @@ -41,8 +42,14 @@ export function get (url, hasBar = false) { if (target.status >= 400) { error(target) } else { - cache[url] = target.response - success(target.response) + const result = cache[url] = { + content: target.response, + opt: { + updatedAt: xhr.getResponseHeader('last-modified') + } + } + + success(result.content, result.opt) } }) }, diff --git a/src/core/fetch/index.js b/src/core/fetch/index.js index 0f2380af2..2fc23b9fb 100644 --- a/src/core/fetch/index.js +++ b/src/core/fetch/index.js @@ -28,8 +28,8 @@ export function fetchMixin (proto) { this.isHTML = /\.html$/g.test(path) // Load main content - last.then(text => { - this._renderMain(text) + last.then((text, opt) => { + this._renderMain(text, opt) if (!loadSidebar) return cb() const fn = result => { this._renderSidebar(result); cb() } diff --git a/src/core/render/index.js b/src/core/render/index.js index 04778eb31..648751b4b 100644 --- a/src/core/render/index.js +++ b/src/core/render/index.js @@ -8,6 +8,7 @@ import { callHook } from '../init/lifecycle' import { getBasePath, getPath, isAbsolutePath } from '../route/util' import { isPrimitive } from '../util/core' import { isMobile } from '../util/env' +import tinydate from 'tinydate' function executeScript () { const script = dom.findAll('.markdown-section>script') @@ -21,6 +22,16 @@ function executeScript () { }, 0) } +function formatUpdated (html, updated, fn) { + updated = typeof fn === 'function' + ? fn(updated) + : typeof fn === 'string' + ? tinydate(fn)(new Date(updated)) + : updated + + return html.replace(/{docsify-updated}/g, updated) +} + function renderMain (html) { if (!html) { // TODO: Custom 404 page @@ -97,9 +108,11 @@ export function renderMixin (proto) { getAndActive('nav') } - proto._renderMain = function (text) { + proto._renderMain = function (text, opt) { callHook(this, 'beforeEach', text, result => { - const html = this.isHTML ? result : markdown(result) + let html = this.isHTML ? result : markdown(result) + html = formatUpdated(html, opt.updatedAt, this.config.formatUpdated) + callHook(this, 'afterEach', html, text => renderMain.call(this, text)) }) }