如何在Jekyll的HTML模板中使用TOC(非*.md文章)及渲染问题排查
Jekyll HTML模板中实现目录(TOC)功能的解决方案
先解决你的核心疑惑:为什么在post.html模板里用TOC(不管加不加{{ }})都无法渲染?
核心原因是Jekyll的TOC生成逻辑默认只针对Markdown文章的内容,而非模板文件本身:
- 如果你直接写
{{ toc }},这个变量根本不存在(除非你自己在模板或配置里定义过),自然不会输出任何内容。 - 就算用插件提供的
{% toc %}标签,它默认也是解析当前页面的content变量——也就是你写的Markdown文章转成的HTML内容,而不是post.html模板里的HTML代码。模板文件本身是Liquid/HTML混合代码,Jekyll不会把它当作Markdown来解析,也不会自动提取其中的标题生成TOC。
接下来分两种场景,教你如何在HTML模板中实现TOC功能:
场景1:为Markdown文章内容生成TOC(最常见需求)
如果你想在post.html模板里展示当前文章的目录,这需要借助Jekyll的TOC插件(比如官方推荐的jekyll-toc),步骤如下:
安装并配置插件
- 在你的项目Gemfile中添加:
gem 'jekyll-toc' - 在
_config.yml中启用插件:plugins: - jekyll-toc
- 在你的项目Gemfile中添加:
在post.html模板中插入TOC
找到你想要放置目录的位置(比如文章内容的上方),添加以下Liquid代码:<div class="article-toc"> <h3>文章目录</h3> {% toc %} </div>这段代码会自动解析当前文章的
content(即Markdown转成的HTML)中的<h1>到<h6>标签,生成带锚点的无序列表目录。如果你想自定义TOC的层级(比如只提取h2和h3),可以修改标签参数:
{% toc h2-h3 %}
场景2:为HTML模板自身的内容生成TOC
如果你的post.html模板本身有固定的HTML标题(比如模板自带的导航、说明板块的标题),需要为这些标题生成TOC,就得手动实现锚点链接:
方法1:纯手动编写
给每个标题添加唯一的id,然后手动创建目录列表:
<!-- TOC部分 --> <div class="template-toc"> <h3>模板目录</h3> <ul> <li><a href="#template-section-1">模板第一部分</a></li> <li><a href="#template-section-2">模板第二部分</a></li> </ul> </div> <!-- 模板内容部分 --> <h2 id="template-section-1">模板第一部分</h2> <p>这里是模板自带的内容...</p> <h2 id="template-section-2">模板第二部分</h2> <p>这里是模板的另一块内容...</p>
方法2:动态生成(适合标题来自数据文件的情况)
如果模板的标题是从_data目录下的文件读取的,可以用Liquid循环自动生成TOC和对应标题:
- 先创建
_data/template_sections.yml:- title: 模板第一部分 id: template-section-1 content: 这里是模板自带的内容... - title: 模板第二部分 id: template-section-2 content: 这里是模板的另一块内容... - 在post.html模板中写入:
<!-- 动态生成TOC --> <div class="template-toc"> <h3>模板目录</h3> <ul> {% for section in site.data.template_sections %} <li><a href="#{{ section.id }}">{{ section.title }}</a></li> {% endfor %} </ul> </div> <!-- 动态生成内容 --> {% for section in site.data.template_sections %} <h2 id="{{ section.id }}">{{ section.title }}</h2> <p>{{ section.content }}</p> {% endfor %}
内容的提问来源于stack exchange,提问作者Natalie Perret




