pull/1956/merge
Markus 4 years ago committed by GitHub
commit 469be8b65f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -9,6 +9,7 @@ export default defineConfig({
title: 'VitePress',
description: 'Vite & Vue powered static site generator.',
created: true,
lastUpdated: true,
cleanUrls: true,
@ -109,6 +110,7 @@ function sidebarGuide() {
{ text: 'Sidebar', link: '/guide/theme-sidebar' },
{ text: 'Prev Next Link', link: '/guide/theme-prev-next-link' },
{ text: 'Edit Link', link: '/guide/theme-edit-link' },
{ text: 'Created', link: '/guide/theme-created' },
{ text: 'Last Updated', link: '/guide/theme-last-updated' },
{ text: 'Layout', link: '/guide/theme-layout' },
{ text: 'Home Page', link: '/guide/theme-home-page' },

@ -110,6 +110,19 @@ export default {
}
```
## created
- Type: `boolean`
- Default: `false`
Use git commit to get the timestamp. This option enables the default theme to display the page's creation time. You can customize the text via [`themeConfig.createdText`](theme-configs#createdText) option.
```ts
export default {
created: true
}
```
## lastUpdated
- Type: `boolean`

@ -76,6 +76,20 @@ type HeadConfig =
| [string, Record<string, string>, string]
```
## created
- Type: `boolean`
- Default: `true`
Whether to display [Created](../guide/theme-created) text in the current page.
```yaml
---
created: false
---
```
## lastUpdated
- Type: `boolean`
@ -83,6 +97,7 @@ type HeadConfig =
Whether to display [Last Updated](../guide/theme-last-updated) text in the current page.
```yaml
---
lastUpdated: false

@ -284,6 +284,21 @@ export interface EditLink {
}
```
## createdText
- Type: `string`
- Default: `Created`
The prefix text showing right before the created time.
```ts
export default {
themeConfig: {
createdText: 'Creation Date'
}
}
```
## lastUpdatedText
- Type: `string`

@ -0,0 +1,25 @@
# Created
The creation time will be displayed in the lower right corner of the page.
To enable it, add `created` options to your config.
## Page Configuration
Add `created` options to your config.
```js
export default {
created: true
}
```
## Frontmatter Configuration
If you would like to hide the created text, set false to the `created` option.
```yaml
---
created: false
---
```

@ -6,6 +6,7 @@ VitePress comes with its default theme providing many features out of the box. L
- [Sidebar](./theme-sidebar)
- [Prev Next Link](./theme-prev-next-link)
- [Edit Link](./theme-edit-link)
- [Created](./theme-created)
- [Last Updated](./theme-last-updated)
- [Layout](./theme-layout)
- [Home Page](./theme-home-page)

@ -6,7 +6,7 @@ import { useEditLink } from '../composables/edit-link.js'
import { usePrevNext } from '../composables/prev-next.js'
import VPIconEdit from './icons/VPIconEdit.vue'
import VPLink from './VPLink.vue'
import VPDocFooterLastUpdated from './VPDocFooterLastUpdated.vue'
import VPDocFooterEditDates from "./VPDocFooterEditDates.vue";
const { theme, page, frontmatter } = useData()
@ -16,6 +16,9 @@ const control = usePrevNext()
const hasEditLink = computed(() => {
return theme.value.editLink && frontmatter.value.editLink !== false
})
const hasCreated = computed(() => {
return page.value.created && frontmatter.value.created !== false
})
const hasLastUpdated = computed(() => {
return page.value.lastUpdated && frontmatter.value.lastUpdated !== false
})
@ -26,7 +29,7 @@ const showFooter = computed(() => {
<template>
<footer v-if="showFooter" class="VPDocFooter">
<div v-if="hasEditLink || hasLastUpdated" class="edit-info">
<div v-if="hasEditLink || hasLastUpdated || hasCreated" class="edit-info">
<div v-if="hasEditLink" class="edit-link">
<VPLink class="edit-link-button" :href="editLink.url" :no-icon="true">
<VPIconEdit class="edit-link-icon" />
@ -34,8 +37,13 @@ const showFooter = computed(() => {
</VPLink>
</div>
<div v-if="hasLastUpdated" class="last-updated">
<VPDocFooterLastUpdated />
<div class="edit-dates">
<div v-if="hasCreated">
<VPDocFooterEditDates is-created="true"/>
</div>
<div v-if="hasLastUpdated">
<VPDocFooterEditDates />
</div>
</div>
</div>
@ -65,6 +73,16 @@ const showFooter = computed(() => {
padding-bottom: 18px;
}
.edit-dates {
display: flex;
flex-direction: column;
justify-content: right;
}
.edit-link {
align-self: flex-end;
}
@media (min-width: 640px) {
.edit-info {
display: flex;
@ -72,6 +90,9 @@ const showFooter = computed(() => {
align-items: center;
padding-bottom: 14px;
}
.edit-dates {
text-align: right;
}
}
.edit-link-button {

@ -1,10 +1,19 @@
<script setup lang="ts">
import { ref, computed, watchEffect, onMounted } from 'vue'
import { useData } from '../composables/data.js'
import {ref, computed, watchEffect, onMounted} from 'vue'
import {useData} from '../composables/data.js'
const { theme, page } = useData()
const {theme, page} = useData()
const date = computed(() => new Date(page.value.lastUpdated!))
const props = defineProps({
isCreated: Boolean
})
const text = props.isCreated ?
(theme.value.createdText || 'Created') :
(theme.value.lastUpdatedText || 'Last updated')
const date = computed(() => new Date(
props.isCreated ? page.value.created! : page.value.lastUpdated!)
)
const isoDatetime = computed(() => date.value.toISOString())
const datetime = ref('')
@ -20,7 +29,7 @@ onMounted(() => {
<template>
<p class="VPLastUpdated">
{{ theme.lastUpdatedText || 'Last updated' }}:
{{ text }}:
<time :datetime="isoDatetime">{{ datetime }}</time>
</p>
</template>

@ -43,6 +43,7 @@ export interface UserConfig<ThemeConfig = any>
locales?: LocaleConfig<ThemeConfig>
appearance?: boolean | 'dark'
created?: boolean
lastUpdated?: boolean
/**
@ -159,6 +160,7 @@ export interface SiteConfig<ThemeConfig = any>
| 'shouldPreload'
| 'mpa'
| 'lastUpdated'
| 'created'
| 'ignoreDeadLinks'
| 'cleanUrls'
| 'useWebFonts'
@ -278,6 +280,7 @@ export async function resolveConfig(
tempDir: resolve(root, '.temp'),
markdown: userConfig.markdown,
lastUpdated: userConfig.lastUpdated,
created: userConfig.created,
vue: userConfig.vue,
vite: userConfig.vite,
shouldPreload: userConfig.shouldPreload,

@ -12,7 +12,10 @@ import {
type MarkdownRenderer
} from './markdown'
import { EXTERNAL_URL_RE, type HeadConfig, type PageData } from './shared'
import { getGitTimestamp } from './utils/getGitTimestamp'
import {
getLastUpdatedTimestampFromGit,
getCreatedTimestampFromGit
} from './utils/getGitTimestamp'
import { slash } from './utils/slash'
const debug = _debug('vitepress:md')
@ -37,6 +40,7 @@ export async function createMarkdownToVueRenderFn(
userDefines: Record<string, any> | undefined,
isBuild = false,
base = '/',
includeCreatedData = false,
includeLastUpdatedData = false,
cleanUrls = false,
siteConfig: SiteConfig | null = null
@ -154,8 +158,11 @@ export async function createMarkdownToVueRenderFn(
relativePath
}
if (includeCreatedData) {
pageData.created = await getCreatedTimestampFromGit(file)
}
if (includeLastUpdatedData) {
pageData.lastUpdated = await getGitTimestamp(file)
pageData.lastUpdated = await getLastUpdatedTimestampFromGit(file)
}
if (siteConfig?.transformPageData) {

@ -68,6 +68,7 @@ export async function createVitePressPlugin(
vite: userViteConfig,
pages,
ignoreDeadLinks,
created,
lastUpdated,
cleanUrls,
rewrites
@ -108,6 +109,7 @@ export async function createVitePressPlugin(
config.define,
config.command === 'build',
config.base,
created,
lastUpdated,
cleanUrls,
siteConfig

@ -1,8 +1,28 @@
import { spawn } from 'cross-spawn'
import type { ChildProcessWithoutNullStreams } from 'child_process'
export function getGitTimestamp(file: string) {
export function getLastUpdatedTimestampFromGit(file: string) {
const child = spawn('git', ['log', '-1', '--pretty="%ci"', file])
return handleChildProcess(file, child)
}
export function getCreatedTimestampFromGit(file: string) {
const child = spawn('git', [
'log',
'-1',
'--diff-filter=A',
'--follow',
'--format="%ci"',
file
])
return handleChildProcess(file, child)
}
function handleChildProcess(
file: string,
child: ChildProcessWithoutNullStreams
) {
return new Promise<number>((resolve, reject) => {
const child = spawn('git', ['log', '-1', '--pretty="%ci"', file])
let output = ''
child.stdout.on('data', (d) => (output += String(d)))
child.on('close', () => {

@ -27,6 +27,7 @@ export const notFoundPageData: PageData = {
description: 'Not Found',
headers: [],
frontmatter: { sidebar: false, layout: 'page' },
created: 0,
lastUpdated: 0
}

@ -60,6 +60,13 @@ export namespace DefaultTheme {
*/
editLink?: EditLink
/**
* Set custom created text.
*
* @default 'Created'
*/
createdText?: string
/**
* Set custom last updated text.
*

1
types/shared.d.ts vendored

@ -11,6 +11,7 @@ export interface PageData {
description: string
headers: Header[]
frontmatter: Record<string, any>
created?: number
lastUpdated?: number
}

Loading…
Cancel
Save