Jekyll 在不久之前發(fā)布了 3.0恳邀,讀完整個(gè) release notes后,我并未發(fā)現(xiàn)任何潛在的風(fēng)險(xiǎn)灶轰,于是我果斷跑到我的服務(wù)器上(沒(méi)錯(cuò)谣沸,我自己托管了 Jekyll 服務(wù)而不是使用 GitHub Page,為了逼格笋颤,為了 https)升級(jí)了 Jekyll乳附。
接著慘絕人寰的悲劇發(fā)生了
升級(jí)后,我訪問(wèn)了我的博客椰弊,首頁(yè)一切完美如初许溅。然后我試著打開某篇我自認(rèn)為寫的還不錯(cuò)的文章,拉到頁(yè)面底端秉版,打算再次回味一下粉絲們的評(píng)論贤重。wat,怎么評(píng)論都沒(méi)了G寤馈2⒒取!辛辛苦苦寫軟文騙來(lái)的粉絲和眼球秸妥,就這么消失了9鐾!!粥惧!
我第一時(shí)間看了下瀏覽器地址欄键畴,holly f**k,我的精心設(shè)計(jì)的大小寫交錯(cuò)的 url 已經(jīng)全部變成了小寫突雪。我迅速滾回了2.5.3起惕,坐和放寬了一會(huì)會(huì)兒,小站又恢復(fù)了平靜咏删。
變成小寫究竟意味著什么
首先惹想,即使你不是處女座,你的內(nèi)心也會(huì)因?yàn)檫@樣一個(gè)不小的變化感到內(nèi)心煎熬督函,不是嗎嘀粱?為什么要改變我的 url 呢。
然后是正經(jīng)的辰狡,我們?cè)?jīng)發(fā)布的博客的 url锋叨,已經(jīng)出現(xiàn)在各種 RSS、Twitter宛篇、Google 的索引等等之中悲柱,一旦 url 發(fā)生改變,之前的所有鏈接都失效了些己。我不確定谷歌的索引是否大小寫敏感豌鸡,但是我確定是嘿般,feedly 中我的文章的性感度(hot!)已經(jīng)被清零了涯冠,twitter上 ifttt 自動(dòng)發(fā)布的更新消息也無(wú)法成功的打開炉奴。
也就是說(shuō),這是一個(gè) breaking change蛇更,然而這并沒(méi)有出現(xiàn)在 Jekyll 3.0 的 release notes 中瞻赶。
那個(gè)第五分鐘出現(xiàn)的紅裙子小妹妹就是兇手!
為了找出問(wèn)題的真兇派任,我立刻到 GitHub 上查看 Jekyll 的源碼砸逊。經(jīng)過(guò)一段時(shí)間的比對(duì),root cause 出現(xiàn)了掌逛。在 2.x 中师逸,Jekyll 使用 post.rb
來(lái)處理文章,同時(shí)存在一個(gè) document.rb
來(lái)應(yīng)對(duì)別的類型的文件豆混。下面摘錄一小段代碼
#post.rb
:title => slug,
def process(name)
m, cats, date, slug, ext = *name.match(MATCHER)
self.date = Utils.parse_date(date, "Post '#{relative_path}' does not have a valid date in the filename.")
self.slug = slug
self.ext = ext
end
#document.rb
title: Utils.slugify(data['slug']) || Utils.slugify(basename_without_ext)
簡(jiǎn)單來(lái)說(shuō)篓像,post 中的 title,就是你文件中的名字皿伺,比如2015-11-16-IAmAwesome.md
的 title 就是 IAmAwesome
员辩。但是在 document.rb
中,Jekyll 額外進(jìn)行了一步處理 Utils.slugify
鸵鸥,我們看看這個(gè)函數(shù)會(huì)做什么:
SLUGIFY_RAW_REGEXP = Regexp.new('\\s+').freeze
SLUGIFY_DEFAULT_REGEXP = Regexp.new('[^[:alnum:]]+').freeze
SLUGIFY_PRETTY_REGEXP = Regexp.new("[^[:alnum:]._~!$&'()+,;=@]+").freeze
def slugify(string, mode=nil)
mode ||= 'default'
return nil if string.nil?
return string.downcase unless SLUGIFY_MODES.include?(mode)
# Replace each character sequence with a hyphen
re = case mode
when 'raw'
SLUGIFY_RAW_REGEXP
when 'default'
SLUGIFY_DEFAULT_REGEXP
when 'pretty'
# "._~!$&'()+,;=@" is human readable (not URI-escaped) in URL
# and is allowed in both extN and NTFS.
SLUGIFY_PRETTY_REGEXP
end
string.
# Strip according to the mode
gsub(re, '-').
# Remove leading/trailing hyphen
gsub(/^\-|\-$/i, '').
# Downcase
downcase
end
Jekyll 把它認(rèn)為不正常的字符都替換成-
奠滑,并且把字符都換成小寫的。
為了修復(fù)我博客的小問(wèn)題妒穴,我立刻發(fā)了個(gè) Pull request养叛,然而這個(gè) pr 是有私心的,我當(dāng)時(shí)只考慮了大小寫的問(wèn)題宰翅。后來(lái)有哥們表示他寫在文件名里的_
都被換成了-
,不開心爽室。
可以想見汁讼,以后會(huì)不斷有人跑過(guò)來(lái)說(shuō),把我的什么什么符號(hào)還給我...
終極解決方案
我的 pr 之后只會(huì)保留大小寫和-
阔墩、_
嘿架,其他的符號(hào)依然會(huì)被替換掉,這不是一個(gè)一勞永逸的修復(fù)啸箫。再加上 Jekyll 目測(cè)進(jìn)入了 maintain mode耸彪,feature change 和 bug fix 現(xiàn)在都需要多人 review 才能進(jìn)入主分支。我的 pr 寫了兩周了忘苛,一個(gè) maintainer 表示可以 merge蝉娜,但要等別人再 review唱较。結(jié)果我這一等就是兩周,這期間我給 Jekyll 提了四個(gè) issue召川,三個(gè) pr南缓,通通 pending。所以荧呐,要想等 Jekyll 發(fā)布新的版本汉形,可能不是一個(gè)明智的做法。
為此倍阐,我寫了一個(gè)插件概疆,叫做 jekyll-post-unslugify,大家可以參考文檔進(jìn)行安裝峰搪,安裝配置完畢后岔冀,你的文章的 title 就會(huì)像 Jekyll 2.x 里面一樣隨心所欲。只有 title 回到了過(guò)去罢艾,你依然可以享受 Jekyll 3.0 的新功能楣颠。
最后,May the title be with you.