Skip to content

Commit e95d512

Browse files
farnabaznobkdatinux
authored
feat: per-page components (#1429)
Co-authored-by: nobkd <[email protected]> Co-authored-by: Sébastien Chopin <[email protected]> Co-authored-by: nobkd <[email protected]>
1 parent 5d3ffee commit e95d512

File tree

8 files changed

+77
-4
lines changed

8 files changed

+77
-4
lines changed

docs/content/4.api/1.components/2.content-renderer.md

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,9 @@ Other types will currently be passed to default slot via `v-slot="{ data }"` or
2020
- `excerpt`{lang=ts}: Whether or not to render the excerpt.
2121
- Type: `Boolean`{lang=ts}
2222
- Default: `false`{lang=ts}
23+
- `components`{lang=ts}: The map of custom components to use for rendering. This prop will pass to markdown renderer and will not affect other file types.
24+
- Type: `Object`{lang=ts}
25+
- Default: `{}`{lang=ts}
2326

2427
## Slots
2528

@@ -57,3 +60,26 @@ const { data } = await useAsyncData('page-data', () => queryContent('/hello').fi
5760
</main>
5861
</template>
5962
```
63+
64+
::alert
65+
Note that when you use default slot and `<ContentRendererMarkdown>` in your template you need to pass `components` to `<ContentRendererMarkdown>`.
66+
67+
```html [pages/[...slug].vue]
68+
<script setup lang="ts">
69+
const { data } = await useAsyncData('page-data', () => queryContent('/hello').findOne())
70+
71+
const components = {
72+
p: 'CustomParagraph'
73+
}
74+
</script>
75+
76+
<template>
77+
<main>
78+
<ContentRenderer :value="data">
79+
<h1>{{ data.title }}</h1>
80+
<ContentRendererMarkdown :value="data" :components="components" />
81+
</ContentRenderer>
82+
</main>
83+
</template>
84+
```
85+
::

src/runtime/components/ContentRendererMarkdown.vue

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,13 @@ export default defineComponent({
4545
tag: {
4646
type: String,
4747
default: 'div'
48+
},
49+
/**
50+
* The map of custom components to use for rendering.
51+
*/
52+
components: {
53+
type: Object,
54+
default: () => ({})
4855
}
4956
},
5057
async setup (props) {
@@ -53,14 +60,15 @@ export default defineComponent({
5360
await resolveContentComponents(props.value.body, {
5461
tags: {
5562
...tags,
56-
...props.value?.tags || {}
63+
...props.value?._components || {},
64+
...props.components
5765
}
5866
})
5967
6068
return { tags }
6169
},
6270
render (ctx) {
63-
const { tags, tag, value } = ctx
71+
const { tags, tag, value, components } = ctx
6472
6573
if (!value) {
6674
return null
@@ -75,7 +83,8 @@ export default defineComponent({
7583
...(value as ParsedContentMeta),
7684
tags: {
7785
...tags,
78-
...value?.tags || {}
86+
...value?._components || {},
87+
...components
7988
}
8089
}
8190

test/__snapshots__/basic.test.ts.snap

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,17 @@ exports[`Basic usage > Get contents index > basic-index-body 1`] = `
1616
"tag": "h1",
1717
"type": "element",
1818
},
19+
{
20+
"children": [
21+
{
22+
"type": "text",
23+
"value": "Hello World",
24+
},
25+
],
26+
"props": {},
27+
"tag": "p",
28+
"type": "element",
29+
},
1930
],
2031
"toc": {
2132
"depth": 2,

test/features/renderer-markdown.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,5 +52,15 @@ export const testMarkdownRenderer = () => {
5252
expect(rendered).toContain('This is an alert for success')
5353
expect(rendered).toContain('This is an alert for danger')
5454
})
55+
56+
test('per-page custom component', async () => {
57+
const html = await $fetch('/_partial/custom-paragraph')
58+
expect(html).contains('[Paragraph]')
59+
})
60+
61+
test('renderer custom component', async () => {
62+
const html = await $fetch('/features/custom-paragraph')
63+
expect(html).contains('[Paragraph]')
64+
})
5565
})
5666
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
<template>
2+
<p>
3+
[Paragraph] <slot />
4+
</p>
5+
</template>
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
_components:
3+
p : CustomProseP
4+
---
5+
6+
This is a paragraph.

test/fixtures/basic/content/index.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,4 @@
1-
# Index
1+
# Index
2+
3+
4+
Hello World
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
<template>
2+
<ContentDoc :path="'/'" :components="{ p: 'CustomProseP' }" />
3+
</template>

0 commit comments

Comments
 (0)