
Jekyll 的 Liquid 模板引擎完全指南输出、过滤器、标签与错误处理配置【免费下载链接】jekyll:globe_with_meridians: Jekyll is a blog-aware static site generator in Ruby项目地址: https://gitcode.com/gh_mirrors/je/jekyllJekyll 使用 Shopify 出品的 Liquid 为主线结合 filters、tags 与 Liquid 配置 三篇关联文档及仓库源码系统讲解 Liquid 基础语法、Jekyll 自带的过滤器与标签、代码高亮、链接生成以及通过_config.yml精细化控制 Liquid 错误行为的完整方案。读完本文你将能够熟练编写 Jekyll 模板、掌握其渲染与错误处理机制并具备排查模板问题的实战能力。一、Liquid 基础Jekyll 模板的两类语法Liquid 模板语言只有两种核心结构输出用双花括号{{ variable }}输出内容例如{{ page.title }}、{{ site.time }}逻辑用花括号加百分号{% if statement %}执行逻辑语句例如循环、条件判断、变量赋值。{% if page.tags.size 0 %} h3标签{{ page.tags | join: , }}/h3 {% endif %}Jekyll 在 lib/jekyll/liquid_renderer.rb 中直接与 Liquid 库对接LiquidRenderer初始化时会把配置中的liquid.error_mode转成符号并设置给Liquid::Template.error_mode模板解析与渲染则委托给 lib/jekyll/liquid_renderer/file.rb其中Liquid::Template.parse(content, :line_numbers true)会以开启行号的方式解析模板——这正是 Jekyll 报错时能精确指出in 文件路径:行号的原因。Jekyll 在此基础上提供了一批实用的 Liquid 增强能力集中在两大块Filters过滤器 与 Tags标签。标准 Liquid 的语法细节可参考官方 Liquid 文档下文聚焦 Jekyll 自身的实现。二、Liquid 配置错误模式与严格校验Liquid 对错误的响应行为可以通过_config.yml中的liquid.error_mode配置共有三档取值行为说明lax忽略所有错误构建继续不输出任何提示warn在控制台为每个错误输出警告默认值strict输出错误信息并停止构建适合 CI / 发布前检查Jekyll 内置的默认配置即liquid: error_mode: warn该默认值定义在 lib/jekyll/configuration.rb 的DEFAULTS常量中——完整的 Liquid 相关默认值为liquid: error_mode: warn # lax / warn / strict strict_filters: false # 是否在调用不存在的过滤器时抛错 strict_variables: false # 是否在引用未赋值的变量时抛错也就是说warn模式下构建过程中会指出任何问题但会尽可能继续构建。strict_variables 与 strict_filters自 Jekyll 3.8.0 起还可以让 Liquid 渲染器捕获两类“隐性错误”strict_variables: true引用未赋值的变量时抛错strict_filters: true调用不存在的过滤器时抛错。liquid: error_mode: strict strict_variables: true strict_filters: true如上配置后build/serve会在遇到 Liquid 相关问题时直接停止并指出违规内容非常适合在开发期强制暴露拼写错误例如把page.titel写成page.title的变体也适合集成到发布流水线中作为质量闸门。需要特别强调的是error_mode配置的是Liquid 解析器parser而strict_variables/strict_filters配置的是Liquid 渲染器renderer两者相互正交、互不影响。从源码看error_mode在LiquidRenderer#initialize时一次性写入Liquid::Template.error_mode全局生效而严格变量/过滤器检查发生在每次模板render阶段。三、Jekyll 内置过滤器Filters标准 Liquid 的 40 个过滤器abs、append、capitalize、date、escape、join、map、sort、truncate等在 Jekyll 中全部支持。为了让常见任务更简单Jekyll 还新增了一批自家过滤器完整清单及示例维护在 docs/_data/jekyll_filters.yml并在 lib/jekyll/filters.rb 中实现最后通过Liquid::Template.register_filter(Jekyll::Filters)注册进 Liquid。常用内置过滤器一览过滤器作用示例relative_url在输入前拼接baseurl配置值生成相对 URL适合部署在域名子路径的站点{{ /assets/style.css | relative_url }}→/my-baseurl/assets/style.cssabsolute_url拼接url与baseurl生成绝对 URL{{ /assets/style.css | absolute_url }}→http://example.com/my-baseurl/assets/style.cssdate_to_xmlschema日期转 XML SchemaISO 8601格式用于 sitemap{{ site.time | date_to_xmlschema }}→2008-11-07T13:07:54-08:00date_to_rfc822日期转 RFC-822 格式用于 RSS 订阅源{{ site.time | date_to_rfc822 }}→Mon, 07 Nov 2008 13:07:54 -0800date_to_string日期转短格式{{ site.time | date_to_string }}→07 Nov 2008date_to_string: ordinal, US序数美式短格式3.8.0Nov 7th, 2008date_to_long_string日期转长格式07 November 2008slugify文件名/标题转小写 URL 友好串可传模式参数见下{{ The _config.yml file | slugify }}→the-config-yml-filejsonify将数组或 Hash 转成 JSON 字符串{{ site.data.products | jsonify }}markdownify将 Markdown 字符串渲染为 HTML{{ page.excerpt | markdownify }}smartify将普通引号转为智能引号{{ He said hi | smartify }}number_of_words统计单词数支持cjk/auto模式以适配中文等 CJK 字符{{ page.content | number_of_words }}array_to_sentence_string数组转“a, b, and c”风格的英文句串{{ page.tags | array_to_sentence_string }}xml_escapeXML 转义{{ content | xml_escape }}cgi_escape/uri_escapeURL 编码{{ foo,bar;baz? | cgi_escape }}→foo%2Cbar%3Bbaz%3Fwhere/where_exp按属性 / 按表达式过滤对象数组见下文专项find/find_exp返回第一个匹配属性的对象否则返回nil{{ site.posts | find: title, Hello }}sort按属性排序可控制nil值出现在前first还是后last{{ site.posts | sort: date, last }}pop/push/shift/unshift/sample数组增删与随机取样非破坏性返回副本{{ array | sample: 3 }}to_integer转整数true→1false→0{{ 42 | to_integer }}normalize_whitespace将连续空白折叠为单个空格{{ page.content | normalize_whitespace }}inspect调试用返回对象的字符串表示并做 XML 转义{{ page | inspect }}注意where/find的第三个参数目标值不能是数组或 Hash——从 lib/jekyll/filters.rb 的实现可见这类值会走#to_s导致比较结果不可预期源码会直接返回原始输入。slugify 的六种模式slugify过滤器接受一个选项参数指定过滤哪些字符默认是default模式过滤内容none不过滤任何字符raw仅过滤空格default空格和非字母数字字符pretty空格和非字母数字字符但保留._~!$(),;ascii空格、非字母数字以及非 ASCII 字符latin同default但拉丁字符先被转写3.7.0如àèïòü→aeiou用法示例{{ The _config.yml file | slugify: pretty }}。用 where 检测 nil 与空值4.0where过滤器可用来筛出属性为nil或的文档/页面{% raw %} {% assign filtered_posts site.posts | where: my_prop, nil %} {% endraw %}上面的写法会选出未定义my_prop或将其显式设为nil的帖子。若想选出属性为空值的帖子则使用 Liquid 特殊字面量empty或blank{% raw %} {% assign filtered_posts site.posts | where: my_prop, empty %} {% endraw %}其底层比较逻辑在 lib/jekyll/filters.rb 的compare_property_vs_target中当目标值是Liquid::Expression::MethodLiteral即empty/blank时会比较属性值或其数组拼接结果是否等于该字面量字符串。where_exp 的二元运算符4.0where_exp的表达式支持 Liquid 二元运算符and/or从而在一次操作中使用多个条件{% raw %} {{ site.movies | where_exp: item, item.genre horror and item.language English }} {% endraw %}{% raw %} {{ site.movies | where_exp: item, item.sub_genre MCU or item.sub_genre DCEU }} {% endraw %}源码中 lib/jekyll/filters.rb 的parse_binary_comparison会循环解析and/or并构建出Liquid::Condition链最终在上下文栈内对每个元素求值。四、Jekyll 内置标签Tags标准 Liquid 的标签控制流if/unless/case、循环for/cycle等全部可用。Jekyll 另有几个内置标签用于构建站点你也可以用 插件 创建自己的标签。4.1 Includes复用页面片段如果你有在站点中反复使用的页面片段include 是把它们抽出来维护的最佳方式{% raw %} {% include footer.html %} {% include sidebar.html paramvalue %} {% endraw %}4.2 代码片段高亮highlightJekyll 内置了对 100 种语言的语法高亮支持这得益于 Rouge 中的highlighter rouge。⚠️Pygments 已废弃Jekyll 4 不支持 Pygments。配置项highlighter: pygments现在会自动回退使用 Rouge——Rouge 用 Ruby 编写且 100% 兼容 Pygments 的样式表。基本用法{% raw %} {% highlight ruby %} def foo puts foo end {% endhighlight %} {% endraw %}highlight标签的第一个参数上例中的ruby是语言标识符。要查找适合你语言的“short name”可查阅 Rouge 支持的语言与词法分析器列表。其参数语法由 lib/jekyll/tags/highlight.rb 的正则定义highlight lang [linenos] [mark_lines3 4 5]解析失败会抛出带合法语法的明确报错。行号linenos可选的第二个参数强制输出带行号的代码块{% raw %} {% highlight ruby linenos %} def foo puts foo end {% endhighlight %} {% endraw %}标记特定行4.4.0可选参数mark_lines接收用双引号包裹、空格分隔的行号列表。下面的代码块会标记第 1、2 行而不标记第 3 行{% raw %} {% highlight ruby mark_lines1 2 %} def foo puts foo end {% endhighlight %} {% endraw %}被标记的行默认应用类名hll。源码 lib/jekyll/tags/highlight.rb 显示mark_lines通过Rouge::Formatters::HTMLLineHighlighter实现linenos则通过Rouge::Formatters::HTMLTable渲染为带 gutter 的表格结构。高亮样式表要让高亮真正显示出来需要引入一份高亮样式表。Pygments 或 Rouge 均可使用 Pygments 风格的样式表例如native.css把它复制到你的 css 目录然后在main.css中引入import native.css;注意Jekyll 会处理代码块中的所有 Liquid 过滤器。如果高亮的语言本身包含花括号很可能需要在代码外围加上{% raw %}与{% endraw %}。自 Jekyll 4.0 起也可以在某篇文档的 front matter 中设置render_with_liquid: false来完全禁用该文档的 Liquid 处理。4.3 链接标签link 与 post_url自 Jekyll 4.0 起link与post_url标签不再需要在前面拼上site.baseurl。link 标签为指定的文章、页面、集合项或文件生成正确的 permalink URL。即使你后续修改了 permalink 风格是否带扩展名link生成的 URL 始终有效。使用link时必须带上文件原始扩展名{% raw %} {% link _collection/name-of-document.md %} {% link _posts/2016-07-26-name-of-post.md %} {% link news/index.html %} {% link /assets/files/doc.pdf %} {% endraw %}也可以把link用在 Markdown 链接中{% raw %} Link to a document Link to a post Link to a page Link to a file {% endraw %}路径规则路径是**相对站点根目录配置文件所在目录**的而不是从当前页面到目标页面的相对路径。例如page_a.md位于pages/folder1/folder2要链接到page_b.md位于pages/folder1应写/pages/folder1/page_b.md而不是../page_b.html。如果不确定路径可以在页面中输出{{ page.path }}查看。链接校验重要收益使用link或post_url的一大好处是链接验证——如果目标不存在Jekyll 将拒绝构建站点。从 lib/jekyll/tags/link.rb 可见link标签会在渲染时遍历site.each_site_file匹配relative_path找不到就抛出ArgumentError从而在构建阶段就暴露死链而不是带着死链上线。变量作为文件名link的文件名可以来自变量。例如在 front matter 定义--- title: My page my_variable: footer_company_a.html ---然后引用{% raw %} {% link {{ page.my_variable }} %} {% endraw %}限制link标签不能加过滤器例如{% link mypage.html | append: #section1 %}是不合法的。要链接到页面内的锚点请使用常规 HTML 或 Markdown 链接写法。post_url 标签生成指向站点内某篇文章的正确 permalink URL{% raw %} {% post_url 2010-07-21-name-of-post %} {% endraw %}如果文章放在子目录中需要带上子目录路径{% raw %} {% post_url /subdir/2010-07-21-name-of-post %} {% endraw %}使用post_url时不需要包含文件扩展名。Markdown 链接写法{% raw %} Name of Link {% endraw %}配合数据文件假设你用 数据文件_data/cool_posts.yaml跟踪一批要展示为“精选文章”的帖子- title: An Awesome Post slug: 2010-07-21-name-of-post - title: Another Awesome Post slug: 2016-07-26-name-of-post自 Jekyll 4.5.0 起可以这样循环输出post_url内部会先渲染{{ }}表达式再解析文章名见 lib/jekyll/tags/post_url.rb{% raw %} Cool posts: {%- for cool_post in site.data.cool_posts %} - {{ cool_post.title }} {%- endfor %} {% endraw %}post_url的匹配逻辑lib/jekyll/tags/post_url.rb通过POST_PATH_MATCHER正则解析文章名中的日期与 slug再与站点文章逐一比对找不到文章时会抛出PostURLError并中止构建。五、渲染管线与缓存源码视角理解 Jekyll 的 Liquid 处理流程有助于排查模板性能与缓存问题初始化LiquidRenderer读取liquid.error_mode并写入 Liquid 全局配置lib/jekyll/liquid_renderer.rb。解析每个模板文件通过LiquidRenderer::File#parse调用Liquid::Template.parse(content, :line_numbers true)解析结果按文件名缓存在LiquidRenderer#cache中lib/jekyll/liquid_renderer/file.rb。渲染render在渲染前会清空模板的instance_assigns避免缓存复用导致变量串扰lib/jekyll/liquid_renderer/file.rbrender!则直接抛出任何错误。统计渲染过程按文件累计次数、字节数与时耗可通过--profile或相关调试手段输出统计表stats_table。对文章、页面、集合等对象Jekyll 通过 Drops见 lib/jekyll/drops/ 下的document_drop.rb、site_drop.rb等把内部对象暴露给 Liquid 模板这也是模板中{{ site.posts }}、{{ page.title }}等变量的数据来源。六、实践建议与常见问题开发期开启严格模式在开发环境把error_mode设为strict并开启strict_variables/strict_filters能提前捕获变量拼写错误和不存在的过滤器发布前再切换回默认warn或lax。善用链接校验把站内链接全部改写成link/post_url标签Jekyll 构建时即可自动发现死链。代码块含花括号模板语言如 Go、Mustache、Liquid 示例本身放进highlight前先包上{% raw %}/{% endraw %}单文档场景可直接在 front matter 声明render_with_liquid: false。link标签不可加过滤器需要锚点时改用普通 Markdown/HTML 链接。where的值限制目标值不要传数组或 Hash也不要依赖#to_s的隐式转换结果。参考资源仓库内Liquid 总览文档Filters 文档 与 内置过滤器数据Tags 文档Liquid 配置文档 与 默认配置过滤器实现highlight 标签实现link 标签实现post_url 标签实现Liquid 渲染器实现 与 渲染器文件级实现【免费下载链接】jekyll:globe_with_meridians: Jekyll is a blog-aware static site generator in Ruby项目地址: https://gitcode.com/gh_mirrors/je/jekyll创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考