Skip to content

Commit c6bdcfb

Browse files
patak-devkiaking
andauthored
feat!: add more global and computed properties (#152)
BREAKING CHANGE: `$theme` global computed is renamed to `$themeConfig` to align better with VuePress. Co-authored-by: Kia King Ishii <kia.king.08@gmail.com>
1 parent b127aee commit c6bdcfb

File tree

7 files changed

+126
-17
lines changed

7 files changed

+126
-17
lines changed

docs/.vitepress/config.js

+1
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ function getGuideSidebar() {
4444
text: 'Advanced',
4545
children: [
4646
{ text: 'Frontmatter', link: '/guide/frontmatter' },
47+
{ text: 'Global Computed', link: '/guide/global-computed' },
4748
{ text: 'Customization', link: '/guide/customization' }
4849
]
4950
}

docs/guide/frontmatter.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ editLink: true
99
---
1010
```
1111

12-
Between the triple-dashed lines, you can set [predefined variables](#predefined-variables), or even create custom ones of your own. These variables can be used via the <code>\$page.frontmatter</code> variable.
12+
Between the triple-dashed lines, you can set [predefined variables](#predefined-variables), or even create custom ones of your own. These variables can be used via the <code>$frontmatter</code> variable.
1313

1414
Here’s an example of how you could use it in your Markdown file:
1515

@@ -19,7 +19,7 @@ title: Docs with VitePress
1919
editLink: true
2020
---
2121

22-
# {{ $page.frontmatter.title }}
22+
# {{ $frontmatter.title }}
2323

2424
Guide content
2525
```

docs/guide/global-computed.md

+73
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
# Global Computed
2+
3+
In VitePress, some core [computed properties](https://v3.vuejs.org/guide/computed.html#computed-properties) can be used by the default theme or custom themes. Or directly in Markdown pages using vue, for example using `$frontmatter.title` to access the title defined in the frontmatter section of the page.
4+
5+
## $site
6+
7+
This is the `$site` value of the site you're currently reading:
8+
9+
```js
10+
{
11+
base: '/',
12+
lang: 'en-US',
13+
title: 'VitePress',
14+
description: 'Vite & Vue powered static site generator.',
15+
head: [],
16+
locales: {},
17+
themeConfig: $themeConfig
18+
}
19+
```
20+
21+
## $themeConfig
22+
23+
Refers to `$site.themeConfig`.
24+
25+
```js
26+
{
27+
locales: {},
28+
repo: 'vuejs/vitepress',
29+
docsDir: 'docs',
30+
editLinks: true,
31+
editLinkText: 'Edit this page on GitHub',
32+
lastUpdated: 'Last Updated',
33+
nav: [...],
34+
sidebar: { ... }
35+
}
36+
```
37+
38+
## $page
39+
40+
This is the `$page` value of the page you're currently reading:
41+
42+
```js
43+
{
44+
relativePath: 'guide/global-computed.md',
45+
title: 'Global Computed',
46+
headers: [
47+
{ level: 2, title: '$site', slug: 'site' },
48+
{ level: 2, title: '$page', slug: '$page' },
49+
...
50+
],
51+
frontmatter: $frontmatter,
52+
lastUpdated: 1606297645000
53+
}
54+
```
55+
56+
## $frontmatter
57+
58+
Reference of `$page.frontmatter`.
59+
60+
```js
61+
{
62+
title: 'Docs with VitePress',
63+
editLink: true
64+
}
65+
```
66+
67+
## $title
68+
69+
Value of the `<title>` label used for the current page.
70+
71+
## $description
72+
73+
The content value of the `<meta name= "description" content= "...">` for the current page.

src/client/app/index.ts

+19-2
Original file line numberDiff line numberDiff line change
@@ -82,14 +82,31 @@ export function createApp() {
8282
return siteDataByRouteRef.value
8383
}
8484
},
85+
$themeConfig: {
86+
get() {
87+
return siteDataByRouteRef.value.themeConfig
88+
}
89+
},
8590
$page: {
8691
get() {
8792
return router.route.data
8893
}
8994
},
90-
$theme: {
95+
$frontmatter: {
9196
get() {
92-
return siteDataByRouteRef.value.themeConfig
97+
return router.route.data.frontmatter
98+
}
99+
},
100+
$title: {
101+
get() {
102+
return router.route.data.title || siteDataByRouteRef.value.title
103+
}
104+
},
105+
$description: {
106+
get() {
107+
return (
108+
router.route.data.description || siteDataByRouteRef.value.description
109+
)
93110
}
94111
}
95112
})

src/client/theme-default/components/NavBarTitle.vue

+3-10
Original file line numberDiff line numberDiff line change
@@ -5,24 +5,17 @@
55
:aria-label="`${$site.title}, back to home`"
66
>
77
<img
8-
v-if="$theme.logo"
8+
v-if="$themeConfig.logo"
99
class="logo"
10-
:src="withBase($theme.logo)"
10+
:src="withBase($themeConfig.logo)"
1111
alt="Logo"
1212
/>
1313
{{ $site.title }}
1414
</a>
1515
</template>
1616

17-
<script lang="ts">
18-
import { defineComponent } from 'vue'
17+
<script setup lang="ts">
1918
import { withBase } from '../utils'
20-
21-
export default defineComponent({
22-
setup() {
23-
return { withBase }
24-
}
25-
})
2619
</script>
2720

2821
<style scoped>

src/node/markdownToVue.ts

+25-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import matter from 'gray-matter'
33
import LRUCache from 'lru-cache'
44
import { createMarkdownRenderer, MarkdownOptions } from './markdown/markdown'
55
import { deeplyParseHeader } from './utils/parseHeader'
6-
import { PageData } from '../../types/shared'
6+
import { PageData, HeadConfig } from '../../types/shared'
77

88
const debug = require('debug')('vitepress:md')
99
const cache = new LRUCache<string, MarkdownCompileResult>({ max: 1024 })
@@ -41,6 +41,7 @@ export function createMarkdownToVueRenderFn(
4141
// inject page data
4242
const pageData: PageData = {
4343
title: inferTitle(frontmatter, content),
44+
description: inferDescription(frontmatter),
4445
frontmatter,
4546
headers: data.headers,
4647
relativePath: file.replace(/\\/g, '/'),
@@ -106,3 +107,26 @@ const inferTitle = (frontmatter: any, content: string) => {
106107
}
107108
return ''
108109
}
110+
111+
const inferDescription = (frontmatter: Record<string, any>) => {
112+
if (!frontmatter.head) {
113+
return ''
114+
}
115+
116+
return getHeadMetaContent(frontmatter.head, 'description') || ''
117+
}
118+
119+
const getHeadMetaContent = (
120+
head: HeadConfig[],
121+
name: string
122+
): string | undefined => {
123+
if (!head || !head.length) {
124+
return undefined
125+
}
126+
127+
const meta = head.find(([tag, attrs = {}]) => {
128+
return tag === 'meta' && attrs.name === name && attrs.content
129+
})
130+
131+
return meta && meta[1].content
132+
}

types/shared.d.ts

+3-2
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,11 @@ export type HeadConfig =
2424
| [string, Record<string, string>, string]
2525

2626
export interface PageData {
27+
relativePath: string
2728
title: string
28-
frontmatter: Record<string, any>
29+
description: string
2930
headers: Header[]
30-
relativePath: string
31+
frontmatter: Record<string, any>
3132
lastUpdated: number
3233
}
3334

0 commit comments

Comments
 (0)