讀Ghost博客源碼與自定義Ghost博客主題

来源:https://www.cnblogs.com/developerdaily/archive/2018/01/03/8184473.html
-Advertisement-
Play Games

我使用的Ghost博客一直使用者預設的Casper主題。我向來沒怎麼打理過自己博客,一方面認為自己不夠專業,很難寫出質量比較高的文字;另一方面認為博客太耗時間,很容易影響正常的工作內容。最近公司即將搬遷,我的開發工作也告一段落,因此抽點時間自定義一個自己的博客主頁。 備註:上圖來自GhostChin ...


我使用的Ghost博客一直使用者預設的Casper主題。我向來沒怎麼打理過自己博客,一方面認為自己不夠專業,很難寫出質量比較高的文字;另一方面認為博客太耗時間,很容易影響正常的工作內容。最近公司即將搬遷,我的開發工作也告一段落,因此抽點時間自定義一個自己的博客主頁。

ghost

備註:上圖來自GhostChina官網,與本文內容無關。

Ghost與Ghost主題

Ghost自稱是專業的內容發佈平臺,實際上跟WordPress相比它只能算一個相對比較年輕的博客系統,在功能上完全無法與成熟的WordPress相比。

我之所以選擇Ghost作為博客系統除了它簡單方便,更因為它是基於Node.js且開源。畢竟基本的功能有了,如果有其他需求的話自己改代碼就可以實現。Ghost提供HTTP服務用的是Express框架。這是一種對我這類半路接觸js的人都可以輕易掌握的框架。

Ghost主題存放在安裝路徑的content/themes目錄中。安裝包自帶了CasperRoon兩個主題,其中前者為預設主題。

Ghost支持HandleBars模板語言,自帶的兩個主題也是基於此語言編寫的,因此,定製Ghost主題最簡單的方法是複製一份Casper的代碼,基於它進行自定義。我就是這麼做的。

關於自定義主題的詳細介紹不在這裡展開,若有需要請參考該鏈接:http://docs.ghostchina.com/zh/themes/

自定義主頁

Ghost只定義了幾個主要頁面,分別是文章列表頁(包含主頁)、文章內容頁、某標簽的文章列表、某作者的文章列表,以及一些rss或sitemap相關的頁面。

這麼一說你就發現了,博客的主頁和文章列表頁面是同一個頁面。主頁對應的路徑為/,列表對應的路徑為/page/:page,其中:page為占位符,表示某個頁碼值,如1、2、3等。這兩個路徑實際上渲染的都是同一個模板文件index.hbs。預設地,Ghost接收到請求時/page/1的GET請求時,返回301重定向到/,再結合一些樣式變化,從而讓你以為主頁和列表頁是分離開的。

我要做的就是讓主頁和列表頁面不一樣。

解決方法1

首先我想到的就是在index.hbs文件中通過變數渲染不一樣的內容。參考pagination.hbs我發現確實存在這兩個可用的變數:prev表示是否有前一頁,以及page表示當前為第幾頁。

pagination.hbs

如果能拿到這兩個變數中的一個,我就可以區別對待主頁和列表。遺憾的是不行。

pagination解釋

分頁相關的變數是模板驅動的,也就是說只能在固定的pagination.hbs這個文件中才能獲取對應的值。該結論尚未在代碼上得到驗證

若在這個問題繼續下去是可以實現我的需求的,但考慮到偏離Ghost原來的設計太遠可能埋下更多坑,因此放棄該解決方法。

解決方法2

既然無法在模板上解決問題,那就讓路徑/渲染原來的index.hbs,讓路徑/page/:page渲染另一個HandleBars文件(我設定為list)。

實現這個方法只要兩個步驟:

  1. 去除針對/page/1的重定向;
  2. /page/:page指定新的渲染文件list.hbs。

需要改動ghost安裝目錄下的core/server/routes/frontend.js文件。下麵是改動後的結果:修改結果

其中,handleIndexPageParam是參考handlePageParam後新增加的一個函數,內容如下:

function handleIndexPageParam(req, res, next, page) {  
    var rssRegex = new RegExp('/rss/(.*)?/');

    page = parseInt(page, 10);

    if (page === 1 && rssRegex.test(req.url)) {
        // Page 1 is an alias, do a permanent 301 redirect
        return redirect301(res, req.originalUrl.replace(rssRegex, '/rss/'));
    } else if (page < 1 || isNaN(page)) {
        // Nothing less than 1 is a valid page number, go straight to a 404
        return next(new errors.NotFoundError());
    } else {
        // Set req.params.page to the already parsed number, and continue
        req.params.page = page;
        return next();
    }
}

另外/page/:page路徑對應的渲染對象frontend.listcore/server/controllers/frontend/index.js中定義。改後的內容如下圖所示:修改後的內容

描述list節點的配置在core/server/controllers/frontend/channel-config.js中定義,在defaults中增加一個節點:

...
list: {  
    name: 'list',
    route: '/',
    frontPageTemplate: 'home'
},
...

儘管需求實現了,但是這種解決方法產生了新的問題:以後無法直接使用第三方提供的主題,若要使用,需要複製index.hbs到新的文件list.hbs

解決方法3

實際上方法2的解決方案增加list相關的代碼是多餘的,我在Ghost官網的文檔裡面查到,原來可以讓路徑/獨立渲染home.hbs文檔,而路徑/page/2+依舊渲染index.hbs

因此結合方法2,應該可以有一種更輕巧的自定義主頁的方式。

本文同步博客

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • [1]數據結構 [2]二叉樹 [3]樹的遍歷 [4]樹的搜索 [5]自平衡樹 ...
  • 本文寫給有一定Promise使用經驗的人,如果你還沒有使用過Promise,這篇文章可能不適合你,建議先瞭解Promise的使用 Promise標準解讀 1.只有一個then方法,沒有catch,race,all等方法,甚至沒有構造函數 Promise標準中僅指定了Promise對象的then方法的 ...
  • 在使用Promise處理一些複雜邏輯的過程中,我們有時候會想要在發生某種錯誤後就停止執行Promise鏈後面所有的代碼。 然而Promise本身並沒有提供這樣的功能,一個操作,要麼成功,要麼失敗,要麼跳轉到then里,要麼跳轉到catch里。 如果非要處理這種邏輯,一般的想法是拋出一個特殊的Erro ...
  • 最近在逛各大網站,論壇,以及像SegmentFault等編程問答社區,發現Vue.js異常火爆,重覆性的提問和內容也很多,樓主自己也趁著這個大前端的熱潮,著手學習了一段時間的Vue.js,目前用它正在做自己的結業項目。 在做的過程中也對Vue.js的官方文檔以及其各種特性有了許多認識。作為一個之前以 ...
  • margin和padding的區別和用法 什麼是margin、padding? marigin:就是外邊距。padding:就是內邊距。怎麼就容易記住兩者呢? 馬蓉大家都知道吧,給王寶強帶帽子的那位,假如你認識了馬蓉是不是想離他遠點呢?而馬蓉的拼音是marong,是不是和margin特別像呢?那麼你 ...
  • 轉自:http://www.cnblogs.com/chiname/articles/216517.html(侵刪) /* * 方法:Array.removeAt(Index) * 功能:刪除數組元素. * 參數:Index刪除元素的下標. * 返回:在原數組上修改數組 */ /* * 方法:Arr ...
  • 今天在寫前端頁面的時候,覺得font-awesome簡單實用就上手試了一下,因為font-awesome圖標庫甚為強大,我就在其css上多做了一些嘗試,這一嘗試發現了一個致命的問題,當我對i標簽進行統一字體大小以及統一字體樣式的時候,發現了我的網頁在不同瀏覽器上的顯示問題,顯示如下: QQ瀏覽器: ...
  • React 可被靈活地運用在各種項目中。你可以用它創建新的應用程式,也可以逐漸地將其加入到現有的代碼庫中而無需重寫。 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...