MDX 运行时助手
Methanol 默认为每个 MDX 文件注入轻量级运行时上下文,旨在简化动态内容生成及模板集成流程。
上下文变量
在 MDX 环境中,以下辅助变量始终全局可用:
ctx: 完整的页面与站点上下文对象。frontmatter:ctx.page.frontmatter的简写别名。rawHTML: 用于插入未转义 HTML 内容的工具函数。
# {frontmatter.title ?? ctx.page.title}
当前路由:{ctx.routePath}
上下文结构
ctx 对象包含的核心属性如下:
ctx.page: 当前页面的元数据对象(详见下文模式说明)。ctx.pages: 包含全站页面(含隐藏页及索引页)的扁平化集合(排除exclude: true,且除非显式设置hidden: false,否则不包含/404和/offline)。ctx.pagesByRoute:routePath -> page的Map对象,用于快速查询。ctx.pagesTree: 基于当前根目录范围的层级导航树。ctx.site: 全局站点元数据(如name,root,pagesDir,distDir,pagefind等)。ctx.withBase(path): 路径处理工具,自动为以/开头的 URL 附加配置的site.base或 Vite base(相对 URL 保持不变)。ctx.language: 当前激活的语言入口对象(源自目录索引页的lang配置;包含label与code)。ctx.getSiblings(): 返回当前页面的相邻节点对象{ prev, next },遵循当前导航根范围。ctx.routePath/ctx.routeHref: 当前页面的路由信息。ctx.path: 当前页面的绝对文件系统路径。
注意:对于 theme.sources 中的 URL 或 public/ 目录下的静态文件,通常无需手动调用 ctx.withBase()(构建系统将自动解析)。但在 JS 中动态生成 URL 且遇到开发环境路径解析不一致时,该工具是有效的解决方案。
ctx.site
ctx.site 是站点级元数据和构建标志的快照,包括:
name,owner,base,moderoot,pagesDir,componentsDir,publicDir,distDirpagefind(enabled,options,build)feed(enabled,atom,path,href)pwa(enabled,manifestPath,manifestHref)generatedAt
ctx.page 元数据对象
ctx.page 提供当前页面的完整元数据信息。完整字段列表如下:
routePath: 标准化后的路由路径(例如/guide/writing)。routeHref: 包含 Base Path 的链接 Href(自动适配site.base/ Vite base)。path: 源文件的绝对系统路径。source: 文件来源标识("user"或"theme")。relativePath: 相对于pagesDir的路径(包含文件扩展名)。name: 去除扩展名后的文件名。dir: 相对于pagesDir的目录路径(根目录为'')。segments: 路由路径片段数组。depth: 路由层级深度。isIndex: 布尔值,若文件为index.mdx则为true。title: 解析后的页面标题(优先取自 Frontmatter,或从标题推断)。frontmatter: 解析后的 YAML Frontmatter 对象。matter: 原始 Frontmatter 数据块。content: 去除 Frontmatter 后的 Markdown 正文原始内容。toc: 提取出的目录结构数据。weight: 用于排序的数值权重(来自 Frontmatter)。date: 标准化的 ISO 日期字符串(来自 Frontmatter)。isRoot: 布尔值,若页面定义了导航根节点则为true。hidden: 布尔值,若页面在导航中隐藏则为true。hiddenByParent: 字符串或null,最近的隐藏父级路由(例如/hidden/)。hiddenByParents: 布尔值,若页面位于任意隐藏分区下则为true。exclude: 布尔值,若页面被构建流程排除则为true。stats.size: 文件大小(字节)。stats.createdAt: 文件创建时间戳(ISO 格式,如可用)。stats.updatedAt: 文件最后修改时间戳(ISO 格式,如可用)。
注:目录索引页面的 routePath 始终包含尾随斜杠(例如 /guide/)。
运行时注入了 ctx.page.getSiblings() 以支持前后页导航。
使用示例:
{ctx.page.title}
{ctx.page.frontmatter?.excerpt}
ctx.pages 集合
ctx.pages 是一个包含项目及主题中所有页面元数据(结构同 ctx.page)的扁平数组。它会自动剔除标记为 exclude: true 的页面,并且除非显式设置 hidden: false,否则会忽略 /404 和 /offline 页面。隐藏页面可能仍会出现在此集合中,但 ctx.pagesTree 会将其过滤掉。
此属性适用于生成自定义索引、站点地图或手动构建导航结构:
<ul>
{ctx.pages.map((page) => (
<li><a href={page.routeHref || page.routePath}>{page.title}</a></li>
))}
</ul>
ctx.pagesTree 层级树
ctx.pagesTree 表示当前根上下文下的导航层级结构(严格遵循 isRoot 与 hidden 规则)。节点结构如下:
type:"page"或"directory"title/name: 显示标签。routePath/routeHref: 节点对应的路由。children: 子节点数组(仅目录节点)。
可用于构建与侧边栏结构一致的导航 UI:
{ctx.pagesTree.map((node) => (
<div>{node.title || node.name}</div>
))}
ctx.getSiblings 辅助函数
ctx.getSiblings() 用于获取当前导航序列中的前一页与后一页。该函数遵循当前导航根设定及可见性规则,确保顺序与侧边栏保持一致。
{(() => {
const siblings = ctx.getSiblings()
if (!siblings) return null
return (
<nav>
{siblings.prev ? <a href={siblings.prev.routeHref || siblings.prev.routePath}>上一页: {siblings.prev.title}</a> : null}
{siblings.next ? <a href={siblings.next.routeHref || siblings.next.routePath}>下一页: {siblings.next.title}</a> : null}
</nav>
)
})()}
rawHTML 工具
rawHTML 用于插入未转义的原始 HTML 内容。这对于嵌入内联脚本或需保留原始格式的标记尤为有用。
{rawHTML('<span class="badge">Beta</span>')}
{rawHTML`<div data-banner="true">Banner</div>`}
rawHTML 同样支持信号(Signals)与标准模板插值。