NexT 主題升級折騰紀錄 (v7.8.0)
之前逛別人文章時,說到了 Next 主題平滑更新的好
卻因為我們修改源碼而導致各種不便
為了能夠自由的更新主題,也為了更好的部落格品質,開始了一段折騰之路 ...。
升級原由
當時我正在看該作者的其他 plugin 功能,偶然看到了這段 :
當時選擇 NexT 主題就是看中它的維護者多、用戶量大,基本一個月左右的時間就會有一個版本更新,直接跟著官方就可以用到最新的特性。
但由於我之前對 NexT 主題做了不少自定義修改,這也使得更新主題變得比較麻煩,沒有辦法通過 git pull 平滑更新,這也違背了我選擇 NexT 主題的初衷。
同時,現在可以通過數據文件(Data File)將配置與主題分離,同時也可以把自定義佈局、樣式放到數據文件中,不用再修改主題源碼,便於後續主題更新。
其實,我當初選擇 NexT 只是因為外觀主題我喜歡而已 XD
但有些細節仍然無法靠官方 config 去設定,這時就只能去改源碼。
正常的 NexT 更新,是 git pull
,然後就會發生各種 merge 錯誤(
merge 的時候每個在那邊看實在頭很痛,誰記得我那時候改了哪些東西。
文件分離真的是個好設計 (透過載入放在主題外部的文件,蓋掉某些內置設定)
於是開始更新報錯之路 ... 。
升級步驟
預設你的部落格資料夾叫做 hexo
。
原主題文件夾是 hexo/themes/next
我先寫我整個流程,有些可能是冤枉路或是你沒遇到的問題,那就可以跳過
所以請看完再決定流程。
git clone 最新版
git clone https://github.com/theme-next/hexo-theme-next themes/next-reloaded
- 請在部落格根目錄做
- clone 下來的資料夾叫做 next-reloaded,不會直接把你原本(next)的蓋掉。
更改 theme
將 hexo/_config.yml
內的 theme:
設置改掉。
1 | -theme: next |
這麼做的好處是舊資料可以先保留,確認新版本完全可以用
再將資料夾名稱 next-reloaded
改回 next
就好。
試試看能不能跑
hexo clean && hexo g
,然後享受報錯
- 如果你之前沒有對 NexT 資料夾內 config 以外的東西做更改,那應該沒差。
- 如果出 error,可以往下看有沒有相關的。
試做資料分離
我其實沒有直接去跑 hexo g
,因為我要延用我的 next config 我必須先搬舊設定。
於是這時候我要來做資料分離 (前面提到的,load 外置檔案)
- 參考 : NexT 文件: DATA-FILES
- 方式有 <Hexo 方式> 和 <NexT 方式>,就是寫 config 的位置不同。
我自己不太想全部擠在/_config.yml
裡面,所以選擇了 <NexT 方式>。 - 實際做起來流程 : 先建
/source/_data/next.yml
(結構 :hexo/source/_data/next.yml
)
然後直接把新 NexT repo 內的_config.yml
全部內容複製到next.yml
。
看一下next.yml
內,前面部分就會有個選項叫override
,改成true
- 方式有 <Hexo 方式> 和 <NexT 方式>,就是寫 config 的位置不同。
遇到 Cannot read property 'active' of undefined
我自己改完之後,想要 hexo clean && hexo g
卻出現Cannot read property 'active' of undefined
- 原因在於我以為我改了,結果我卻是拿舊版本的
_config.yml
的內容去改。- 這邊我踩了 Sublime 的一個大坑,有個 plugin 可以讓我做文件 Compare 而且可以編輯
結果按了儲存,卻其實沒有儲存 (有點難解釋),做了第三次以後才發現
所以那個next.yml
我就這樣來來回回做了四次,改到我選項都背起來了 ... - 結論 : 確認自己是拿最新的
_config.yml
去複製來改。
- 這邊我踩了 Sublime 的一個大坑,有個 plugin 可以讓我做文件 Compare 而且可以編輯
遇到 Unhandled rejection Template render error
改完再試試 hexo clean && hexo g
卻產生: Unhandled rejection Template render error
特點 : 常常會有不同 swig 編譯失敗 ...
有些說雙大括號
{{ }}
造成的問題,但我文章壓根沒動過,沒道理因為升級就變這樣。跳過。這種 render 失敗,有可能是你裝了一些 plugin
要靠放 custom.js 等等檔案才能用的,你卻沒放好導致他們無法正常運作
所以無法解析某些 tag,如下方
``{% some_function %}`花了很大一段時間,發現自己放錯地方 (我有裝個需要自己放 custom.js 的插件)
註 : 同類型 error :
TypeError: Cannot read property 'replace' of null
- replace 問題有可能是 tag 產生的問題或者是 config 沒完全。
- 我在建立新的測試用 blog 有遇到這個問題,後來整個 blog 又再刪掉重建一次就好了 ...
或是 : hexo 插件過舊,需要用 npm 更新。
npm 插件更新
在找上述問題的過程中,也把 npm 插件全更新了。
- 說實話我很不會用 npm。
npm install
打了好幾次就是不更新。 - 原來這和根目錄的
/package.json
有關,你要把想要的版本寫上去,他才會更新。
(或是寫 "latest" 也會直接幫你弄到最新。)
1 | // 舉例 |
- 這個步驟有個技巧,你可以用
npm outdated
檢查。- 更新的話可以裝
npm-check
這個程式,或是手動改/package.json
- 更新的話可以裝
過了這邊,其實該處理的都差不多了,剩下 :
- 你可能裝了一些 plugin 但是過舊,作者也沒推出更新。
- 以前有改過 NexT 主題的源碼,
如果有裝 hexo-tag-aplayer
後面 render 跑出了一些和 hexo-tag-aplayer
這個 plugin 有關的 error。
簡單來說,這是一個小型網頁音樂撥放器,我以前文章有用到。
這部份我也是繞了超久 ...
可能會遇到的問題 :
重複載入 Aplayer.js 資源腳本問題
hexo server
後,瀏覽器開 console 發現某某文件突然多了些奇怪的文字。<link rel="stylesheet" class="aplayer-secondary-style-marker" href="/assets/css/APlayer.min.css"><script src="/assets/js/APlayer.min.js" class="aplayer-secondary-script-marker"></script><script class="meting-secondary-script-marker" src="/assets/js/Meting.min.js"></script>
- 多了這段,除了懷疑
hexo-tag-aplayer
之外還有誰呢 ...。 - 相關症狀與討論 : issues#44
- 開發者的解釋 : Readme CN
解決 :
在 hexo config 那邊,如同 readme 所寫,新增 asset_inject 這個選項。
1
2
3aplayer:
+ asset_inject: false
// 記得前面是兩個空白再來我們必須自己引入 js 和 css 等檔案。
我原本在 hexo 3.x 版本 配上 next 7.1.1 版本 ,自動注入就能 work 了
現在升級了才發生這個問題,但是相對的,override 的功能也做得更完善。
以下方式是適用 "如果可以使用 override" 的場合 :建立
blog資料夾/source/_data/head.swig
_data
這個資料夾預設沒有,自己創。在
/source/_data/next.yml
內
搜尋head: source/_data/head.swig
將他取消註釋。
(註 : next.yml 這個配置在上方章節有提到)在
head.swig
內放入以下內容1
2
3
4
5<!-- require APlayer -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/aplayer/dist/APlayer.min.css">
<script src="https://cdn.jsdelivr.net/npm/aplayer/dist/APlayer.min.js"></script>
<!-- require MetingJS -->
<script src="https://cdn.jsdelivr.net/npm/meting@2.0.1/dist/Meting.min.js"></script>
如果你說,步驟 2 後面的東西都看不懂怎麼辦,或是不想搞/不能搞 Override 怎辦。
那也可以直接做 file inject,就是直接修改源碼
在 next 主題資料夾內,找 layout/_partials/head/head.swig
在最後面加入上面那份引入的區塊就可以了。
Unrecognized tag argument(3): loop:one at throwError
抱歉,這個問題我不知道怎麼解決。
其實我以前曾經去改過 hexo-tag-aplayer 的 plugin 源碼
但我也重新裝了,理論上也無關才是
後來看看,這個 repo 最後更新已經是兩年前了
故我決定去找找有沒有新的取代 plugin 可以用。
我找到了 hexo-tag-mmedia
。
hexo-tag-mmedia
這是一個也是基於 aplayer
做的插件,而且作者看起來有在更新的樣子
但是畢竟是個人做的,使用者也少,所以 bug 和功能還不算完善。
下面會提及我遇到的問題。
ReferenceError: value is not defined
hexo g
後產生這段。
直接上結論 : 我使用了 {% aplayerlrc %}
的這個 tag
但是作者說這部分功能還不完善,拿掉這個 tag 的播放器 code 就沒事了。
無法同個文章放置多個播放器
我自己有一篇文章放了兩首歌,用兩個播放器
但是不知道為何總是只出現一個
後來看了一下 render 後的 js,是用 getElementById
...
這樣當然會只渲染同個 DOM ...
順帶一提,外部 JS 庫也會被重複 loading。
回報後作者說下個版本改進。
width 失效
舉例 :{% aplayer "晴天と喪失" "RADWIMPS" "xxx.mp3" "width:30%" %}
然後 width 都會失效。
原因 : 源碼疏失
1 | Line 50 |
不過我不太想直接改,先等看看作者會不會修吧,issue 已提。
目前不支援 loop:none
說實話這是個很常用的功能,mutex 也是
但是作者預設的選項並沒有提供可以設定的地方
看作者會不會增加囉,或是哪天我太閒 clone 過來看 ...
語言界面
以前在 /_config.yml
是這樣寫的
1 | language: |
更新後就突然變成英文了。
原因應該是讀取參數的名稱改了
改成以下
1 | language: |
順利解決。
一些 CSS 調整
字體大小
- 升級後,部落格預設文字大小變成 1em,在我的環境差不多是 16px
這點我十分頭痛 ... 但 next.yml 理論上可以設定。
- 升級後,部落格預設文字大小變成 1em,在我的環境差不多是 16px
側邊欄 部落格簡介排版跑掉
- sidebar 上方會顯示部落格的 description,padding 也被調整過了。
如果因為字體跑掉而導致排版和以前不一樣,可以考慮調整以下
1 | /* 2020/05/20 sidebar description 在最新 next 變瘦了,是因為這邊 */ |
- 注意,要啟用
styles.styl
的話需要做幾件事情 :- 在
/source/_data/
裡面建立styles.styl
這個檔案
(跟next.yml
同個位置) - 在
next.yml
裡面,把custom_file_path
裡面的style: source/_data/styles.styl
取消註釋
- 在
- 如果不使用上述 data 分離方式,想直接改主題源碼
可以到/themes/next/source/css/_custom
放custom.styl
這個檔案
效果是一樣的。
取消文章貼齊頂端
- 在我以前部落格配置中,首頁文章是沒有貼齊頂端的
我不是很喜歡貼齊的那種感覺 ... 也可以說我已經習慣有距離的感覺了
但是把舊的 CSS 套用了之後,新版 NexT 卻還是一樣貼齊。
(主要是透過調整.post
的 margin 和 padding 來讓他不貼齊)
看了一下架構
1 | 以前首頁 : |
所以 #post
和 #content
已失效;
原本 .post
在 .post-block
外面,現在也直接省略 .post
。
解決方式 : 在 <div class="content index posts-expand" >
加個 .post
加入方式一樣有兩種
- 用 data 分離方式 :
- 在
/source/_data/
裡面建立body-end.swig
這個檔案
(跟next.yml
同個位置) - 在
next.yml
裡面,把custom_file_path
裡面的bodyEnd: source/_data/body-end.swig
取消註釋 - 在
body-end.swig
內寫以下 code- 使用
body-end.swig
來進行啟用不確定是不是最好的方法。
有更好的使用方式歡迎留言跟我說。
- 使用
- 在
1 | <script> |
- 透過改主題源碼方式 :
- 我沒實際做過,單純看看源碼推測,可以試試。
- 在
/themes/next/layout/index.swig
,修改其中一行- 只改
index.swig
的,因為點進去後的文章和以前的架構差不多,首頁改掉了而已
- 只改
1 | 我這邊是 Line 6 |
Fancybox 特定圖片不套用
以前看別人教學,就是在特定 js 裡面,阻止特定 class 渲染 :
1 | var $image = $(this); |
然後在你不想套用 fancybox 的圖片,加上 class="nofancybox"
就好。
... 可是 !
今天如果我想要在不動 NexT 源碼的情況呢 ?
我嘗試了在 body-end.swig
放一些 js code
(像是拿掉 fancybox class、或是拿掉 <a>
tag )
但是因為 fancybox js 渲染時機問題,總之無效。
其實之前一直沒嘗試所謂的 Hexo Data File 特性,只知道好像可以新增一些檔案
後來嘗試在 /source
裡面建立 /js/utils.js
看能不能覆蓋 ... 於是就成功了。
步驟大概是 :
- 在
/source
裡面建立js
資料夾 - 複製
/theme/next/source/js/src/utils.js
,貼過去/source/js
- 修改
/source/js/utils.js
1 | // v7.8.0 的跟以前有一點點不一樣 |
添加自己的頭像和背景圖片
以前總是自己手動丟到 /public/images
資料夾。
但是缺點是 : 每次 hexo clean
都會頭很痛,又要重放。
後來發現,有一部分圖片是從 next/source/images
當作來源
所以就把他放到該資料夾去了。
由於發現了 Hexo Data File 特性,於是
建立 /source/images
然後放入想要放的圖片,愉快解決。
近期文章區塊
參考: Hexo博客:九、添加近期文章板块 Hexo-NexT 版本更新记
針對 Hexo Data File 特性加上一點點個人化,我這樣做 :
next.yml
中添加1
2
3recent_posts_title: 近期文章
recent_posts_layout: block
recent_posts: true在
/source/_data/sidebar.swig
放以下 code
注 : 中間我是寫posts.slice('1', '5')
,因為我有置頂文章next.yml
中取消sidebar.swig
的註釋:1
2
3
4custom_file_path:
- #sidebar: source/_data/sidebar.swig
+ sidebar: source/_data/sidebar.swig
如何查看 Hexo 和 Next 的版本 ?
預設 config 設置中,底下會有 Powered by Hexo, Powered by Next 的文字。
這部分在更新之後,原本可以顯示版本的,但後來被簡化掉了。
看了一下,有在這份 PR 提及
簡化掉了,如果自己又想看怎麼辦 ?
(就像我當初想要升級卻不知道當前版本 ...)
以下提供簡單的方式 (要用 F12 看)
1 | Get Hexo version: <meta name="generator"> in <head> |
大概是這樣。