资讯动态

Jekyll 3.4.0 版本解析:`group_by_exp` 分组过滤器与 Windows 时区管理的实战指南

发布时间:2026/9/19 22:56:47 来源:尧图企业网站定制
Jekyll 3.4.0 版本解析group_by_exp分组过滤器与 Windows 时区管理的实战指南【免费下载链接】jekyll:globe_with_meridians: Jekyll is a blog-aware static site generator in Ruby项目地址: https://gitcode.com/gh_mirrors/je/jekyllJekyll 3.4.0 是 2017 年 1 月发布的一个以修复为主、同时带来三项关键变化的版本新增按表达式分组的内置 Liquid 过滤器group_by_exp、在 Windows 平台上实现对 IANA 时区代码的准确支持以及一批主题、includes、permalinks 相关文档的改进。本文以官方发布公告为骨架结合当前仓库中的过滤器实现、配置解析与测试用例源码完整讲解这两项核心能力的用法、底层原理与注意事项帮助你升级到 3.4.0 后立刻上手。一、版本定位一次小而精的更新Jekyll 3.4.0发布公告见 docs/_posts/2017-01-18-jekyll-3-4-0-released.markdown延续了 3.x 系列「bug fixes 增量特性」的节奏。公告将本次更新概括为三点新增group_by_exp过滤器与已有的where_by_exp形成「筛选 / 分组」两套表达式驱动的组合拳Windows 用户可以使用 IANA 时区代码如Asia/Shanghai在_config.yml中准确设置timezone官方文档围绕 themes、includes、permalinks 进行了改进并同步补充了历史变更记录。其余大量工作是社区贡献的常规 bug 修复。升级方式与平常一致gem update jekyll或修改Gemfile中的版本约束后bundle update jekyll。二、核心新特性group_by_exp表达式分组过滤器1. 与group_by/where_by_exp的关系在 Jekyll 中group_by过滤器负责「按某个属性值分组」而where_by_exp负责「按表达式筛选」。3.4.0 新增的group_by_exp则是「按 Liquid 表达式的结果分组」它把group_by的分组能力和where_by_exp的表达式灵活性结合到了一起。三者的分工可以这样理解过滤器能力典型场景where/where_exp按属性或表达式筛选数组返回子集只保留某类文章group_by按属性值分组按标签、年份归类group_by_exp3.4.0 新增按表达式计算结果分组按年份截断后的值、大写后的值等派生值归类2. 基本用法与官方示例group_by_exp的签名是三个参数输入数组、循环变量名、表达式字符串。{{ site.members | group_by_exp: item, item.graduation_year | truncate: 3, }}这段示例来自官方过滤器文档数据 docs/_data/jekyll_filters.yml对site.members中每个成员的graduation_year先做truncate: 3, 截取前 3 位且不追加省略号再按截取结果分组例如把2013、2014归入201把2009归入200。输出是形如{name201, items[...]}的分组数组每组都带有name、items和size三个键。对照源码 lib/jekyll/filters/grouping_filters.rb 可以看到实现逻辑def group_by_exp(input, variable, expression) return input unless groupable?(input) parsed_expr parse_expression(expression) context.stack do groups input.group_by do |item| context[variable] item parsed_expr.render(context) end grouped_array(groups) end end关键点在于表达式是运行时解析的parse_expression把传入的字符串封装成Liquid::Variable在遍历每个元素时把元素赋给循环变量并渲染表达式因此表达式可以任意复杂——调用过滤器、拼接字符串、比较日期都行支持任意可枚举对象groupable?只要求输入响应group_by数组、Hash 均可分组结果统一结构grouped_array将 Ruby 的Hash#group_by结果转换为{name ..., items [...], size ...}的数组方便模板中直接用group.name、group.items、group.size渲染。3. 对比group_by的异同group_by(input, property)的实现lib/jekyll/filters/grouping_filters.rb等价于把表达式固定为「读取某个属性」。测试用例 test/test_filters.rb 专门验证了这一点should be equivalent of group_by do actual filter.group_by_exp(filter.site.pages, page, page.layout) expected filter.group_by(filter.site.pages, layout) assert_equal expected, actual end也就是说group_by_exp: item, item.layout与group_by: layout结果完全一致前者只是更通用的超集。4. 更多实战示例按表达式派生值分组例如按版本号主版本归类{% assign groups site.data.versions | group_by_exp: item, item.version | split: . | first %}该用法在 test/test_filters.rb 中有对应的测试数据与断言。直接按整个元素分组表达式为变量本身{{ a,b,c,d | split: , | group_by_exp: item, item }}测试 test/test_filters.rb 验证了这种写法按元素本身分组每个元素自成一组。配合数组与 Hash 输入均可工作对非数组输入如字符串则原样返回测试 test/test_filters.rb 确认了这一兜底行为。5. 与where_by_exp的组合应用where_by_exp负责按表达式筛选group_by_exp负责按表达式分组二者可串联使用。例如先筛选出未归档的文章再按「文章标题首字母大写后的年份」分组{% assign active site.posts | where_exp: post, post.published true %} {% assign groups active | group_by_exp: post, post.title | truncate: 4, %}在 3.4.0 时代where_exp的表达式支持已相当完整后续版本4.0进一步加入了and/or二元运算符支持见 docs/_docs/liquid/filters.md但分组能力从 3.4.0 起就已具备group_by_exp这一通用形态。三、Windows 时区管理IANA 时区代码的准确支持1. 背景Windows 上时区为何一直是痛点Windows 没有原生 zoneinfo 数据Ruby 解释器无法理解 IANA 时区名如Asia/Shanghai。此前在 Windows 上使用自定义时区TZ环境变量会退化为 UTC/GMT 00:00虽然也可以用 POSIX 格式如EST5手动定义但处理夏令时DST规则变化时既不直观也不可靠。3.4.0 的解决方案是借助tzinfogem 按 IANA 时区数据库计算偏移量并在内部换算成 Windows 可识别的 POSIX 风格定义。2. 配置方式在_config.yml中照常设置timezone该键的默认值为nil表示使用本地时区见 lib/jekyll/configuration.rbtimezone: Asia/ShanghaiWindows 用户需要确保Gemfile中包含tzinfo与tzinfo-data。3.4.0 起新建的站点会在Gemfile中默认写入以下内容见 docs/_docs/installation/windows.md老站点需要手动补充# Windows and JRuby does not include zoneinfo files, so bundle the tzinfo-data gem # and associated library. platforms :mingw, :x64_mingw, :mswin, :jruby do gem tzinfo, 1, 3 gem tzinfo-data end注意platforms声明只在 Windows及 JRuby环境下才安装这些 gem不影响 Linux/macOS 的依赖树。3. 底层实现原理核心逻辑位于 lib/jekyll/utils/win_tz.rb 的WinTZ.calculate方法def calculate(timezone, now Time.now) External.require_with_graceful_fail(tzinfo) unless defined?(TZInfo) tz TZInfo::Timezone.get(timezone) offset tz.period_for_utc(now.getutc).utc_total_offset # POSIX style definition reverses the offset sign. sign offset.positive? ? - : ... WTZ#{sign}#{time} end关键步骤通过TZInfo::Timezone.get(timezone)加载 IANA 时区定义用period_for_utc与utc_total_offset获取当前时刻相对 UTC 的总偏移含 DST 调整注意源码注释说明这是为了兼容 tzinfo v1POSIX 时区符号约定与直觉相反西半球时区如美国东部 ESTUTC-5表示为EST5因此代码在偏移为正时输出-、偏移为负时输出支持非整小时偏移例如Australia/EuclaUTC8:45换算为WTZ-08:45返回的WTZ...字符串最终用于重新定义ENV[TZ]使 Jekyll 在 Windows 上按真实时区处理文章日期。测试 test/test_win_tz.rb 系统验证了这一点IANA 时区冬季1 月夏季7 月America/New_YorkWTZ05:00WTZ04:00DST 生效Europe/ParisWTZ-01:00WTZ-02:00DST 生效Australia/EuclaWTZ-08:45—UTCWTZ00:00—可以看到 DST 被正确计入纽约冬季 UTC-5、夏季 UTC-4巴黎冬季 UTC1、夏季 UTC2。4. 适用前提与限制该能力面向Windows 与 JRuby 平台Linux/macOS 自带 zoneinfo无需此机制必须安装tzinfo且tzinfo-data提供时区数据库否则会通过require_with_graceful_fail优雅降级并给出提示timezone配置值必须是 IANA 数据库中的合法代码如Asia/Shanghai、America/New_York。四、3.4.0 配套文档更新与升级建议公告同时提到文档在 themes、includes、permalinks 方面得到改进。本仓库的对应文档包括过滤器参考docs/_docs/liquid/filters.mdgroup_by_exp从 3.4.0 起在 docs/_data/jekyll_filters.yml 中带版本徽标展示Windows 安装与时区管理docs/_docs/installation/windows.md完整变更历史可查阅仓库 History.markdown 中 v3.4.0 一节。升级到 3.4.0 的建议顺序更新Gemfile版本约束并执行bundle update jekyllWindows 用户检查并补齐tzinfo/tzinfo-data依赖在_config.yml中确认timezone使用 IANA 代码将手写循环分组的模板改为group_by_exp简化维护。五、小结Jekyll 3.4.0 用两个精准的特性解决了实际问题group_by_exp让模板作者可以用任意 Liquid 表达式分组数据源码 lib/jekyll/filters/grouping_filters.rb 与测试 test/test_filters.rb 提供了完整的实现与验证而 Windows 时区支持让跨平台站点的日期显示不再漂移源码 lib/jekyll/utils/win_tz.rb 与测试 test/test_win_tz.rb 覆盖了含 DST 与奇数偏移量的全部情形。对升级用户而言这两项能力立即可用也是 3.x 系列在模板表达能力与平台健壮性上继续演进的重要一步。【免费下载链接】jekyll:globe_with_meridians: Jekyll is a blog-aware static site generator in Ruby项目地址: https://gitcode.com/gh_mirrors/je/jekyll创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价