我使用的Ghost博客一直使用者默认的Casper主题。我向来没怎么打理过自己博客,一方面认为自己不够专业,很难写出质量比较高的文字;另一方面认为博客太耗时间,很容易影响正常的工作内容。最近公司即将搬迁,我的开发工作也告一段落,因此抽点时间自定义一个自己的博客主页。

备注:上图来自GhostChina官网,与本文内容无关。

Ghost与Ghost主题

Ghost自称是专业的内容发布平台,实际上跟WordPress相比它只能算一个相对比较年轻的博客系统,在功能上完全无法与成熟的WordPress相比。

我之所以选择Ghost作为博客系统除了它简单方便,更因为它是基于Node.js且开源。毕竟基本的功能有了,如果有其他需求的话自己改代码就可以实现。Ghost提供HTTP服务用的是Express框架。这是一种对我这类半路接触js的人都可以轻易掌握的框架。

Ghost主题存放在安装路径的content/themes目录中。安装包自带了Casper和Roon两个主题,其中前者为默认主题。

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这个文件中才能获取对应的值。该结论尚未在代码上得到验证

若在这个问题继续下去是可以实现我的需求的,但考虑到偏离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.list在core/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,应该可以有一种更轻巧的自定义主页的方式。

本文同步博客

读Ghost博客源码与自定义Ghost博客主题的更多相关文章

  1. SpringMVC+Spring+MyBatis个人技术博客源码

    项目描述 Hi,大家好,又到了源码分享时间啦,今天我们分享的源码一个<个人技术博客>,该博客是基于SSM实现的一个个人博客系统,适合初学SSM和个人博客制作的同学学习.有了这个源码,直接买 ...

  2. java个人博客源码

    初入博客园,请各位多关照,来而不往非礼也. 如需要源码以及学习内容,qq:1397617269,我看到就回你们资源. 直接给链接: 链接:https://pan.baidu.com/s/1S_awtg ...

  3. 如何读懂Framework源码?如何从应用深入到Framework?

    如何读懂Framework源码? 首先,我也是一个应用层开发者,我想大部分有"如何读懂Framework源码?"这个疑问的,应该大都是应用层开发. 那对于我们来讲,读源码最大的问题 ...

  4. 修改VCL源码实现自定义输入对话框

    来自:https://yq.aliyun.com/wenji/88428 通过修改VCL源码实现自定义输入对话框 在BCB中有两个函数可以实现输入对话框:InputBox和InputQuery,其实I ...

  5. Android菜鸟的成长笔记(6)——剖析源码学自定义主题Theme

    原文:Android菜鸟的成长笔记(6)--剖析源码学自定义主题Theme 还记得在Android菜鸟的成长笔记(3)中我们曾经遇到了一个问题吗?"这个界面和真真的QQ界面还有点不同的就是上 ...

  6. css控制div显示/隐藏方法及2种方法比较原码 - czf164的专栏 - 博客频道 - CSDN.NET

    body{ font-family: "Microsoft YaHei UI","Microsoft YaHei",SimSun,"Segoe UI& ...

  7. Java并发指南10:Java 读写锁 ReentrantReadWriteLock 源码分析

    Java 读写锁 ReentrantReadWriteLock 源码分析 转自:https://www.javadoop.com/post/reentrant-read-write-lock#toc5 ...

  8. 读源码【读mybatis的源码的思路】

    ✿ 需要掌握的编译器知识 ★ 编译器为eclipse为例子 调试准备工作(步骤:Window -> Show View ->...): □ 打开调试断点Breakpoint: □ 打开变量 ...

  9. 从无到有开发自己的Wordpress博客主题---代码环境准备

    注意这里说的是代码环境准备哦,而不是L(M)AMP运行环境哦,运行环境会在后述文章中在写. 一.在本地初始化git环境并且链接上gitee 1.在gitee上创建一个项目托管你的代码 这个不在赘述,按 ...

随机推荐

  1. bzoj 1084;vijos 1191 [SCOI2005] 最大子矩阵

    Description 这里有一个n*m的矩阵,请你选出其中k个子矩阵,使得这个k个子矩阵分值之和最大.注意:选出的k个子矩阵不能相互重叠. Input 第一行为n,m,k(1≤n≤100,1≤m≤2 ...

  2. [bzoj2665] [cqoi2012]编号

    首先有一个直观暴力的想法.. 枚举每个数,如果这个数可行的话,就加进答案里,然后把和它超过4个位置相同的数去掉. 然后正解真的是这个>_< 假设取到了数x,只要和x有5位相同的数就可以排除 ...

  3. int ,long long等范围

    unsigned   int   0-4294967295   int   -2147483648-2147483647 unsigned long 0-4294967295long   -21474 ...

  4. lombok使用基础教程

    前言 lombok是一个编译级别的插件,它可以在项目编译的时候生成一些代码.在很多工具类的项目中都有这个功能.比如dagger. 通俗的说,lombok可以通过注解来标示生成getter settte ...

  5. BLE空中升级 谈(一)

    BLE 空中升级谈 -- CC2541 的产品开发中OAD注意事项 现在的智能设备(可穿戴,智能家居,智能玩具等)是越来越多了,大公司的产品颜值高,功能强大而完备的应该说是比比皆是,这里不谈论它是满足 ...

  6. 我的第一个python web开发框架(20)——产品发布(部署到服务器)

    首先按上一章节所讲述的,将服务器环境安装好以后,接下来就是按步骤将网站部署到服务器上了. 我们的站点是前后端分离的,所以需要部署两个站点.首先来发布前端站点. 部署前端站点 输入命令进入svn管理文件 ...

  7. UE4 Xml读写

    UE4自带一个XmlParser,可以很方便的实现Xml的读写. 1,在PublicDependencyModuleNames.AddRange中添加XmlParser. 2,include XmlP ...

  8. Oracle_创建用户_授予权限

    Oracle_创建用户_授予权限 --创建用户,需要足够的权限  create create user hzf identified by hzf;    --给用户bjsxt分配权限  grant ...

  9. linux CentOS部署【minimal 】

    1.为什么选择CentOS不选择其他版本:http://www.cnblogs.com/TeemoHQ/p/6377260.html 2.准备的资源:VMware[官网下载],CentOS镜像 [阿里 ...

  10. ngRx 官方示例分析 - 3. reducers

    上一篇:ngRx 官方示例分析 - 2. Action 管理 这里我们讨论 reducer. 如果你注意的话,会看到在不同的 Action 定义文件中,导出的 Action 类型名称都是 Action ...