深藏若虛

從 Jekyll 遷移至 WordPress

From Jekyll to Wordpress

離上次發文轉眼又過了四個月,農曆新年也來到了。這段時間雖然沒發文,卻也是有在做部落格的更新,主軸就如標題所述,將部落格的系統從靜態網站產生器的 Jekyll 移至 WordPress。原因就如去年 12 月的 Facebook 貼文所述,主要是圖片管理不易。雖然 XDite 創辦的 Logdown 的確在這部分做得很好,但 Logdown 也如創辦人自己所述是疏於經營的,讓我對他的信心不高XD。Wake 推薦的方式挺有趣,但最近實在沒時間投入一個成熟度不高且又要多項服務自己整合的方式 Orz。所以決定還是回到以前碰過 WordPress 作為部落格的基底。

對於部落格系統、服務使用歷程大概是:

  1. Pixnet
  2. Blogger
  3. WordPress + VPS
  4. Octpress + Github
  5. Jekyll + Github
  6. WordPress + Docker on VPS

繞了一圈,還是回到 WordPress,這個結果也是挺讓人啼笑皆非的。不過這些年來 WordPress 的確是也變滿多的,介面上、客製化、外掛數量等。而且有了 Docker 後,在架設與部署上對環境的規劃時間也減少了,耗費了一段時間去重新投入這塊,本篇主要就是在講述從 Jekyll 遷移到 WordPress 的歷程,包括了主題客製化(Theme Customize)的開發、漢字標準格式的整合、外掛(Plugin)、環境部署與架設幾個部分。

目錄
  1. WordPress 的改變
  2. 主題客製化
  3. 漢字標準格式
  4. 外掛(Plugin)
    1. Jetpack 由 WordPress.com 團隊開發
    2. Crayon Syntax Highlighter
    3. UpdraftPlus – Backup/Restore
  5. 環境部署與架設
  6. 結語

WordPress 的改變

這裡的改變不是指 WordPress 近年改變的觀察,畢竟是我沒有一直關注這個社群,而是指自己很久以前接觸 WordPress 到現在重新接觸後,感受變化特別多的部分。但其實我也久沒使用 WordPress 了,有種我是在使用一個新的 CMS 的感覺XD。也聽說最近幾年 WordPress 已從一個 Blog System 演化成一個成熟的 CMS 了呢。

最直觀的改變大概就是管理後台的介面吧。會想從靜態網站產生器換到 WordPress 無非就是希望管理上能更加簡易、直觀和自動,有一個簡潔、美觀的後台的確是挺對我的胃口的。值得一提的是 WordPress 的後台也有支援 RWD 的瀏覽,或許之後可以用平板做簡單的管理。

Wordpress 後台

另一個比較友善的部分,系統、外掛與主題若有更新,後台都會提醒你,讓你手動去更新。說是手動,事實上也就是一鍵更新,不用其他的操作XD,雖然很多人都說 WordPress 可能資安漏洞比較多,但是有發現的漏洞官方應該都會迅速更新補上,並提醒使用者可更新,我覺得至少減輕了在資安上的不少疑慮。當然,若要和靜態網站產生器的部落格比起來,是不可能沒有漏洞的,這部分就看個人的平衡點和抉擇了。

在 WordPress 進階功能的補足上,官方也有推出一個外掛叫做 Jetpack,一次幫你補充滿多後台的功能。在寫作與閱讀上,比較讓我注重的就是有提供 Markdown 語法的支援(對,就算換到 WordPress 我還是離不開 Markdown。 XD),以及能使用 Latex 語法去加入較美觀的數學式,再來就是也有提供許多媒體或社交網站的 Shortcode Embeds,讓內嵌 Facebook 的發文、Instgram 的照片、Youtube 的影片、SlideShare 的簡報更加的方便。這些寫作上的方便性也算是拉近了 WordPress 與 Logdown 的差異,也算是我願意回到 WordPress 的原因之一。

比較可惜的是,儘管在寫作上多了不少進階功能,甚至提供了 Markdown 語法,但在程式設計師最關注的程式碼上色仍沒有實作。1雖然能理解這不是一般使用者的必備需求,但是多少還是有點遺憾。不過還好在 WordPress 社群中已經有不少程式碼上色的外掛創作,我會在後面的章節提到我是如何實作這個需求。

主題客製化(Theme Customize)

一開始要投入這塊時,在網路上一直找不到一個有系統的整裡,直接去去看官網的文件,也比較偏向工具書,沒辦法以比較快速的途徑帶過整體概念。所幸後來找到了 FunDesigner 提供的 免費 WORDPRESS 佈景主題開發指南電子書,讓我得以把整體概念暸解一遍,再透過官方的文件做比較細節的暸解,總算將在 Jekyll 已經有基礎的前端設計移植過來了。

早在使用 Jekyll 時,我已經針對自己偏好的風格去做部落格主題的實作,要移植過來主要就是將 Jekyll 的語法轉換成 WordPress 提供的 PHP 函式。這部分如上述,透過該電子書以及官方文件一一完成移植了。

不過因為原本的設計仍有許多地方要加強,尤其是後面 Sass 的程式碼凌亂不堪,所以也順勢重新整理,並加上原本缺乏的 RWD,開始做比較細節的改動,讓部落格在手機、平板、電腦上都能有比較良好的瀏覽體驗。

我將這個主題命名為 Modest,即為謙虛的意思,與部落格名稱相呼應,希望讓讀者感受的風格是比較平淡無華,但在內容瀏覽上是舒適的。

這部分唯一遇到的問題大概就是由於我不是公開的主題,每次有修改後都要重新上傳,導致一些主題的客製化欄位資料遺失。後來改用 Docekr 將這部分的程式 Volume 到伺服器上,再透過 Git 去做更新,就算是改善了這個問題,這部分的實作我也會後面提到。

漢字標準格式

既然是一個注重內容以及其瀏覽舒適度為訴求的主題,那對於字體、字型、排版等都會有比較注重的調整,在這部分我使用了漢字標準格式這套前端框架,幫我處理漢字瀏覽上的一些細節調整,包括字型、縮進、強調等,去取代西方的一些不適用在漢字瀏覽的慣例。細節可以到官方使用手冊瀏覽。

比較有趣的是該框架還有提供高級排版功能,我啟用了章節的編排這個功能,讓框架自動幫我在標題加上計數,以方便讀者瞭解文章的結構。

不過有一個比較令我猶豫的地方在於該框架對於標點符號樣式的修正。該框架對於句點逗號頓號採用的字型是使其偏下,而不是台灣教育部規定的居中,這讓我挺不習慣的。所以在這裡我試圖尋找一些歷史沿革以及實際上的比較。

我在中國的知乎網站上找的一篇名為〈中国的文言文为什么没有标点符号?〉的討論串,裡面最高評分的解答去搜集了許多古籍資料做考證,讓我了解到在古文中標點符號的形式與沿革。不過重點是在於幾乎所有的句讀都是偏右的形式做排版(古文多以直書做書寫排版),換成現代網頁排版形式,也就是偏下。

之後我又透過變數設定分別使用同一篇文章去比較這兩種排版在閱讀上的感受差異,如下圖:

雖然還是覺得比較習慣居中的排版方式,但是撇除習慣,偏下的排版方式,在閱讀上能將句子斷的更明顯,閱讀上更加容易,所以最後還是決定採用偏下的排版方式。不過倒也想知道讀者的感覺,你們覺得是採居中的方式比較好閱讀呢?還是偏下呢?若可以,透過留言讓我知道吧。

外掛(Plugin)

因為才剛從 Jekyll 移植過來,所以安裝的外掛到不會太多,畢竟原本的環境就偏向簡單,所以也不太會有額外的需求,另一方面也是讓部落格的系統盡量簡化。會安裝外掛的主要就是針對三大需求:Markdown 語法支援、程式碼上色、部落個資料備份。所以我也就只安裝三個外掛,在這邊我會針對這三個外掛做些簡介。

Jetpack 由 WordPress.com 團隊開發

這個外掛在前面已經有約略提過了,在目前 3.9.1 的版本裡提供了 37 項服務,多數服務都挺實用的,尤其是 Markdown 語法的支援還算完整(可惜沒有辦法自行擴充或調整)。當然,除了前面提過的在寫作上的支援外,也有針對安全性去封鎖惡意 IP 的服務、監聽網站是否離線的服務、減輕主機負擔的圖片快取服務等等,有興趣的可以自行安裝該外掛去查看。

另外他也有簡單的網誌統計功能,讓你簡單直觀了解訪客流量的統計,這一方面也算是解決了我一項使用 Jekyll 的苦惱,讓我不用每次想看訪客資料都要到 Google Analysis,而可以先透過這邊的統計去了解。有想要比較深入的報表再去閱讀 Google Analysis 的資料即可。

Crayon Syntax Highlighter

2016-09-22: 本站已改用 highlight.js 作為著色工具,可以參照 用 highlight.js 作為 wordpress 程式碼著色的程式

身為一個程式設計師,怎麼可以忍受部落格的程式碼沒有上色呢?不能嘛!XD

於是我在 WordPress 的外掛以Syntax Highlight為關鍵字去尋找,最後選定了目前活躍安裝度最高的 Crayon Syntax Highlighter。這款外掛的優點是彈性選項多,你可以針對目前的需求去做功能的勾選,另外他也能針對程式碼上色去選擇你喜歡的風格,甚至基於該風格再另外做客製化修正。而最重要的語言支援度上,它支援了 63 種語言,其中包括我常用的 C#, CSS, Java, JavaScript, PHP, Python, Ruby, Sass, Shell, YAML 等,最近比較出名的 Go, Swift 也有納入支援。有興趣進一步知道它支援哪些上色風格和語言的可以到他的 Github Ropository 做瀏覽。

不過儘管 Crayon 提供許多彈性的設定,但對我來說仍然有些地方不足。比如說他會直接把 <pre> 標籤轉換成自己的標籤以提供上色服務,但是他的上色的預設風格(例如純文字的環境)又有奇怪的上色,當我希望能提供單一色調 <pre> 時就會衝突。所以我將他的 Paser 說了點變化,讓它只會抓取有 crayon 屬性並以其結尾的 <pre> 標籤,像是這樣 <pre class="..." crayon>...</pre>,這樣我就可以讓一般的 <pre> 標籤和給 Crayon 上色的部分共存了。2

修改方式很簡單,使用外掛編輯器打開 wp.php 這份檔案,如下所述修改 capture_crayons() 的內容即可。

if ((CrayonGlobalSettings::val(CrayonSettings::CAPTURE_PRE) || $skip_setting_check) && $in_flag[CrayonSettings::CAPTURE_PRE]) {
    # 刪除這行
    $wp_content = preg_replace_callback('#(?<!\$)<\s*pre(?=(?:([^>]*)\bclass\s*=\s*(["\'])(.*?)\2([^>]*))?)([^>]*)>(.*?)<\s*/\s*pre\s*>#msi', 'CrayonWP::pre_tag', $wp_content);

    # 以這行取代之
    $wp_content = preg_replace_callback('#(?<!\$)<\s*pre(?=(?:([^>]*)\bclass\s*=\s*(["\'])(.*?)\2([^>]*))?)([^>]*)crayon>(.*?)<\s*/\s*pre\s*>#msi', 'CrayonWP::pre_tag', $wp_content);
}

另外,我也希望能整合 Markdown 語法去支援類似 ~~~php 的語法,但是 Jetpack 提供的 Markdown 會自動將這種用法將 ~~~ 轉成 <pre><code> 、將 ~~~php 轉成 <pre><code class="php"> ,而不是 Crayon 可以 Parse 的語法。所以我做了以下修改。首先一樣修改 wp.phpcapture_crayons() 方法,在剛剛修改的 if 判斷是裡新增一行去抓取 <pre><code class="php">...</code ></pre> 3 的敘述改成 Crayon 可以讀取的格式,如下:

if ((CrayonGlobalSettings::val(CrayonSettings::CAPTURE_PRE) || $skip_setting_check) && $in_flag[CrayonSettings::CAPTURE_PRE]) {
    # 加入這行,要放在這個判斷式裡的首行
    $wp_content = preg_replace_callback('#(?<!\$)<\s*pre\s*>\s*<code>(.*?)</code>\s*<\s*/\s*pre\s*>#msi', 'CrayonWP::pre_code_tag', $wp_content);

    # 這是我們在上面加入,不過本次修改不相依上面的修改,不一定改過這行。
    $wp_content = preg_replace_callback('#(?<!\$)<\s*pre(?=(?:([^>]*)\bclass\s*=\s*(["\'])(.*?)\2([^>]*))?)([^>]*)crayon>(.*?)<\s*/\s*pre\s*>#msi', 'CrayonWP::pre_tag', $wp_content);
}

然後在 wp.phpclass CrayonWP {} 中加入一個靜態方法:

class CrayonWP {
    ....

    # 加入此方法去轉換格式
    public static function pre_code_tag($matches) {
        $lang = $matches[1];
        $content = $matches[2];

        # 這邊要注意如果你沒有套用上面 `<pre crayon>` 的修改,要將 ` crayon` 刪除
        $result = "<pre class=\"lang:{$lang}\" crayon>{$content}</pre>";
        return $result;
    }

    ...
}

如此就可以成功支援 ~~~language 的語法了。

UpdraftPlus – Backup/Restore

這是用來作為備份和還原的外掛,這部分就見仁見智了,你可使用 Jetpack 提供的付費備份還原服務,也可以使用其他比較知名的外掛,以關鍵字 Backup 去搜尋就會找到挺多的。

本部落格一樣是採用目前活躍安裝度最高的外掛,叫做 UpdraftPlus Backup/Restore,他擁有我需要的基本功能如最基本的備份和還原、還有定期備份、將備份檔同步到雲端空間,基本上我只要有這三個就足以滿足我的需求了。

另外我也針對備份做了雙保險,就是利用 Docker 將 WordPress 存放的資料的 wp-content 以及 MariaDB 的資料庫檔案 Volume 出來,然後再透過排程去執行腳本,定期將這兩個資料夾壓縮備份到 Nas 上,這部分我會在下一個章節細述。

環境部署與架設

自從會使用 Docker 後,要架設一個服務我都會率先尋找是否已經有相關映像檔(Image),以節省安裝環境與架設服務的時間。Wordpress 身為知名的部落格系統,官方很早就有提供其映像檔,詳細資訊可看 WordPress 在 Docker Hub 的頁面

而隨著 Docker Compose 逐漸普遍與成熟,官方也有提供 docker-compose.yml 的設定樣本給使用者,事實上該設定檔已足以讓我架設 WordPress。但為了開發方便以及避免不小心把容器砍掉導致資料消逝,或是未來升級版本更加方便,我都會習慣把資料所在資料夾做 Volume,讓其資料與 Host 上同步。在新增 Volumes 的設定後,我的 docker-compose.yml 設定檔如下:

wordpress:
  image: wordpress:4.7.1-php7.1-apache
  restart: always
  environment:
    WORDPRESS_DB_PASSWORD: YOUR_PASSWORD
  links:
    - db:mysql
  ports:
    - 8080:80
  volumes:
    - ./wp-content:/var/www/html/wp-content

db:
  image: mariadb
  restart: always
  environment:
    MYSQL_ROOT_PASSWORD: YOUR_PASSWORD
  volumes:
    - ./database:/var/lib/mysql

幸運的是,這些映像檔都有針對這部份做最佳化,你不用擔心在 Host 上無資料,因而將空資料夾取代掉容器中原本有檔案的資料夾,導致容器建立失敗。Wordpress 的映像檔會先建立容器後,再把 WordPress 的程式檔案丟到 /var/www/html/ 中以進行安裝。同樣的 MariaDB 的映像檔也有類似的支援。因此儘管一開始沒有資料,仍可直接以此設定檔建立容器。

所以環境建立與部署很簡單,只要伺服器上有 Docker 和 Docker-Compose 即可。隨後建立一個資料夾,並將上面的設定檔寫在該資料夾下的 docker-compose.yml 中,最後在該資料夾下輸入指令 docker-compose up,Wordpress 就建立起來啦!

最後,我們就透過 Host 的命令列,移動到 wp-content/themes/ 資料夾下,使用 git 將自己客製化的主題複製(git clone)到此目錄下,再利用 WordPress 後台的佈景主題頁面去啟用,就成功將我的主題套用在 WordPress 上啦!

結語

從去年十二月開始有念頭要將部落格從 Jekyll 遷移到 WordPress 上,到實際完成大概經歷了兩個月,實際動工的時間大概就是從農曆新年假期開始的約莫兩週左右。這一週耗費最多時間的大概就是在主題的移植與改進,也趁機弄熟了 WordPress 主題的製作方式,再來大概就是去將程式碼高亮、資料備份等雜事都推上軌道。

另外耗費許多時間的大概就是將文章轉過來,這部分我就沒有透過程式處理了,畢竟網路上的程式大概都是幫你從 WordPress 轉移到 Jekyll,我這種遷移反而是小眾了,況且文章還不多,比起自己在寫程式或正規表達式,手動轉倒是比較省事。另一方面自己手動轉過來也是為了重新審視自己以前寫的文章,知道未來有空要針對哪些文章做維護,尤其是 Docker 相關的文章,可能過期不少了。

嘛,耗費不少時間做這件事,希望算有移除以前懶得寫文章的障礙,讓自己能願意再多寫文章充實這個部落個囉。接下來半年算是自己的論文衝刺期,或許也會將蒐集到的資料與想法,局部的放在這個地方作為筆記。

最後,新的西元年、農曆年,還請大家多多指教。 <(_ _)>


  1. 雖然 WordPress 官方的 Markdown Quick Reference 有提到是有支援的,但我自行嘗試後是沒有成功上色的,不知道問題是出在哪裡(版本不同、文件過期之類的?)。若是有讀者實驗後是有的,還煩請跟我說一聲,我們再討論交流一下。w 
  2. 另一種方案就是新增一個語言支援(例如取名為 txt),然後不使用任何配色。 
  3. 在寫這邊文章時,發現 Jetpack Markdown 只要使用到含有 </code> 的 code 語法時就會 Parser 錯誤,如 ...</code>... 。但若中間有加空格如 </ code></code > 就沒事,所以在這裡我們才這樣表示。在註解裡則是裡用 Markdown 可以使用 HTML Tag,且 Parser 不會去解析 HTML Tag 中的文字的特性,使用 <code>&lt;/code&gt;</code> 這種較難維護的語法做表示。 

Information Technology , ,