管理的實戰(zhàn)指南)
Jekyll 3.4.0 版本解析group_by_exp分組過濾器與 Windows 時區(qū)管理的實戰(zhàn)指南【免費下載鏈接】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 月發(fā)布的一個以修復(fù)為主、同時帶來三項關(guān)鍵變化的版本新增按表達式分組的內(nèi)置 Liquid 過濾器group_by_exp、在 Windows 平臺上實現(xiàn)對 IANA 時區(qū)代碼的準確支持以及一批主題、includes、permalinks 相關(guān)文檔的改進。本文以官方發(fā)布公告為骨架結(jié)合當前倉庫中的過濾器實現(xiàn)、配置解析與測試用例源碼完整講解這兩項核心能力的用法、底層原理與注意事項幫助你升級到 3.4.0 后立刻上手。一、版本定位一次小而精的更新Jekyll 3.4.0發(fā)布公告見 docs/_posts/2017-01-18-jekyll-3-4-0-released.markdown延續(xù)了 3.x 系列「bug fixes 增量特性」的節(jié)奏。公告將本次更新概括為三點新增group_by_exp過濾器與已有的where_by_exp形成「篩選 / 分組」兩套表達式驅(qū)動的組合拳Windows 用戶可以使用 IANA 時區(qū)代碼如Asia/Shanghai在_config.yml中準確設(shè)置timezone官方文檔圍繞 themes、includes、permalinks 進行了改進并同步補充了歷史變更記錄。其余大量工作是社區(qū)貢獻的常規(guī) bug 修復(fù)。升級方式與平常一致gem update jekyll或修改Gemfile中的版本約束后bundle update jekyll。二、核心新特性group_by_exp表達式分組過濾器1. 與group_by/where_by_exp的關(guān)系在 Jekyll 中g(shù)roup_by過濾器負責「按某個屬性值分組」而where_by_exp負責「按表達式篩選」。3.4.0 新增的group_by_exp則是「按 Liquid 表達式的結(jié)果分組」它把group_by的分組能力和where_by_exp的表達式靈活性結(jié)合到了一起。三者的分工可以這樣理解過濾器能力典型場景where/where_exp按屬性或表達式篩選數(shù)組返回子集只保留某類文章group_by按屬性值分組按標簽、年份歸類group_by_exp3.4.0 新增按表達式計算結(jié)果分組按年份截斷后的值、大寫后的值等派生值歸類2. 基本用法與官方示例group_by_exp的簽名是三個參數(shù)輸入數(shù)組、循環(huán)變量名、表達式字符串。{{ site.members | group_by_exp: item, item.graduation_year | truncate: 3, }}這段示例來自官方過濾器文檔數(shù)據(jù) docs/_data/jekyll_filters.yml對site.members中每個成員的graduation_year先做truncate: 3, 截取前 3 位且不追加省略號再按截取結(jié)果分組例如把2013、2014歸入201把2009歸入200。輸出是形如{name201, items[...]}的分組數(shù)組每組都帶有name、items和size三個鍵。對照源碼 lib/jekyll/filters/grouping_filters.rb 可以看到實現(xiàn)邏輯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關(guān)鍵點在于表達式是運行時解析的parse_expression把傳入的字符串封裝成Liquid::Variable在遍歷每個元素時把元素賦給循環(huán)變量并渲染表達式因此表達式可以任意復(fù)雜——調(diào)用過濾器、拼接字符串、比較日期都行支持任意可枚舉對象groupable?只要求輸入響應(yīng)group_by數(shù)組、Hash 均可分組結(jié)果統(tǒng)一結(jié)構(gòu)grouped_array將 Ruby 的Hash#group_by結(jié)果轉(zhuǎn)換為{name ..., items [...], size ...}的數(shù)組方便模板中直接用group.name、group.items、group.size渲染。3. 對比group_by的異同group_by(input, property)的實現(xiàn)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結(jié)果完全一致前者只是更通用的超集。4. 更多實戰(zhàn)示例按表達式派生值分組例如按版本號主版本歸類{% assign groups site.data.versions | group_by_exp: item, item.version | split: . | first %}該用法在 test/test_filters.rb 中有對應(yīng)的測試數(shù)據(jù)與斷言。直接按整個元素分組表達式為變量本身{{ a,b,c,d | split: , | group_by_exp: item, item }}測試 test/test_filters.rb 驗證了這種寫法按元素本身分組每個元素自成一組。配合數(shù)組與 Hash 輸入均可工作對非數(shù)組輸入如字符串則原樣返回測試 test/test_filters.rb 確認了這一兜底行為。5. 與where_by_exp的組合應(yīng)用where_by_exp負責按表達式篩選group_by_exp負責按表達式分組二者可串聯(lián)使用。例如先篩選出未歸檔的文章再按「文章標題首字母大寫后的年份」分組{% 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的表達式支持已相當完整后續(xù)版本4.0進一步加入了and/or二元運算符支持見 docs/_docs/liquid/filters.md但分組能力從 3.4.0 起就已具備group_by_exp這一通用形態(tài)。三、Windows 時區(qū)管理IANA 時區(qū)代碼的準確支持1. 背景Windows 上時區(qū)為何一直是痛點Windows 沒有原生 zoneinfo 數(shù)據(jù)Ruby 解釋器無法理解 IANA 時區(qū)名如Asia/Shanghai。此前在 Windows 上使用自定義時區(qū)TZ環(huán)境變量會退化為 UTC/GMT 00:00雖然也可以用 POSIX 格式如EST5手動定義但處理夏令時DST規(guī)則變化時既不直觀也不可靠。3.4.0 的解決方案是借助tzinfogem 按 IANA 時區(qū)數(shù)據(jù)庫計算偏移量并在內(nèi)部換算成 Windows 可識別的 POSIX 風格定義。2. 配置方式在_config.yml中照常設(shè)置timezone該鍵的默認值為nil表示使用本地時區(qū)見 lib/jekyll/configuration.rbtimezone: Asia/ShanghaiWindows 用戶需要確保Gemfile中包含tzinfo與tzinfo-data。3.4.0 起新建的站點會在Gemfile中默認寫入以下內(nèi)容見 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環(huán)境下才安裝這些 gem不影響 Linux/macOS 的依賴樹。3. 底層實現(xiàn)原理核心邏輯位于 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關(guān)鍵步驟通過TZInfo::Timezone.get(timezone)加載 IANA 時區(qū)定義用period_for_utc與utc_total_offset獲取當前時刻相對 UTC 的總偏移含 DST 調(diào)整注意源碼注釋說明這是為了兼容 tzinfo v1POSIX 時區(qū)符號約定與直覺相反西半球時區(qū)如美國東部 ESTUTC-5表示為EST5因此代碼在偏移為正時輸出-、偏移為負時輸出支持非整小時偏移例如Australia/EuclaUTC8:45換算為WTZ-08:45返回的WTZ...字符串最終用于重新定義ENV[TZ]使 Jekyll 在 Windows 上按真實時區(qū)處理文章日期。測試 test/test_win_tz.rb 系統(tǒng)驗證了這一點IANA 時區(qū)冬季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提供時區(qū)數(shù)據(jù)庫否則會通過require_with_graceful_fail優(yōu)雅降級并給出提示timezone配置值必須是 IANA 數(shù)據(jù)庫中的合法代碼如Asia/Shanghai、America/New_York。四、3.4.0 配套文檔更新與升級建議公告同時提到文檔在 themes、includes、permalinks 方面得到改進。本倉庫的對應(yīng)文檔包括過濾器參考docs/_docs/liquid/filters.mdgroup_by_exp從 3.4.0 起在 docs/_data/jekyll_filters.yml 中帶版本徽標展示W(wǎng)indows 安裝與時區(qū)管理docs/_docs/installation/windows.md完整變更歷史可查閱倉庫 History.markdown 中 v3.4.0 一節(jié)。升級到 3.4.0 的建議順序更新Gemfile版本約束并執(zhí)行bundle update jekyllWindows 用戶檢查并補齊tzinfo/tzinfo-data依賴在_config.yml中確認timezone使用 IANA 代碼將手寫循環(huán)分組的模板改為group_by_exp簡化維護。五、小結(jié)Jekyll 3.4.0 用兩個精準的特性解決了實際問題group_by_exp讓模板作者可以用任意 Liquid 表達式分組數(shù)據(jù)源碼 lib/jekyll/filters/grouping_filters.rb 與測試 test/test_filters.rb 提供了完整的實現(xiàn)與驗證而 Windows 時區(qū)支持讓跨平臺站點的日期顯示不再漂移源碼 lib/jekyll/utils/win_tz.rb 與測試 test/test_win_tz.rb 覆蓋了含 DST 與奇數(shù)偏移量的全部情形。對升級用戶而言這兩項能力立即可用也是 3.x 系列在模板表達能力與平臺健壯性上繼續(xù)演進的重要一步?!久赓M下載鏈接】jekyll:globe_with_meridians: Jekyll is a blog-aware static site generator in Ruby項目地址: https://gitcode.com/gh_mirrors/je/jekyll創(chuàng)作聲明:本文部分內(nèi)容由AI輔助生成(AIGC),僅供參考