ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

mdBook index.hbs 模板完全指南:上下文数据、Handlebars 助手与自定义主题

mdBook index.hbs 模板完全指南:上下文数据、Handlebars 助手与自定义主题 开发工具文档【免费下载链接】mdBookCreate book from markdown files. Like Gitbook but implemented in Rust项目地址https://gitcode.com/gh_mirrors/md/mdBook点击查看免费下载导读index.hbs是 mdBook HTML 渲染器使用的 Handlebars 模板负责将每一章 Markdown 渲染出的 HTML 注入页面骨架决定整本书的布局与样式。本文基于官方指南 guide/src/format/theme/index-hbs.md 展开并结合仓库中 crates/mdbook-html/src/html_handlebars/hbs_renderer.rs 等源码实现系统讲解模板可访问的全部上下文属性、toc/resource/fa三个内置助手的工作原理与使用方式。读完本文你将掌握如何阅读默认模板、在自定义index.hbs中正确取用数据以及如何利用mdbook init --theme安全地定制主题而不破坏默认功能。index.hbs 在渲染管线中的位置在 mdBook 中Markdown 源文件并不会被直接当作 HTML 输出。渲染流程是每一章 Markdown 先被转换为 HTML 片段content随后被注入到index.hbs这个 Handlebars 模板中最终写出为.html文件。这一流程在 crates/mdbook-html/src/html_handlebars/hbs_renderer.rs 中清晰可见// Render the handlebars template with the data let rendered ctx.handlebars.render(index, ctx.data)?; fs::write(out_path, rendered)?;模板本身在render()入口被注册handlebars.register_template_string(index, String::from_utf8(theme.index.clone())?)?;默认的index.hbs位于 crates/mdbook-html/front-end/templates/index.hbs并通过include_bytes!编译进 mdBook 二进制见 crates/mdbook-html/src/theme/mod.rs。也就是说即使你的项目目录下没有theme/文件夹mdBook 也内置了一份完整的模板只有当你显式提供同名文件覆盖时才会使用你的版本。如果你想改变书的布局或风格大概率需要动这个模板。下面先介绍模板中能访问到的所有数据。模板上下文Context中暴露的数据mdBook 在渲染前会构造一个 JSON 上下文即「context」模板通过{{name_of_property}}语法访问其中的属性。这些数据由make_data()函数统一构建见 crates/mdbook-html/src/html_handlebars/hbs_renderer.rs并在render_chapter()中按章节补充同文件第 87-123 行。完整属性如下属性类型说明取值来源language字符串书的语言如en未在book.toml中指定时默认为en。常用于html lang{{ language }}config.book.languagetitle字符串当前页面的标题等价于{{ chapter_title }} - {{ book_title }}若未设置book_title则退化为chapter_titlerender_chapter()中拼接book_title字符串书的标题来自book.tomlconfig.book.titlechapter_title字符串当前章节标题来自SUMMARY.md中的章节名ch.namepath字符串当前章节源 Markdown 文件相对于src目录的路径ch.pathcontent字符串当前章节渲染后的 HTML 内容由 markdown 渲染管线产出path_to_root字符串从当前文件指向书根目录的相对路径内容全部是../。由于输出保留了源目录结构做相对链接时常用它作为前缀fs::path_to_root(path)previous/next对象上一章/下一章导航对象含title与link两个属性render_chapter()中构造chapters数组全书章节列表元素为字典形如{section: 1.2.1, name: 章节名, path: dir/markdown.md}常用于构造侧边栏目录make_data()遍历book.iter()除了上述文档明确列出的属性从make_data()源码还可以看到模板还能访问更多上下文例如text_direction文本方向对应book.toml的text-direction、description、favicon_png/favicon_svg、default_theme/preferred_dark_theme/builtin_themes、mathjax_support、additional_css/additional_js、print_enable、fold_enable/fold_level、search_enabled/search_js、git_repository_url/git_repository_icon、live_reload_endpoint、playground_*系列等。默认模板正是借助这些属性实现主题切换、搜索、代码复制、实时重载等功能的。previous / next 的典型用法导航对象在 hbs_renderer.rs 第 108-123 行 中构造link是相对当前书根目录的.html路径因此模板中通常与path_to_root配合使用默认模板的写法是{{#if previous}} a relprev href{{ path_to_root }}{{previous.link}} classnav-chapters previous ... {{/if}} {{#if next}} a relnext prefetch href{{ path_to_root }}{{next.link}} classnav-chapters next ... {{/if}}chapters 的结构细节从 make_data() 第 609-645 行 可以看出chapters数组中的每个元素实际可能包含的键比文档示例更丰富普通章节section如1.2.1、name、path、has_sub_items是否含有子章节分部标题Part仅含part键分隔符Separator仅含spacer键。这些额外字段是toc助手见下生成侧边栏时的重要输入。Handlebars 内置助手helpers除了数据属性mdBook 还向 Handlebars 注册了三个助手。注册代码在 hbs_renderer.rs 第 234-242 行fn register_hbs_helpers(self, handlebars: mut Handlebars_, html_config: HtmlConfig) { handlebars.register_helper( toc, Box::new(helpers::toc::RenderToc { no_section_label: html_config.no_section_label, }), ); handlebars.register_helper(fa, Box::new(helpers::fontawesome::fa_helper)); }其中resource助手比较特殊——它不是一开始就注册的而是在静态文件写完、拿到哈希映射之后才注册hbs_renderer.rs 第 409-413 行。toc生成侧边栏目录toc助手以块级助手的形式使用{{#toc}}{{/toc}}它会根据书的结构输出类似下面的 HTML缩进与结构随书的层级变化ul classchapter lia hreflink/to/file.htmlSome chapter/a/li li ul classsection lia hreflink/to/other_file.htmlSome other Chapter/a/li /ul /li /ul从源码实现crates/mdbook-html/src/html_handlebars/helpers/toc.rs可以看到它依赖上下文中的chapters、fold_enable、fold_level、is_toc_html等数据通过root/chapters读取章节数组按section中.的数量判断层级输出嵌套的ol classsection根据fold_enable与fold_level决定章节是否折叠展开对无path的条目输出span而非a对带has_sub_items的条目在折叠模式下输出a classchapter-fold-toggle❱/a展开/收起按钮在 iframetoc.html中渲染时链接会带上target_parent若配置了no-section-label true则不再输出章节编号strong标签。如果你希望目录采用不同的结构例如自绘侧边栏toc助手无法定制但你可以直接读取chapters属性用 JavaScript 在模板里自行处理script var chapters {{chapters}}; // Processing here /script注意{{chapters}}输出的是 JSON 字面量需要确认它是否应加引号默认模板中chapters被序列化进toc.js供 JavaScript 使用详见 toc.js.hbs。文档特别提醒目前要用非默认目录结构只能借助 JavaScriptHandlebars 层尚无替代助手。resource静态资源路径resource助手用于获取静态文件的路径。它有两个关键特性隐式包含path_to_root输出的路径自动以指向书根目录的../前缀开头因此你无需手动拼接自动适配带哈希的文件名启用output.html.hash-files时静态文件会被重命名为名称-哈希前4字节.扩展名的形式resource会根据内部哈希表把模板中的逻辑名翻译成真实文件名。典型用法link relstylesheet href{{ resource css/chrome.css }}实现位于 crates/mdbook-html/src/html_handlebars/helpers/resources.rs它从上下文root/path计算path_to_root然后查hash_map查不到时原样返回传入的名字。哈希重命名本身由 static_files.rs 的 hash_files() 完成——对文件内容取 SHA-256 摘要的前 4 字节拼进文件名而write_files()还会用正则\{\{ resource ([^]) \}\}替换 CSS/JS 文件内部的{{ resource ... }}指令让资源之间也能互相引用static_files.rs 第 210-236 行。关于哈希文件的配置可参考 guide/src/format/configuration/renderers.md 中output.html.hash-files的说明。fa内联 Font Awesome 图标mdBook 内置了 Font Awesome Free 的 MIT 许可 SVG 文件副本fa助手可以直接把图标渲染为内联 SVG。它接受三个位置参数Type类型solid、regular、brands之一light与duotone目前不支持Icon图标名从免费图标集中任选如print、bars、magnifying-glassID可选若提供会作为id属性添加到图标外层span上。例如{{fa solid print print-button}}渲染结果span classfa-svg idprint-buttonsvg xmlnshttp://www.w3.org/2000/svg viewBox0 0 512 512path dM448 192V77.25c0-8.49-3.37-16.62-9.37-22.63L393.37 9.37c-6-6-14.14-9.37-22.63-9.37H96C78.33 0 64 14.33 64 32v160c-35.35 0-64 28.65-64 64v112c0 8.84 7.16 16 16 16h48v96c0 17.67 14.33 32 32 32h320c17.67 0 32-14.33 32-32v-96h48c8.84 0 16-7.16 16-16V256c0-35.35-28.65-64-64-64zm-64 256H128v-96h256v96zm0-224H128V64h192v48c0 8.84 7.16 16 16 16h48v96zm48 72c-13.25 0-24-10.75-24-24 0-13.26 10.75-24 24-24s24 10.74 24 24c0 13.25-10.75 24-24 24z//svg/span实现见 crates/mdbook-html/src/html_handlebars/helpers/fontawesome.rs其中还做了前缀容错传入的图标名会先剥离fa-、fab-、fas-前缀再查表若图标不存在渲染会报错并提示去 Font Awesome 免费图标站核对图标名与类型前缀。默认模板中大量使用该助手例如菜单栏的{{fa solid bars}}、主题切换按钮{{fa solid paintbrush}}、搜索按钮{{fa solid magnifying-glass}}、打印按钮{{fa solid print print-button}}等见 index.hbs。另外git-repository-icon配置会决定菜单栏 Git 仓库图标所用的类型与图标名make_data()会根据图标名前缀把fab-github翻译成brands类型见 hbs_renderer.rs 第 593-607 行。在默认模板中的实际用法默认模板 index.hbs 是学习以上所有特性的最佳范例。几个值得关注的片段语言与文本方向html lang{{ language }} class{{ default_theme }} sidebar-visible dir{{ text_direction }}页面标题title{{ title }}/title无 JS 时的目录iframe classsidebar-iframe-outer src{{ path_to_root }}toc.html/iframe正文注入main{{{ content }}}/main注意是三对花括号表示输出不转义的 HTML代码高亮与剪贴板脚本script src{{ resource clipboard.min.js }}/script script src{{ resource highlight.js }}/script script src{{ resource book.js }}/script默认模板还通过{{#if search_enabled}}、{{#if print_enable}}、{{#if git_repository_url}}、{{#if canonical_url}}等条件块按配置动态决定是否渲染搜索栏、打印页链接、Git 仓库入口与 canonical 链接这为你自定义模板时如何处理可选配置提供了现成的参考模式。自定义 index.hbs 的推荐做法通过 theme 目录覆盖mdBook 的 HTML 渲染器自带默认主题全部资源文件都编译在内。你可以通过在自己的书根目录下src旁边新建theme目录并放置同名文件来实现选择性覆盖凡是theme目录里存在的文件都会替换内置默认版本。index.hbs就放在theme/index.hbs。可覆盖文件的完整清单见 guide/src/format/theme/README.md其中与本文相关的包括index.hbs整页模板head.hbs追加到每页 HTMLhead部分的内容通过{{ head}}部分模板注入见 index.hbs 第 19 行header.hbs追加到每个页面顶部的内容通过{{ header}}注入toc.js.hbs与toc.html.hbs用于渲染toc.js与无 JS 侧边栏 iframe 页面toc.html的模板。从 theme/mod.rs 的 Theme::new() 可以看出主题目录的匹配是精确到文件名的目录下存在哪个文件就覆盖哪个不存在的文件继续使用内置版本。此外还有两个值得注意的行为字体目录fonts/里只要存在fonts.css内置的 Open Sans / Source Code Pro 字体包就不会再输出favicon.png与favicon.svg只会同时覆盖或同时保留默认——只覆盖其中一个时另一个也不会被复制对应 theme/mod.rs 第 145-159 行 的配对逻辑。使用 mdbook init --theme 快速起步官方指南建议自定义主题时不要一次性覆盖全部文件。原因是自定义文件优先于内置文件而内置版本会随 mdBook 版本更新获得新修复/新特性长期整体覆盖会让你错过这些更新。推荐的流程是运行mdbook init --theme把默认主题自动复制进你的源码目录删除你不需要覆盖的文件只保留要修改的那几个以默认文件为模板仅增改你需要的部分。这样做同时能保证你不会因为遗漏某个必要的标签而破坏功能例如某些脚本、样式或 aria 属性。另外注意mdbook init --theme不会创建全部文件——像head.hbs这样的文件本来就没有内置对应物需要时自行创建即可。覆盖主题后的配套配置如果你彻底替换了内置主题例如移除了所有内置 CSS 变量定义请务必在book.toml中显式设置output.html.preferred-dark-theme它决定浏览器通过prefers-color-scheme: dark请求深色模式时使用哪个主题默认值为内置的navy。相关配置项见 guide/src/format/configuration/renderers.md 中的「HTML renderer options」一节其中theme、default-theme、preferred-dark-theme、no-section-label控制toc助手是否输出章节编号等选项都与本文介绍的数据和助手直接相关。小结index.hbs是 mdBook 定制外观的枢纽Markdown 内容经渲染后以content注入模板模板再借助language、title、path_to_root、previous/next、chapters等上下文数据以及toc、resource、fa三个助手完成页面骨架、导航、静态资源与图标的输出。理解这些数据与助手的来源和边界hbs_renderer.rs、helpers 目录、默认模板 index.hbs再配合mdbook init --theme与「只覆盖需要的文件」原则你就能安全、高效地把 mdBook 的输出打磨成自己的样式。赞分享开发工具文档【免费下载链接】mdBookCreate book from markdown files. Like Gitbook but implemented in Rust项目地址https://gitcode.com/gh_mirrors/md/mdBook点击查看免费下载相关推荐从零到一Duix.Avatar开源AI虚拟分身完整指南从零到一Duix.Avatar开源AI虚拟分身完整指南 在数字时代拥有一个能代表你的AI虚拟分身不再是遥不可及的梦想。Duix.Avatar作为真正开源的A人工智能AI 应用数字人媒体生成桌面应用终极BilibiliDown指南3分钟学会B站视频下载打造个人专属离线资源库终极BilibiliDown指南3分钟学会B站视频下载打造个人专属离线资源库 你是否曾因为网络不稳定而错过B站上的精彩教学视频是否担心收藏的优质内容突然下音视频桌面应用ForgeCode 自定义 Agent 系统提示模板解析从 Handlebars 模板到运行时系统上下文的完整实现指南ForgeCode 自定义 Agent 系统提示模板解析从 Handlebars 模板到运行时系统上下文的完整实现指南 ForgeCode本仓库项目支持通人工智能AI Agent代码智能体AI 应用CLI开发工具上一篇Mac Mouse Fix 完整指南把百元鼠标变成比触控板更顺滑的 macOS 指针下一篇Transmission NAT-PMP协议实现自动化端口映射的技术架构与实践创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表