Ghost blog with Prism

如果一個 tech blog 在文章中沒有 code example 跟 code blocks ,那就跟太陽餅沒有太陽、老婆餅沒有老婆一樣是廣告不實🤔。

因此為了在 Ghost Blog 中加入這樣的功能,我們只需要在 Code Injection 這裡引入一些使用 Prism.js 必要的 Library 與 CSS 就能讓文章有漂亮的程式碼色彩標註囉~

使用 Prism.js

Prism.js 主要有兩種使用方式,一種是使用本地端檔案,將官網上所下載的 JS 與 CSS 檔案放到 ghost 的資料夾中。另一種方法則是使用 CDN 載入 JS 與 CSS 檔案。
這邊我會兩種方式都使用,因為我習慣使用的Atom-one-dark配色沒有在 CDN 上面,所以只能自己加入,雖然說只是一些 CSS 但又不想要直接貼在 Code Injection 內造成雜亂,因此將直接在 Ghost的資料夾中修改 .hbs檔 來達成。而主要的 JS Library 則會使用 CDN 加載的方式。

CDN加載

其實很簡單,只需要在 Code InjectionFooter 中加入,由 cdnjs.com 所提供的 JS 就可以完成加載。

<!--主檔-->
<script defer  src="https://cdnjs.cloudflare.com/ajax/libs/prism/1.23.0/prism.min.js"></script>
<!--提供行數計算的Plugin-->
<script defer  src="https://cdnjs.cloudflare.com/ajax/libs/prism/1.23.0/plugins/line-numbers/prism-line-numbers.min.js"></script>

而另一個需要載入的則是 line-numbers 這個 Plugin 的 CSS,一樣由 CDN 加載。不過這次是加入在 Code InjectionHeader 中。

<link rel="stylesheet" type="text/css" href="https://cdnjs.cloudflare.com/ajax/libs/prism/1.23.0/plugins/line-numbers/prism-line-numbers.min.css"></link>

本地端載入

要在 Ghost 上使用本地載入步驟沒有很複雜,但若要複雜的方式修改也行,不過這裡不會有相關的教學(可能未來會補),可以直接參考該主題的說明去修改本地的 CSS ,如我這個主題 Alto 的 Readme 就有提到它有使用到 Gulp/PostCSS 先 compile CSS 檔案,因此若是直接修改主題資料夾內的 CSS 是不會有任何的改變,必須在修改後 recompile 才能看到效果。

問題來了,這個 Theme folder 在哪裡呢?

若你是使用 ghost-cli 建立的話,主題資料夾應該是在 /var/lib/ghost/content/themes/ 底下。
我在架設這個 Ghost Blog 的時候是使用 docker 的方式建立,在一開始的時候就有將 /var/lib/ghost/content/ 內的資料 mapping 到 host 上,因此不需要再額外進入 docker container 內修改檔案。

接下來的步驟就很簡單了,找到現在正在使用的主題資料夾,進入 {主題資料夾}/assets/css/ ,在這裡建立你想要使用的 highlight CSS 就可以了。
接下來將 {主題資料夾}/ 底下的 default.hbs 打開,在 <head> 加入你的 stylesheet 就完成啦。

如果看不懂的話,舉我自己為例:
我先到 /var/lib/ghost/content/themes/alto/assets/css/misc/ 底下新增一個 prism-onedark.css 並將 CSS code 輸入。
接下來到 /var/lib/ghost/content/themes/alto/default.hbs 內的 <head> 加入

<head>
...
<link rel="stylesheet" href="{{asset "css/misc/prism-onedark.css"}}">
...
</head>

然後再 restart docker container 即可。

該怎麼寫?

在 Ghost Blog 中的寫法主要有兩種,一種是直接使用內建的 Markdown 語法撰寫,另一種嚴格說還是在 Markdown 中撰寫,但是使用的方法則是利用 Inline HTML 來撰寫 HTML code 來表現,畢竟 Markdown 最後就是編譯成 HTML

Markdown 寫法

由於 Ghost 本身就支援 Markdown 語法的撰寫文章,而 Markdown 本身就支援 code block 的語法,因此只需要輸入三個反引號,並在反引號後空一格再加上 language name 就可以看到效果了。

例如下圖這段程式碼:

經過 Markdown 渲染後像這樣:

<script>
    window.onload=function(){
        var share = document.querySelector(".share");
        var author = document.querySelector(".author");
        if (share !== null){share.remove();}
        if (author !== null){author.remove();}
    }
</script>

如果沒有出 BUG 或是我有更換主題的話,應該要長得如下圖:

以上就是使用 Markdown 本身的語法搭配 Prism.js 所呈現出的效果。但有時候程式碼比較長的時候,我們會需要標註行數這樣功能來輔助閱讀, Prism.js 是有提供 line-numbers 這個 Plugin 可以提供使用者標註程式碼行數,但至目前為止,我還沒找出該怎麼在 Markdown 用法中加上 line-numbers 這個 Plugin 的方法,因此需要藉由第二種使用 Inline HTML 的寫法來使用於需要標註行數的程式碼。

Markdown Inline HTML 寫法

使用 HTML 的寫法也不難,只需要使用 precode 這兩個 tag 就能將在被他們所包住的程式碼進行 highlight ,只需要在兩個 tag 其中之一加上 class=language-{name}即可,若是要使用行數計算,只需要再空一格,並加上 line-numbers 就完成了。

以下是同樣一段程式碼區段,使用Inline HTML的寫法達成,並加入 line-numbers Plugin 。
這裡可以發現在 <script> 這個 tag 的部分有些不一樣,那是因為在這裡的 HTML Code 會直接編譯成一般的 HTML ,因此若是直接寫 <script> 就會讓瀏覽器誤以為這段程式碼是一段需要被執行的 <script> ,而無法正常輸出 code block 。因此需要使用 &lt;&gt; 這類 HTML 字符編碼進行撰寫。


經過 Markdown 渲染後像這樣:


<script>
    window.onload=function(){
        var share = document.querySelector(".share");
        var author = document.querySelector(".author");

        if (share !== null){share.remove();}
        if (author !== null){author.remove();}
    }
</script>;

如果沒有出 BUG 或是我有更換主題的話,應該要長得如下圖:

那我該如何知道我使用的語言的language name為何呢?

https://prismjs.com/#supported-languages 官網就有提供清單可以做查詢~

以上就是這一次的筆記,過程中踩了很多的坑,但也因此從中學到不少經驗,在此分享給大家作為參考。
依然同一句話,在開發的經驗與技術面的部份仍不是這麼熟稔,若有寫得不夠周全或錯誤煩請指正。