使用您最喜欢的AI助手总结文档,并引用此页面和AI提供商
此页面的内容已使用 AI 翻译。
查看英文原文的最新版本如果您有改善此文档的想法,请随时通过在GitHub上提交拉取请求来贡献。
文档的 GitHub 链接复制文档 Markdown 到剪贴板
import { FileTree } from '@astrojs/starlight/components';
import PackageManagerTabs from '/components/tabs/PackageManagerTabs.astro';
import { Steps } from '@astrojs/starlight/components';
import ReadMore from '/components/ReadMore.astro';
这个 Astro 集成 允许使用 Markdoc 来创建组件、页面和内容集合条目。
为什么是 Markdoc?
Markdoc 允许你使用 Astro 组件 增强 Markdown。如果你已经使用 Markdoc 编写了现有内容,此集成允许你使用内容集合将这些文件带到 Astro 项目中。
安装
Astro 包含了一个 astro add 命令,用于自动设置官方集成。如果你愿意,可以改为手动安装集成。
在新的终端窗口中运行下面其中一个命令。
如果你遇到任何问题,请随时在 GitHub 上向我们报告,并尝试下面的手动安装步骤。
手动安装
首先,安装 @astrojs/markdoc 包:
然后,使用 integrations 属性将集成应用到你的 astro.config.* 文件中:
复制代码到剪贴板
import { defineConfig } from 'astro/config';import markdoc from '@astrojs/markdoc';export default defineConfig({ // ... integrations: [markdoc()],});
VS Code 编辑器集成
如果你正在使用 VS Code,有一个官方的 Markdoc 语言扩展,其中包括了对配置标签的语法高亮和自动完成功能。在 GitHub 上查看语言服务器以获取更多信息。
要设置扩展,需在项目根目录创建一个名为 markdoc.config.json 的文件,并包含以下内容:
复制代码到剪贴板
[ { "id": "my-site", "path": "src/content", "schema": { "path": "markdoc.config.mjs", "type": "esm", "property": "default", "watch": true } }]
将 markdoc.config.mjs 设置为你的配置文件,并使用 schema 对象,通过 path 属性定义你的 Markdoc 文件存储的位置。由于 Markdoc 是专门用于内容集合的,你可以使用 src/content。
用法
Markdoc 文件只能在内容集合中使用。使用 .mdoc 扩展名将条目添加到任何内容集合中:
然后,使用 内容集合 API 查询你的集合:
复制代码到剪贴板
---import { getEntry, render } from 'astro:content';const entry = await getEntry('docs', 'why-markdoc');const { Content } = await render(entry);---<!--使用 `data` 访问 frontmatter 属性`--><h1>{entry.data.title}</h1><!--使用 Content 组件渲染 Markdoc 内容--><Content />
了解更多关于 Astro 内容集合文档 的信息。
传递 Markdoc 变量
你可能需要向你的内容传递 变量。这在传递服务端渲染参数如 A/B 测试时非常有用。
变量可以通过 Content 组件作为 props 传递:
复制代码到剪贴板
---import { getEntry, render } from 'astro:content';const entry = await getEntry('docs', 'why-markdoc');const { Content } = await render(entry);---<!--将 `abTest` 参数作为变量传递--><Content abTestGroup={Astro.params.abTestGroup} />
现在,abTestGroup 可以在 docs/why-markdoc.mdoc 中作为一个变量使用:
复制代码到剪贴板
{% if $abTestGroup === 'image-optimization-lover' %}让我来告诉你关于图像优化的信息...{% /if %}
要使一个变量对所有 Markdoc 文件全局可用,你可以使用 markdoc.config.mjs|ts 中的 variables 属性:
复制代码到剪贴板
import { defineMarkdocConfig } from '@astrojs/markdoc/config';export default defineMarkdocConfig({ variables: { environment: process.env.IS_PROD ? 'prod' : 'dev', },});
从你的 Markdoc 内容中访问 frontmatter
要访问 frontmatter,你可以在渲染内容的地方将条目的 data 属性作为一个变量传递:
复制代码到剪贴板
---import { getEntry, render } from 'astro:content';const entry = await getEntry('docs', 'why-markdoc');const { Content } = await render(entry);;---<Content frontmatter={entry.data} />
现在,这可以在你的 Markdoc 中作为 $frontmatter 访问。
渲染组件
@astrojs/markdoc 提供了配置选项,以使用 Markdoc 的所有功能,并将 UI 组件连接到你的内容。
将 Astro 组件作为 Markdoc 标签
你可以配置 Markdoc 标签,将其映射到 .astro 组件。你可以通过在项目根目录创建 markdoc.config.mjs|ts 文件并配置 tag 属性来添加新的标签。
这个例子渲染了一个 Aside 组件,并允许传递一个 type 字符串属性:
复制代码到剪贴板
import { defineMarkdocConfig, component } from '@astrojs/markdoc/config';export default defineMarkdocConfig({ tags: { aside: { render: component('./src/components/Aside.astro'), attributes: { // Markdoc 要求每个属性都有类型定义。 // 这些应该反映你正在渲染的组件的 `Props` 类型 // 查看 Markdoc 的属性定义文档: // https://markdoc.dev/docs/attributes#defining-attributes type: { type: String }, }, }, },});
现在,这个组件可以在你的 Markdoc 文件中使用 {% aside %} 标签。子元素将被传递给你的组件的默认插槽:
复制代码到剪贴板
# 欢迎来到 Markdoc 👋{% aside type="tip" %}使用像这种花哨的“aside”标签为你的文档添加一些 _花活_。{% /aside %}
使用客户端 UI 组件
标签和节点仅限于 .astro 文件。为了在 Markdoc 中嵌入客户端 UI 组件,使用一个包装 .astro 组件来渲染一个框架组件,并配合你所需的 client: 指令。
这个例子使用 ClientAside.astro 组件包装了一个 React 的 Aside.tsx 组件:
复制代码到剪贴板
---import Aside from './Aside';---<Aside {...Astro.props} client:load />
现在,这个 Astro 组件可以传递给配置中任何 标签 或 节点 的 render 属性:
复制代码到剪贴板
import { defineMarkdocConfig, component } from '@astrojs/markdoc/config';export default defineMarkdocConfig({ tags: { aside: { render: component('./src/components/ClientAside.astro'), attributes: { type: { type: String }, }, }, },});
从 npm 包和 TypeScript 文件中使用 Astro 组件
你可能需要使用从 TypeScript 或 JavaScript 文件中以命名导出形式暴露的 Astro 组件。这在使用 npm 包和设计系统时很常见。
你可以将导入名称作为第二个参数传递给 component() 函数:
复制代码到剪贴板
import { defineMarkdocConfig, component } from '@astrojs/markdoc/config';export default defineMarkdocConfig({ tags: { tabs: { render: component('@astrojs/starlight/components', 'Tabs'), }, },});
这将在内部生成以下导入语句:
复制代码到剪贴板
import { Tabs } from '@astrojs/starlight/components';
Markdoc 部分内容
{% partial /%} 标签允许你在 Markdoc 内容中渲染其他的 .mdoc 文件。
这对于跨多个文档的重用内容很有用,并且允许你拥有不遵循你的内容集合模式的 .mdoc 内容文件。
:::tip 对于部分文件或目录,使用下划线 _ 作为前缀。这将从内容集合查询中排除部分内容。 :::
此示例展示了一个 Markdoc 部分内容,用于在博客集合条目中使用的页脚:
复制代码到剪贴板
社交链接:- [Twitter / X](https://twitter.com/astrodotbuild)- [Discord](https://astro.build/chat)- [GitHub](https://github.com/withastro/astro)
使用 {% partial /%} 标签在博客文章条目的底部渲染页脚。使用 file 属性并提供文件路径,可以是相对路径或者导入别名:
复制代码到剪贴板
# 我的博客文章{% partial file="./_footer.mdoc" /%}
语法高亮
@astrojs/markdoc 提供了 Shiki 和 Prism 扩展来高亮你的代码块。
Shiki
使用 extends 属性将 shiki() 扩展应用到你的 Markdoc 配置中,你可以选择传递一个 shiki 配置对象:
复制代码到剪贴板
import { defineMarkdocConfig } from '@astrojs/markdoc/config';import shiki from '@astrojs/markdoc/shiki';export default defineMarkdocConfig({ extends: [ shiki({ // 从 Shiki 的内置主题中进行选择(或添加你自己的主题) // 默认:'github-dark' // https://shiki.style/themes theme: 'dracula', // 启用单词折叠以防止水平滚动 // 默认:false wrap: true, // 传入自定义语言 // 注意:Shiki 内置了许多的 langs,包括 `.astro`! // https://shiki.style/languages langs: [], }), ],});
Prism
使用 extends 属性将 prism() 扩展应用到你的 Markdoc 配置中。
复制代码到剪贴板
import { defineMarkdocConfig } from '@astrojs/markdoc/config';import prism from '@astrojs/markdoc/prism';export default defineMarkdocConfig({ extends: [prism()],});
要了解如何配置 Prism 样式表,请看我们的语法高亮指南。
自定义 Markdoc 节点 / 元素
你可能想要将标准的 Markdown 元素,比如段落和加粗文本,渲染为 Astro 组件。为此,你可以配置一个 Markdoc 节点。如果某个节点接收到属性,这些属性将作为组件的 props 可用。
这个例子使用一个自定义的 Quote.astro 组件来渲染引用块:
复制代码到剪贴板
import { defineMarkdocConfig, nodes, component } from '@astrojs/markdoc/config';export default defineMarkdocConfig({ nodes: { blockquote: { ...nodes.blockquote, // 应用 Markdoc 的默认的其他配置项 render: component('./src/components/Quote.astro'), }, },});
查看 Markdoc 节点文档 了解所有内置节点及其属性。
自定义标题
@astrojs/markdoc 自动为你的标题添加锚点链接,并 通过内容集合 API 生成一个 headings 列表。为了进一步自定义标题的渲染方式,你可以应用一个 Astro 组件作为 Markdoc 节点。
这个例子使用 render 属性渲染了一个 Heading.astro 组件:
复制代码到剪贴板
import { defineMarkdocConfig, nodes, component } from '@astrojs/markdoc/config';export default defineMarkdocConfig({ nodes: { heading: { ...nodes.heading, // 保留默认的锚点链接生成 render: component('./src/components/Heading.astro'), }, },});
所有 Markdown 标题将渲染 Heading.astro 组件,并将以下 attributes 作为组件的 props 传递:
- level: number 标题的级别 1 - 6
- id: string 从标题的文本内容生成的 id。这对应于由 内容 render() 函数 生成的 slug。
例如,标题 ### Level 3 heading! 将传递 level: 3 和 id: 'level-3-heading' 作为组件的 props。
自定义图片组件
Astro 的 <Image /> 组件不能直接在 Markdoc 中使用。但是你可以配置一个 Astro 组件来覆盖每次使用原生 ![]() 图片语法时的默认图片节点,或者作为一个自定义的 Markdoc 标签让你可以指定额外的图片属性。
覆盖 Markdoc 的默认图片节点
为了覆盖默认图片节点,你可以配置一个 .astro 组件来代替标准的 <img> 渲染。
```astro title="src/components/MarkdocImage.astro" --- import { Image } from "astro:assets"; interface Props { src: ImageMetadata; alt: string; } const { src, alt } = Astro.props; --- <Image src={src} alt={alt} /> ```2. <Image /> 组件需要为无法使用 ![]() 语法来提供的远程图片提供 width 和 height 属性。为了避免在使用远程图片时出现错误,当发现远程 URL src 属性时,会更新你的组件并渲染成标准的 HTML <img> 标签:
```astro title="src/components/MarkdocImage.astro" ins="| string" del={9} ins={10-12} --- import { Image } from "astro:assets"; interface Props { src: ImageMetadata | string; alt: string; } const { src, alt } = Astro.props; --- <Image src={src} alt={alt} /> { typeof src === 'string' ? <img src={src} alt={alt} /> : <Image src={src} alt={alt} /> } ```3. 配置 Markdoc 来覆盖默认的图片节点并渲染 MarkdocImage.astro:
```js title="markdoc.config.mjs" import { defineMarkdocConfig, nodes, component } from '@astrojs/markdoc/config'; export default defineMarkdocConfig({ nodes: { image: { ...nodes.image, // 应用 Markdoc 的其他默认选项 render: component('./src/components/MarkdocImage.astro'), }, }, }); ```4. 现在,任何 .mdoc 文件中的原生图片语法都将使用 <Image /> 组件来优化你的本地图片。你仍然可以使用远程图片,但是它们将不会被 Astro 的 <Image /> 组件渲染。
```md title="src/content/blog/post.mdoc" <!-- 由 <Image /> 优化组件 -->  <!-- 未优化的 <img> 标签 -->  ```创建一个自定义的 Markdoc 图片标签
Markdoc 的 image 标签允许你在图片上设置额外的属性,这是用 ![]() 语法无法实现的。例如,自定义图片标签允许你对需要 width 和 height 的远程图片使用 Astro 的 <Image /> 组件。
以下步骤将创建一个自定义的 Markdoc 图片标签,以显示一个带有标题的 <figure> 元素,使用 Astro 的 <Image /> 组件来优化图片。
```astro title="src/components/MarkdocFigure.astro" --- // src/components/MarkdocFigure.astro import { Image } from "astro:assets"; interface Props { src: ImageMetadata | string; alt: string; width: number; height: number; caption: string; } const { src, alt, width, height, caption } = Astro.props; --- <figure> <Image {src} {alt} {width} {height} /> {caption && <figcaption>{caption}</figcaption>} </figure> ```2. 配置你的自定义图片标签来渲染你的 Astro 组件:
```ts title="markdoc.config.mjs" import { component, defineMarkdocConfig, nodes } from '@astrojs/markdoc/config'; export default defineMarkdocConfig({ tags: { image: { attributes: { width: { type: String, }, height: { type: String, }, caption: { type: String, }, ...nodes.image.attributes }, render: component('./src/components/MarkdocFigure.astro'), }, }, }); ```3. 在 Markdoc 文件中使用 image 标签来显示一个带有标题的图形,为你的组件提供所有必要的属性:
```md {% image src="./astro-logo.png" alt="Astro Logo" width="100" height="100" caption="a caption!" /%} ```Markdoc 高级配置
markdoc.config.mjs|ts 文件接受 所有 Markdoc 配置选项,包括 标签 和 函数。
你可以从 markdoc.config.mjs|ts 文件的默认导出中传递这些选项:
复制代码到剪贴板
import { defineMarkdocConfig } from '@astrojs/markdoc/config';export default defineMarkdocConfig({ functions: { getCountryEmoji: { transform(parameters) { const [country] = Object.values(parameters); const countryToEmojiMap = { japan: '🇯🇵', spain: '🇪🇸', france: '🇫🇷', }; return countryToEmojiMap[country] ?? '🏳'; }, }, },});
现在,你可以从任何 Markdoc 内容条目中调用这个函数:
复制代码到剪贴板
¡Hola {% getCountryEmoji("spain") %}!
查看 Markdoc 文档 了解更多关于在你的内容中使用变量或函数的信息。
设置根 HTML 元素
默认情况下,Markdoc 会用 <article> 标签包裹文档。这可以通过修改 Markdoc 的 document 节点来改变。它接受一个 HTML 元素名称或者如果你希望移除包裹元素,可以使用 null:
复制代码到剪贴板
import { defineMarkdocConfig, nodes } from '@astrojs/markdoc/config';export default defineMarkdocConfig({ nodes: { document: { ...nodes.document, // 应用其他选项的默认值 render: null, // 默认为 'article' }, },});
集成配置选项
Astro Markdoc 集成处理了在 markdoc.config.js 文件中不可用的 Markdoc 选项和功能的配置。
allowHTML
允许在 Markdoc 标签和节点旁边编写 HTML 标记。
默认情况下,Markdoc 不会将 HTML 标记识别为语义内容。
要实现更接近 Markdown 的体验,其中 HTML 元素可以与你的内容一起使用,请将 allowHTML:true 作为 markdoc 集成选项设置。这将在 Markdoc 标记中启用 HTML 解析。
复制代码到剪贴板
import { defineConfig } from 'astro/config'; import markdoc from '@astrojs/markdoc'; export default defineConfig({ // ... integrations: [markdoc({ allowHTML: true })], });
:::caution 当 allowHTML 被启用时,Markdoc 文档中的 HTML 标记将被渲染为实际的 HTML 元素(包括 <script>),这将使 XSS 等攻击向量成为可能。确保任何 HTML 标记来自可信的来源。 :::
ignoreIndentation
默认情况下,任何使用四个空格缩进的内容都会被视为代码块。不幸的是,这种行为使得在具有复杂结构的文档中用任意级别的缩进来提高可读性变得困难。
在使用 Markdoc 的嵌套标签时,将标签内的内容缩进可以帮助清楚地显示层级深度。为了支持任意缩进,我们需要禁用基于缩进的代码块,并修改几个其他的 markdown-it 解析规则,以忽略缩进的代码块。即通过启用 ignoreIndentation 选项可以应用这些修改。
复制代码到剪贴板
import { defineConfig } from 'astro/config'; import markdoc from '@astrojs/markdoc'; export default defineConfig({ // ... integrations: [markdoc({ ignoreIndentation: true })], });
复制代码到剪贴板
# 欢迎使用带有缩进标签的 Markdoc 👋# 注意:可以使用空格或制表符进行缩进{% custom-tag %}{% custom-tag %} ### 标签可以缩进以提高可读性 {% another-custom-tag %} 当有大量嵌套时,这一点更容易遵循。 {% /another-custom-tag %}{% /custom-tag %}{% /custom-tag %}
示例
- Astro Markdoc 入门模板 展示了如何在你的 Astro 项目中使用 Markdoc 文件。