@astrojs/markdoc
这个 Astro 集成 允许使用 Markdoc 来创建组件、页面和内容集合条目。
为什么是 Markdoc?
段落标题 为什么是 Markdoc?Markdoc 允许你使用 Astro 组件 增强 Markdown。如果你已经使用 Markdoc 编写了现有内容,此集成允许你使用内容集合将这些文件带到 Astro 项目中。
安装
段落标题 安装快速安装
段落标题 快速安装astro add
命令行工具可以自动为你安装。在新的终端窗口中运行以下命令之一。(如果你不确定你使用的是哪个包管理器,请运行第一个命令。)然后,按照提示操作,在终端中输入 “y”(意思是 “yes”)。
# 使用 NPMnpx astro add markdoc# 使用 Yarnyarn astro add markdoc# 使用 PNPMpnpm astro add markdoc
如果你遇到任何问题,请随时在 GitHub 上向我们报告,并尝试下面的手动安装步骤。
手动安装
段落标题 手动安装首先,使用你的包管理器安装 @astrojs/markdoc
包。如果你使用的是 npm 或者不确定,请在终端中运行以下命令:
npm install @astrojs/markdoc
然后,在你的 astro.config.*
文件中使用 integrations
属性应用这个集成:
import { defineConfig } from 'astro/config';import markdoc from '@astrojs/markdoc';export default defineConfig({ // ... integrations: [markdoc()], // ^^^^^^^^^});
编辑器集成
段落标题 编辑器集成VS Code 默认支持 Markdown。但是,为了支持 Markdoc 编辑器,你可能希望在 VSCode 配置中添加以下设置。这样可以确保编写 Markdoc 文件时提供类似 Markdown 的编辑器体验。
{ "files.associations": { "*.mdoc": "markdown" }}
用法
段落标题 用法Markdoc 文件只能在内容集合中使用。使用 .mdoc
扩展名将条目添加到任何内容集合中:
src/content/docs/ why-markdoc.mdoc quick-start.mdoc
然后,使用 内容集合 API 查询你的集合:
---import { getEntryBySlug } from 'astro:content';
const entry = await getEntryBySlug('docs', 'why-markdoc');const { Content } = await entry.render();---
<!--使用 `data` 访问 frontmatter 属性`--><h1>{entry.data.title}</h1><!--使用 Content 组件渲染 Markdoc 内容--><Content />
📚 了解更多关于 Astro 内容集合文档 的信息。
Markdoc 配置
段落标题 Markdoc 配置@astrojs/markdoc
提供了配置选项,以使用 Markdoc 的所有功能,并将 UI 组件连接到你的内容。
将 Astro 组件作为 Markdoc 标签
段落标题 将 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 %}
使用 npm 包和 TypeScript 文件中的 Astro 组件
段落标题 使用 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';
自定义标题
段落标题 自定义标题@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 - 6id: string
从标题的文本内容生成的id
。这对应于 内容render()
函数生成的slug
。
例如,标题 ### Level 3 heading!
将会传递 level: 3
和 id: 'level-3-heading'
作为组件的 props。
语法高亮
段落标题 语法高亮@astrojs/markdoc
提供了 Shiki 和 Prism 扩展来高亮你的代码块。
Shiki
段落标题 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://github.com/shikijs/shiki/blob/main/docs/themes.md theme: 'dracula', // 启用单词折叠以防止水平滚动 // 默认:false wrap: true, // 传入自定义语言 // 注意:Shiki 内置了许多的 langs,包括 `.astro`! // https://github.com/shikijs/shiki/blob/main/docs/languages.md langs: [], }), ],});
Prism
段落标题 Prism使用 extends
属性将 prism()
扩展应用到你的 Markdoc 配置中。
import { defineMarkdocConfig } from '@astrojs/markdoc/config';import prism from '@astrojs/markdoc/prism';
export default defineMarkdocConfig({ extends: [prism()],});
📚 要了解如何配置 Prism 样式表,请看我们的语法高亮指南。
设置根 HTML 元素
段落标题 设置根 HTML 元素默认情况下,Markdoc 会使用 <article>
标签包装文档。这可以从 document
Markdoc 节点中更改。这个节点接受一个 HTML 元素名称,或者如果你想删除包装元素的话,可以传递 null
:
import { defineMarkdocConfig, nodes } from '@astrojs/markdoc/config';
export default defineMarkdocConfig({ nodes: { document: { ...nodes.document, // 应用默认的其他配置项 render: null, // 默认 'article' }, },});
自定义 Markdoc 节点 / 元素
段落标题 自定义 Markdoc 节点 / 元素你可能想要将标准的 Markdown 元素,例如段落和加粗文本,渲染为 Astro 组件。为此,你可以配置一个 Markdoc 节点。如果给定的节点接收到属性,它们可将作为组件 props 来使用。
这个例子使用一个自定义的 Quote.astro
组件渲染引用块:
import { defineMarkdocConfig, nodes, component } from '@astrojs/markdoc/config';
export default defineMarkdocConfig({ nodes: { blockquote: { ...nodes.blockquote, // 应用默认的其他配置项 render: component('./src/components/Quote.astro'), }, },});
📚 在他们的文档中找到 Markdoc 的所有内置节点和节点属性。
使用客户端 UI 组件
段落标题 使用客户端 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 }, }, }, },});
Markdoc 配置
段落标题 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 文档 了解更多关于在你的内容中使用变量或函数的信息。
Markdoc 语言服务器
段落标题 Markdoc 语言服务器如果你使用的是 VS Code,有一个官方的 Markdoc 语言扩展,它包括了为配置的标签提供语法高亮和自动完成。在 GitHub 上查看语言服务器 的更多信息。
要设置这个扩展,创建一个 markdoc.config.json
文件到项目根目录,内容如下:
[ { "id": "my-site", "path": "src/content", "schema": { "path": "markdoc.config.mjs", "type": "esm", "property": "default", "watch": true } }]
schema
属性 包含了为 Astro 内容集合配置语言服务器的所有信息。它接受以下属性:
path
: 配置文件的路径。type
: 配置文件使用的模块类型(esm
允许import
语法)。property
: 包含配置对象的导出属性名称。watch
: 告诉服务器监听配置中的更改。 顶级path
属性告诉服务器内容位于哪里。由于 Markdoc 是特定于内容集合的,因此可以使用src/content
。
传递 Markdoc 变量
段落标题 传递 Markdoc 变量你可能需要将 变量 传递给你的内容。当传递 SSR 参数时,这是很有用的,比如 A/B 测试。
变量可以通过 Content
组件作为 props 传递:
---import { getEntryBySlug } from 'astro:content';
const entry = await getEntryBySlug('docs', 'why-markdoc');const { Content } = await entry.render();---
<!--将`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
段落标题 从你的 Markdoc 内容中访问 frontmatter要访问 frontmatter,你可以在渲染内容的地方将条目 data
属性 作为变量 传递:
---import { getEntry } from 'astro:content';
const entry = await getEntry('docs', 'why-markdoc');const { Content } = await entry.render();---
<Content frontmatter={entry.data} />
这样就可以在你的 Markdoc 中作为 $frontmatter
访问。
集成配置选项
段落标题 集成配置选项Astro Markdoc 集成处理了在 markdoc.config.js
文件中不可用的 Markdoc 选项和功能的配置。
allowHTML
段落标题 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 })], // ^^^^^^^^^^^^^^^});
当 allowHTML
被启用时,Markdoc 文档中的 HTML 标记将被渲染为实际的 HTML 元素(包括 <script>
),这将使 XSS 等攻击向量成为可能。确保任何 HTML 标记来自可信的来源。
ignoreIndentation
段落标题 ignoreIndentation默认情况下,任何使用四个空格缩进的内容都会被视为代码块。不幸的是,这种行为使得在具有复杂结构的文档中用任意级别的缩进来提高可读性变得困难。
在使用 Markdoc 的嵌套标签时,将标签内的内容缩进可以帮助清楚地显示层级深度。为了支持任意缩进,我们需要禁用基于缩进的代码块,并修改几个其他的 markdown-it 解析规则,以忽略缩进的代码块。即通过启用 ignoreIndentation 选项可以应用这些修改。
import { defineConfig } from 'astro/config';import markdoc from '@astrojs/markdoc';
export default defineConfig({ // ... integrations: [markdoc({ ignoreIndentation: true })], // ^^^^^^^^^^^^^^^^^^^^^^^});
# Welcome to Markdoc with indented tags 👋
# Note: Can use either spaces or tabs for indentation
{% custom-tag %}{% custom-tag %} ### Tags can be indented for better readability
{% another-custom-tag %} This is easier to follow when there is a lot of nesting {% /another-custom-tag %}
{% /custom-tag %}{% /custom-tag %}
示例
段落标题 示例- Astro Markdoc 入门模板 展示了如何在你的 Astro 项目中使用 Markdoc 文件。
故障排除
段落标题 故障排除寻求帮助,请查看 Discord 上的 #support
频道。我们友好的支持小组成员在这里帮助你!
你还可以查看我们的 Astro 集成文档 了解更多关于集成的信息。
贡献
段落标题 贡献这个项目由 Astro 核心团队维护。欢迎提交 issue 或 PR!
更新日志
段落标题 更新日志查看 CHANGELOG.md, 了解本集成的变更历史。