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>
pull/156/head
Matias Capeletto 4 years ago committed by GitHub
parent b127aeeaf1
commit c6bdcfbf4f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -44,6 +44,7 @@ function getGuideSidebar() {
text: 'Advanced', text: 'Advanced',
children: [ children: [
{ text: 'Frontmatter', link: '/guide/frontmatter' }, { text: 'Frontmatter', link: '/guide/frontmatter' },
{ text: 'Global Computed', link: '/guide/global-computed' },
{ text: 'Customization', link: '/guide/customization' } { text: 'Customization', link: '/guide/customization' }
] ]
} }

@ -9,7 +9,7 @@ editLink: true
--- ---
``` ```
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. 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.
Heres an example of how you could use it in your Markdown file: Heres an example of how you could use it in your Markdown file:
@ -19,7 +19,7 @@ title: Docs with VitePress
editLink: true editLink: true
--- ---
# {{ $page.frontmatter.title }} # {{ $frontmatter.title }}
Guide content Guide content
``` ```

@ -0,0 +1,73 @@
# Global Computed
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.
## $site
This is the `$site` value of the site you're currently reading:
```js
{
base: '/',
lang: 'en-US',
title: 'VitePress',
description: 'Vite & Vue powered static site generator.',
head: [],
locales: {},
themeConfig: $themeConfig
}
```
## $themeConfig
Refers to `$site.themeConfig`.
```js
{
locales: {},
repo: 'vuejs/vitepress',
docsDir: 'docs',
editLinks: true,
editLinkText: 'Edit this page on GitHub',
lastUpdated: 'Last Updated',
nav: [...],
sidebar: { ... }
}
```
## $page
This is the `$page` value of the page you're currently reading:
```js
{
relativePath: 'guide/global-computed.md',
title: 'Global Computed',
headers: [
{ level: 2, title: '$site', slug: 'site' },
{ level: 2, title: '$page', slug: '$page' },
...
],
frontmatter: $frontmatter,
lastUpdated: 1606297645000
}
```
## $frontmatter
Reference of `$page.frontmatter`.
```js
{
title: 'Docs with VitePress',
editLink: true
}
```
## $title
Value of the `<title>` label used for the current page.
## $description
The content value of the `<meta name= "description" content= "...">` for the current page.

@ -82,14 +82,31 @@ export function createApp() {
return siteDataByRouteRef.value return siteDataByRouteRef.value
} }
}, },
$themeConfig: {
get() {
return siteDataByRouteRef.value.themeConfig
}
},
$page: { $page: {
get() { get() {
return router.route.data return router.route.data
} }
}, },
$theme: { $frontmatter: {
get() { get() {
return siteDataByRouteRef.value.themeConfig return router.route.data.frontmatter
}
},
$title: {
get() {
return router.route.data.title || siteDataByRouteRef.value.title
}
},
$description: {
get() {
return (
router.route.data.description || siteDataByRouteRef.value.description
)
} }
} }
}) })

@ -5,24 +5,17 @@
:aria-label="`${$site.title}, back to home`" :aria-label="`${$site.title}, back to home`"
> >
<img <img
v-if="$theme.logo" v-if="$themeConfig.logo"
class="logo" class="logo"
:src="withBase($theme.logo)" :src="withBase($themeConfig.logo)"
alt="Logo" alt="Logo"
/> />
{{ $site.title }} {{ $site.title }}
</a> </a>
</template> </template>
<script lang="ts"> <script setup lang="ts">
import { defineComponent } from 'vue'
import { withBase } from '../utils' import { withBase } from '../utils'
export default defineComponent({
setup() {
return { withBase }
}
})
</script> </script>
<style scoped> <style scoped>

@ -3,7 +3,7 @@ import matter from 'gray-matter'
import LRUCache from 'lru-cache' import LRUCache from 'lru-cache'
import { createMarkdownRenderer, MarkdownOptions } from './markdown/markdown' import { createMarkdownRenderer, MarkdownOptions } from './markdown/markdown'
import { deeplyParseHeader } from './utils/parseHeader' import { deeplyParseHeader } from './utils/parseHeader'
import { PageData } from '../../types/shared' import { PageData, HeadConfig } from '../../types/shared'
const debug = require('debug')('vitepress:md') const debug = require('debug')('vitepress:md')
const cache = new LRUCache<string, MarkdownCompileResult>({ max: 1024 }) const cache = new LRUCache<string, MarkdownCompileResult>({ max: 1024 })
@ -41,6 +41,7 @@ export function createMarkdownToVueRenderFn(
// inject page data // inject page data
const pageData: PageData = { const pageData: PageData = {
title: inferTitle(frontmatter, content), title: inferTitle(frontmatter, content),
description: inferDescription(frontmatter),
frontmatter, frontmatter,
headers: data.headers, headers: data.headers,
relativePath: file.replace(/\\/g, '/'), relativePath: file.replace(/\\/g, '/'),
@ -106,3 +107,26 @@ const inferTitle = (frontmatter: any, content: string) => {
} }
return '' return ''
} }
const inferDescription = (frontmatter: Record<string, any>) => {
if (!frontmatter.head) {
return ''
}
return getHeadMetaContent(frontmatter.head, 'description') || ''
}
const getHeadMetaContent = (
head: HeadConfig[],
name: string
): string | undefined => {
if (!head || !head.length) {
return undefined
}
const meta = head.find(([tag, attrs = {}]) => {
return tag === 'meta' && attrs.name === name && attrs.content
})
return meta && meta[1].content
}

5
types/shared.d.ts vendored

@ -24,10 +24,11 @@ export type HeadConfig =
| [string, Record<string, string>, string] | [string, Record<string, string>, string]
export interface PageData { export interface PageData {
relativePath: string
title: string title: string
frontmatter: Record<string, any> description: string
headers: Header[] headers: Header[]
relativePath: string frontmatter: Record<string, any>
lastUpdated: number lastUpdated: number
} }

Loading…
Cancel
Save