首页
3. 打造一款炫酷的主题,我们只需要掌握以下技能

就我目前所知,对个人博客感兴趣的有这些群体:学生、作者、程序员、设计师...

对于开源的博客框架也有很多种选择,我们可以用老牌的 WordPress 、也可以用 Github + Jekyll 搭一个静态的站点、也可以用二次元码农喜欢的 Hexo,还有 Hugo 等等,当然还有我们的 Ghost

以上的大部分博客框架我都有尝试过,最终还是觉得 Ghost 用得比较顺手。优缺点什么的我这里就不做对比了,没有最好的,只有最合适的。

需要用到的技能

对于主题制作其实不需要太多的知识,我们只需要知道简单的 HTML + CSS 就可以了 , 如果知道一点 JS 那更好了。

但如果想随心所欲地打造一款看起来不错而且工程上比较规范的主题,我们需要掌握以下技能

  • HTML5 + CSS3 + JavaScript (ES6)
  • Sass 或 Less
  • Handlebars (ghost所用的模板语言)
  • gulp 或 webpack (构建工具)
  • 英文文档阅读能力
  • 设计能力

HTML 的基础知识可以去 w3school get 到。Sass 和 Less 是动态的 CSS 语言,也不是很难,网上有很多十分钟入门教程,花十分钟看一下就会了。构建工具我们选择 Gulp 吧,也不是什么大的工程,这个相对易于学习一点。Handlebars 是一种模板语言,它有自己的官网,但对于我们开发主题来说,只需要了解几个简单的表达式就可以了。

Handlebars

image_1ehqveesb1l7916lp14ju1lp2aqnp.png-30.6kB

首先介绍的是 Handlebars。Handlebars 可以说是 Ghost 主题的灵魂了,正如它教程里介绍的一样。我们用它配合后台提供的上下文数据,就可以很方便地在 HTML 中使用动态的数据。

我们先看一下它官网提供的示例吧

<div class ="entry">
	<h1> {{title}} </h1>
	<div class = "body">
		{{body}}
	</div>
</div>

Handlebars 模板是由普通的 HTML 和 Handlebars 表达式组成的。所有的 Handlebars 表达式都是用两个大括号包裹起来的。

然后我们需要提供 context (上下文数据)

{
title: "My New Post",
body: "This is my first post!"
}

最终的结果如下

<div  class = "entry">
	<h1> My New Post </h1>
	<div class = "body">
		This is my first post!
	</div>
</div>

在我们的 Ghost 主题里,每个模板都有特定的 context ,我们通过官方提供的 context-table ,可以找出当前模板可以访问的数据。

模板可以访问的所有数据实际上都是一个很大的 JSON 对象 ( 一组嵌套的属性及其值),这对于一篇文章来说看起来像这样:

{
post: {
id: "xyz",
title: "My blog post title",
slug: "welcome",
...
author: {
id: "abc",
name: "Jo Bloggs",
...
}
}
}

Data Expressions (数据表达式)

数据表达式是最简单也是最常用的,主要用来输出模板可以访问的数据,比如 {{title}}
可以输出文章的标题

HTML Data Expressions

例如:{{{bio}}}

有时,我们需要输出的数据可能包含 HTML ,但默认的 {{}}表达式会将 HTML 当成纯文本输出,使用 {{{}}} 才能正确呈现 HTML

Global Data

例如:{{@site.title}}

Ghost 可以通过 {{@site}} 属性访问一些全局数据,@标志也可以在块级表达式中提供特殊的属性,后面会在具体的使用场景中介绍到

Path Expressions

例如:{{primary_author.name}}

有时,我们想要输出的属性在当前的作用域中不可用,因为它属于另一个对象。例如,如果我们想输出文章的作者姓名,用{{name}}是不行的。只能通过 {{primary_author.name}}来访问。

Block Expressions (Scopes)

例如:{{#post}}{{/post}}

有时,我们想要输出比较多的属性,例如,在文章里需要访问大量作者属性。我们可以使用块级表达式来框定一个作用域,那样就不用频繁使用 Path Expressions 了。

块级表达式类似于 HTML 标签,有开始和结束标记,在它们之间我们可以直接访问当前对象的属性,例如:

{{#primary_author}}
My name is {{name}}, visit my <a href="{{website}}">Website!</a>
{{/primary_author}}

Block expressions vs Path expressions

{{#primary_author}}{{name}}{{/primary_author}}{{primary_author.name}}在很大程度上是一样的。这两种写法最大的不同就是在块级表达式中我们可以使用 handlebars helpers

直接这样解释有点不好懂,我们举个例子吧,在 index.hbs里面这样写:

{{!< default}}
{{#posts.[0]}}

<p>{{primary_author.url}}</p>

{{#primary_author}}
<p>{{url}}</p>
<p>{{url absolute="true"}}</p>
{{/primary_author}}

{{/posts.[0]}}

输出结果

image_1ehr5huid1tt41gkh1imt1jjt7s516.png-12.1kB

可以看到第一种写法的url跟第二种写法的url输入的结果不太一样。因为{{url}}是一个 Data Helper,它默认输入的是相对路径。如果要跟第一种写法一样,需加上absolute="true"

Block + Path Expressions

这两种表达式还可以有更高级的用法,比如结合起来使用以达到我们希望的结果。下面的例子显示了如何使用主页上的最新帖子

{{#posts.[0]}}
<h3 class="first_title">{{title}}</h3>
<div class="first_content">{{content}}</div>
{{/posts.[0]}}

在实际的主题开发中,这是很有用的。比如我们想针对最新的文章设计样式,突出显示

Helpers (助手)

例如前面提到的:{{content}}{{url}}。ghost v3 把 heplers 分为了 Functional HelpersData HelpersUtility Helpers,这种区分方式让大家更容易去查询文档。

助手表达式与其它表达式的区别在于它提供了一些方法,而不仅仅是输出数据。本质上,数据表达式是变量,助手表达式是函数。

Functional Helpers

image_1ehr630e214h5cknbon14ud178a1j.png-42.6kB

Functional Helpers 里面有之前版本的Block Helpers,以及新增加的hasget。下面列举的四个Block Helpers主要是做一些流程控制。hasget则提供了更为灵活的操作方式,后面具体会介绍到。

  • {{#if}}{{else}}{{/if}}
  • {{#is}}{{/is}}
  • {{#unless}}{{else}}{{/unless}} ,与 if 相反
  • {{#foreach}}{{/foreach}}

Data Helpers

image_1ehr6a1qtfcen871svg1k95fo12t.png-54.3kB

Data Helpers 方便我们更容易地处理一些数据的展示。比如:{{excerpt characters="140"}}可以输入文章的140个字符作为列表中的介绍语句。

Utility Helpers

image_1ehr6o302sc31hs21as4crgea3a.png-59.8kB

Utility Helpers 提供的是一些功能性的助手,在主题样式的控制上可以给到我们很多便捷的操作。比如:body_class 在不同的页面会输出为不同的类。pagination可以很方便地处理分页……

Layout Expressions (布局表达式)

例如:{{!< default}}{{{body}}}

布局的作用是允许我们定义一个其他模板可以扩展的基本模板。在 Ghost 主题中常见的做法是新建一个default.hbs的默认模板,里面包含一个 HTML 页面的核心元素:header 、 footer 和 内容。然后我们会用 {{{body}}}这个助手函数来加载其他模板的内容。其他模板都以{{!< default}}表达式开始,表明它扩展了默认的布局

Partial Expressions

例如:{{> loop}}

Partial 也是 Ghost 主题里面很重要的内容。它允许我们创建包含在其他模板里的小型可重用模板。通常我们会在根目录创建一个partials目录来存放我们创建的各种小的模板,比如:loop.hbs,然后在其他的模板中可以使用{{> loop}} 输出内容。注意:如果partials目录里面还有子目录,我们输出的时候要将路径带上,比如:{{> author/mini-bio}}

Comments (注释)

例如:{{!-- comments --}}

Handlebars 有自己的注释方式,跟 HTML 不一样,需要注意一下。

其他

这篇教程着重讲的是 HandlebarsGhost 主题中是怎样运用的。掌握了这些,我们可以基于它提供的助手去实现我们自己的主题。最后想说的是,它本身提供的只是一个工具而已,我们更多的想法应该是制作博客主题本身。这里面会涉及到更多其他的能力,比如设计能力、编码功底、项目管理能力等等。