我使用的Ghost
博客一直使用者默認(rèn)的Casper
主題。我向來沒怎么打理過自己博客,一方面認(rèn)為自己不夠?qū)I(yè),很難寫出質(zhì)量比較高的文字;另一方面認(rèn)為博客太耗時間,很容易影響正常的工作內(nèi)容。最近公司即將搬遷,我的開發(fā)工作也告一段落,因此抽點時間自定義一個自己的博客主頁。
備注:上圖來自GhostChina官網(wǎng),與本文內(nèi)容無關(guān)。
Ghost與Ghost主題
Ghost
自稱是專業(yè)的內(nèi)容發(fā)布平臺,實際上跟WordPress
相比它只能算一個相對比較年輕的博客系統(tǒng),在功能上完全無法與成熟的WordPress
相比。
我之所以選擇Ghost
作為博客系統(tǒng)除了它簡單方便,更因為它是基于Node.js
且開源。畢竟基本的功能有了,如果有其他需求的話自己改代碼就可以實現(xiàn)。Ghost
提供HTTP
服務(wù)用的是Express
框架。這是一種對我這類半路接觸js
的人都可以輕易掌握的框架。
Ghost主題存放在安裝路徑的content/themes
目錄中。安裝包自帶了Casper
和Roon
兩個主題,其中前者為默認(rèn)主題。
Ghost
支持HandleBars
模板語言,自帶的兩個主題也是基于此語言編寫的,因此,定制Ghost
主題最簡單的方法是復(fù)制一份Casper
的代碼,基于它進行自定義。我就是這么做的。
關(guān)于自定義主題的詳細介紹不在這里展開,若有需要請參考該鏈接:http://docs.ghostchina.com/zh/themes/。
自定義主頁
Ghost
只定義了幾個主要頁面,分別是文章列表頁(包含主頁)、文章內(nèi)容頁、某標(biāo)簽的文章列表、某作者的文章列表,以及一些rss或sitemap相關(guān)的頁面。
這么一說你就發(fā)現(xiàn)了,博客的主頁和文章列表頁面是同一個頁面。主頁對應(yīng)的路徑為/
,列表對應(yīng)的路徑為/page/:page
,其中:page為占位符,表示某個頁碼值,如1、2、3等。這兩個路徑實際上渲染的都是同一個模板文件index.hbs
。默認(rèn)地,Ghost
接收到請求時/page/1
的GET請求時,返回301重定向到/
,再結(jié)合一些樣式變化,從而讓你以為主頁和列表頁是分離開的。
我要做的就是讓主頁和列表頁面不一樣。
解決方法1
首先我想到的就是在index.hbs文件中通過變量渲染不一樣的內(nèi)容。參考pagination.hbs我發(fā)現(xiàn)確實存在這兩個可用的變量:prev
表示是否有前一頁,以及page
表示當(dāng)前為第幾頁。
如果能拿到這兩個變量中的一個,我就可以區(qū)別對待主頁和列表。遺憾的是不行。
分頁相關(guān)的變量是模板驅(qū)動的,也就是說只能在固定的pagination.hbs這個文件中才能獲取對應(yīng)的值。該結(jié)論尚未在代碼上得到驗證
若在這個問題繼續(xù)下去是可以實現(xiàn)我的需求的,但考慮到偏離Ghost
原來的設(shè)計太遠可能埋下更多坑,因此放棄該解決方法。
解決方法2
既然無法在模板上解決問題,那就讓路徑/
渲染原來的index.hbs,讓路徑/page/:page
渲染另一個HandleBars
文件(我設(shè)定為list)。
實現(xiàn)這個方法只要兩個步驟:
- 去除針對
/page/1
的重定向; - 為
/page/:page
指定新的渲染文件list.hbs。
需要改動ghost安裝目錄下的core/server/routes/frontend.js
文件。下面是改動后的結(jié)果:
其中,handleIndexPageParam
是參考handlePageParam
后新增加的一個函數(shù),內(nèi)容如下:
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
路徑對應(yīng)的渲染對象frontend.list
在core/server/controllers/frontend/index.js
中定義。改后的內(nèi)容如下圖所示:
描述list節(jié)點的配置在core/server/controllers/frontend/channel-config.js
中定義,在defaults中增加一個節(jié)點:
...
list: {
name: 'list',
route: '/',
frontPageTemplate: 'home'
},
...
盡管需求實現(xiàn)了,但是這種解決方法產(chǎn)生了新的問題:以后無法直接使用第三方提供的主題,若要使用,需要復(fù)制index.hbs
到新的文件list.hbs
。
解決方法3
實際上方法2的解決方案增加list
相關(guān)的代碼是多余的,我在Ghost官網(wǎng)的文檔里面查到,原來可以讓路徑/
獨立渲染home.hbs
文檔,而路徑/page/2+
依舊渲染index.hbs
。
因此結(jié)合方法2,應(yīng)該可以有一種更輕巧的自定義主頁的方式。
同步博客