diff --git a/docs/guide/custom-themes.md b/docs/guide/custom-themes.md index f70f2b3dca..190173df77 100644 --- a/docs/guide/custom-themes.md +++ b/docs/guide/custom-themes.md @@ -28,6 +28,7 @@ This is the value of `$site` of this very website: "base": "/", "pages": [ { + "lastModified": 1524027677, "path": "/", "title": "VuePress", "frontmatter": {} @@ -43,7 +44,8 @@ This is the `$page` object for this page you are looking at: ``` json { - "path": "/custom-themes.html", + "lastModified": 1524847549, + "path": "/guide/custom-themes.html", "title": "Custom Themes", "headers": [/* ... */], "frontmatter": {} @@ -54,6 +56,10 @@ If the user provided `themeConfig` in `.vuepress/config.js`, it will also be ava Finally, don't forget that `this.$route` and `this.$router` are also available as part of Vue Router's API. +::: tip + `lastModified` is the UNIX timestamp of this file's last git commit, so please ensure you have git installed. +::: + ## Content Excerpt If a markdown file contains a `` comment, any content above the comment will be extracted and exposed as `$page.excerpt`. If you are building custom theme for blogging, this data can be used to render a post list with excerpts. diff --git a/docs/zh/guide/custom-themes.md b/docs/zh/guide/custom-themes.md index 474bca7aad..8b5ebffc3e 100644 --- a/docs/zh/guide/custom-themes.md +++ b/docs/zh/guide/custom-themes.md @@ -28,6 +28,7 @@ VuePress 使用单文件组件来构建自定义主题。想要开发一个自 "base": "/", "pages": [ { + "lastModified": 1524027677, "path": "/", "title": "VuePress", "frontmatter": {} @@ -43,6 +44,7 @@ VuePress 使用单文件组件来构建自定义主题。想要开发一个自 ``` json { + "lastModified": 1524847549, "path": "/custom-themes.html", "title": "自定义主题", "headers": [/* ... */], @@ -54,6 +56,10 @@ VuePress 使用单文件组件来构建自定义主题。想要开发一个自 最后,别忘了,作为 Vue Router API 的一部分,`this.$route` 和 `this.$router` 同样可以使用。 +::: tip 提示 + `lastModified` 是这个文件最后一次 git 提交的 unix 时间戳,所以请确保你已经安装了 git。 +::: + ## 内容摘抄 如果一个 markdown 文件中有一个 `` 注释,则该注释之前的内容会被抓取并暴露在 `$page.excerpt` 属性中。如果你在开发一个博客主题,你可以用这个属性来渲染一个带摘抄的文章列表。 diff --git a/lib/prepare.js b/lib/prepare.js index e892f1cbcc..46b478de6f 100644 --- a/lib/prepare.js +++ b/lib/prepare.js @@ -5,7 +5,12 @@ const yamlParser = require('js-yaml') const tomlParser = require('toml') const createMarkdown = require('./markdown') const tempPath = path.resolve(__dirname, 'app/.temp') -const { inferTitle, extractHeaders, parseFrontmatter } = require('./util') +const { + inferTitle, + extractHeaders, + parseFrontmatter, + getGitLastModifiedTimeStamp +} = require('./util') fs.ensureDirSync(tempPath) @@ -178,12 +183,15 @@ async function resolveOptions (sourceDir) { // resolve pagesData const pagesData = await Promise.all(pageFiles.map(async (file) => { + const filepath = path.resolve(sourceDir, file) + const lastModified = getGitLastModifiedTimeStamp(filepath) const data = { + lastModified, path: fileToPath(file) } // extract yaml frontmatter - const content = await fs.readFile(path.resolve(sourceDir, file), 'utf-8') + const content = await fs.readFile(filepath, 'utf-8') const frontmatter = parseFrontmatter(content) // infer title const title = inferTitle(frontmatter) diff --git a/lib/util/index.js b/lib/util/index.js index 67588591da..a1c2a70b09 100644 --- a/lib/util/index.js +++ b/lib/util/index.js @@ -1,3 +1,4 @@ +const spawn = require('cross-spawn') const parseHeaders = require('./parseHeaders') exports.normalizeHeadTag = tag => { @@ -81,3 +82,7 @@ exports.extractHeaders = (content, include = [], md) => { cache.set(key, res) return res } + +exports.getGitLastModifiedTimeStamp = filepath => { + return parseInt(spawn.sync('git', ['log', '-1', '--format=%ct', filepath]).stdout.toString('utf-8')) +} diff --git a/package.json b/package.json index 1768fee7af..e490caa9df 100644 --- a/package.json +++ b/package.json @@ -45,6 +45,7 @@ "commander": "^2.15.1", "connect-history-api-fallback": "^1.5.0", "copy-webpack-plugin": "^4.5.1", + "cross-spawn": "^6.0.5", "css-loader": "^0.28.11", "diacritics": "^1.3.0", "docsearch.js": "^2.5.2", diff --git a/yarn.lock b/yarn.lock index e86ccec3b0..cd4483a612 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1374,6 +1374,16 @@ cross-spawn@^5.0.1, cross-spawn@^5.1.0: shebang-command "^1.2.0" which "^1.2.9" +cross-spawn@^6.0.5: + version "6.0.5" + resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-6.0.5.tgz#4a5ec7c64dfae22c3a14124dbacdee846d80cbc4" + dependencies: + nice-try "^1.0.4" + path-key "^2.0.1" + semver "^5.5.0" + shebang-command "^1.2.0" + which "^1.2.9" + cryptiles@2.x.x: version "2.0.5" resolved "https://registry.yarnpkg.com/cryptiles/-/cryptiles-2.0.5.tgz#3bdfecdc608147c1c67202fa291e7dca59eaa3b8" @@ -4284,6 +4294,10 @@ neo-async@^2.5.0: version "2.5.1" resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-2.5.1.tgz#acb909e327b1e87ec9ef15f41b8a269512ad41ee" +nice-try@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/nice-try/-/nice-try-1.0.4.tgz#d93962f6c52f2c1558c0fbda6d512819f1efe1c4" + no-case@^2.2.0: version "2.3.2" resolved "https://registry.yarnpkg.com/no-case/-/no-case-2.3.2.tgz#60b813396be39b3f1288a4c1ed5d1e7d28b464ac" @@ -4686,7 +4700,7 @@ path-is-inside@^1.0.1, path-is-inside@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/path-is-inside/-/path-is-inside-1.0.2.tgz#365417dede44430d1c11af61027facf074bdfc53" -path-key@^2.0.0: +path-key@^2.0.0, path-key@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/path-key/-/path-key-2.0.1.tgz#411cadb574c5a140d3a4b1910d40d80cc9f40b40"