From c5c68a37c5576ee49dbf676b86a2add0d79d33f8 Mon Sep 17 00:00:00 2001 From: Runyasak Chaengnaimuang Date: Sat, 7 Dec 2024 16:08:46 +0700 Subject: [PATCH 1/7] feat: implement defineProps --- src/core/markdown.ts | 20 +++++++++++++++++++- test/__snapshots__/excerpt.test.ts.snap | 4 ++-- test/__snapshots__/transform.test.ts.snap | 20 ++++++++++---------- 3 files changed, 31 insertions(+), 13 deletions(-) diff --git a/src/core/markdown.ts b/src/core/markdown.ts index 141b62a..17dc520 100644 --- a/src/core/markdown.ts +++ b/src/core/markdown.ts @@ -61,6 +61,24 @@ function extractCustomBlock(html: string, options: ResolvedOptions) { return { html, blocks } } +function createDefinePropsWithDefaults(props: { + [s: string]: unknown +}) { + const propsValue = Object + .entries(props) + .reduce((acc, [key, cur]) => `${acc}${key}:{default:${getPropsDefaultValue(cur)}},`, ``) + + return `defineProps({${propsValue}})` +} + +function getPropsDefaultValue(value: T) { + return typeof value === 'string' + ? `\`${value}\`` + : typeof value === 'object' + ? JSON.stringify(value) + : value +} + export function createMarkdown(options: ResolvedOptions) { const isVue2 = options.vueVersion.startsWith('2.') @@ -171,7 +189,7 @@ export function createMarkdown(options: ResolvedOptions) { if (options.excerpt && !excerptKeyOverlapping && frontmatter.excerpt !== undefined) delete frontmatter.excerpt - scriptLines.push(`const frontmatter = ${JSON.stringify(frontmatter)}`) + scriptLines.push(`const frontmatter = ${createDefinePropsWithDefaults(frontmatter)}`) if (options.exportFrontmatter) { frontmatterExportsLines = Object.entries(frontmatter) diff --git a/test/__snapshots__/excerpt.test.ts.snap b/test/__snapshots__/excerpt.test.ts.snap index fcbd749..cc38038 100644 --- a/test/__snapshots__/excerpt.test.ts.snap +++ b/test/__snapshots__/excerpt.test.ts.snap @@ -11,7 +11,7 @@ exports[`excerpt > raw excerpt 1`] = ` @@ -32,7 +32,7 @@ exports[`excerpt > rendered excerpt 1`] = ` diff --git a/test/__snapshots__/transform.test.ts.snap b/test/__snapshots__/transform.test.ts.snap index ff1a828..3b09a34 100644 --- a/test/__snapshots__/transform.test.ts.snap +++ b/test/__snapshots__/transform.test.ts.snap @@ -9,7 +9,7 @@ exports[`transform > basic 1`] = ` " `; @@ -32,7 +32,7 @@ exports[`transform > couldn't expose frontmatter 1`] = ` " " `; @@ -55,7 +55,7 @@ exports[`transform > export keyword frontmatters 1`] = ` " " @@ -105,7 +105,7 @@ exports[`transform > style 1`] = ` " @@ -116,7 +116,7 @@ exports[`transform > vue directives 1`] = `

+``` + It will also be passed to the wrapper component's props if you have set `wrapperComponent` option. ## Document head and meta From 39a2460c616a935d570b08e11b836d9e842275fa Mon Sep 17 00:00:00 2001 From: Runyasak Chaengnaimuang Date: Sun, 15 Dec 2024 21:40:26 +0700 Subject: [PATCH 3/7] feat: add frontmatterMerge props --- src/core/markdown.ts | 27 +++------ test/__snapshots__/excerpt.test.ts.snap | 14 +++-- test/__snapshots__/transform.test.ts.snap | 68 ++++++++++++++++------- 3 files changed, 66 insertions(+), 43 deletions(-) diff --git a/src/core/markdown.ts b/src/core/markdown.ts index 17dc520..1b6d5d9 100644 --- a/src/core/markdown.ts +++ b/src/core/markdown.ts @@ -61,24 +61,6 @@ function extractCustomBlock(html: string, options: ResolvedOptions) { return { html, blocks } } -function createDefinePropsWithDefaults(props: { - [s: string]: unknown -}) { - const propsValue = Object - .entries(props) - .reduce((acc, [key, cur]) => `${acc}${key}:{default:${getPropsDefaultValue(cur)}},`, ``) - - return `defineProps({${propsValue}})` -} - -function getPropsDefaultValue(value: T) { - return typeof value === 'string' - ? `\`${value}\`` - : typeof value === 'object' - ? JSON.stringify(value) - : value -} - export function createMarkdown(options: ResolvedOptions) { const isVue2 = options.vueVersion.startsWith('2.') @@ -189,7 +171,12 @@ export function createMarkdown(options: ResolvedOptions) { if (options.excerpt && !excerptKeyOverlapping && frontmatter.excerpt !== undefined) delete frontmatter.excerpt - scriptLines.push(`const frontmatter = ${createDefinePropsWithDefaults(frontmatter)}`) + scriptLines.push( + `import { computed } from 'vue'`, + `const props = ${`defineProps({ frontmatterMerge: { default: ${JSON.stringify(frontmatter)} } })`}`, + `const _frontmatter = ${JSON.stringify(frontmatter)}`, + 'const frontmatter = computed(() => ({ ..._frontmatter, ...props.frontmatterMerge }))', + ) if (options.exportFrontmatter) { frontmatterExportsLines = Object.entries(frontmatter) @@ -201,7 +188,7 @@ export function createMarkdown(options: ResolvedOptions) { } if (!isVue2 && options.exposeFrontmatter && !hasExplicitExports()) - scriptLines.push('defineExpose({ frontmatter })') + scriptLines.push('defineExpose({ frontmatter: _frontmatter })') if (!isVue2 && headEnabled && head) { // @ts-expect-error legacy option diff --git a/test/__snapshots__/excerpt.test.ts.snap b/test/__snapshots__/excerpt.test.ts.snap index cc38038..8238e30 100644 --- a/test/__snapshots__/excerpt.test.ts.snap +++ b/test/__snapshots__/excerpt.test.ts.snap @@ -11,8 +11,11 @@ exports[`excerpt > raw excerpt 1`] = ` " `; @@ -32,7 +38,10 @@ exports[`transform > couldn't expose frontmatter 1`] = ` " " `; @@ -55,8 +67,11 @@ exports[`transform > export keyword frontmatters 1`] = ` " " `; @@ -105,8 +129,11 @@ exports[`transform > style 1`] = ` " `; @@ -116,8 +143,11 @@ exports[`transform > vue directives 1`] = `

" `; @@ -40,8 +38,7 @@ exports[`transform > couldn't expose frontmatter 1`] = ` " `; @@ -69,9 +65,8 @@ exports[`transform > export keyword frontmatters 1`] = ` " `; @@ -131,9 +123,8 @@ exports[`transform > style 1`] = ` " `; @@ -145,9 +136,8 @@ exports[`transform > vue directives 1`] = ` @@ -36,7 +44,15 @@ exports[`excerpt > rendered excerpt 1`] = ` diff --git a/test/__snapshots__/transform.test.ts.snap b/test/__snapshots__/transform.test.ts.snap index dc1ffe2..438a206 100644 --- a/test/__snapshots__/transform.test.ts.snap +++ b/test/__snapshots__/transform.test.ts.snap @@ -11,7 +11,15 @@ exports[`transform > basic 1`] = ` " `; @@ -38,7 +54,15 @@ exports[`transform > couldn't expose frontmatter 1`] = ` " `; @@ -65,7 +97,15 @@ exports[`transform > export keyword frontmatters 1`] = ` " @@ -123,7 +187,15 @@ exports[`transform > style 1`] = ` " @@ -136,7 +208,15 @@ exports[`transform > vue directives 1`] = ` ``` +Alternatively, you can replace all frontmatter values using the `:frontmatter-replace` prop. Any remaining frontmatter properties will not render and will be `undefined`. + +```html + + + +``` + +For example, if you use `:frontmatter-replace`, the `description` property will not be shown on the screen. + +> Use either `:frontmatter-merge` or `:frontmatter-replace` for a component. If both props are provided, only `:frontmatter-replace` will take effect. + It will also be passed to the wrapper component's props if you have set `wrapperComponent` option. ## Document head and meta