> ## Content Index
> Fetch the complete content index at: https://nigzu.com/llms.txt
> Use this file to discover other available public pages before exploring further.

# Ghost 主题开发学习
- URL: https://nigzu.com/ghostkai-develop-theme-learn/
- Published: 2025-05-14T08:52:09.000Z
- Updated: 2025-06-08T17:40:28.000Z
- Author: 宁嘉
- Tags: Ghost, 砖工技术

[构建自定义 Ghost 主题 - 文档](https://ghost.org/docs/themes/?ref=nigzu.com)

## 基本概念

- Handlebars 是 Ghost 的模板语言，用于创建模板。
- `index.hbs` 、 `post.hbs` 和 `package.json` 这三个必填文件构成了主题的基本结构。
- 上下文将网站数据与正确的模板连接起来。
- GScan 工具用于验证 Ghost 主题。

### 模板语言

Ghost 主题使用标准 HTML 、CSS 和 JavaScript 创建，在需要呈现动态数据时使用 Handlebars 表达式， [Handlebars](https://handlebarsjs.com/guide/expressions.html?ref=nigzu.com) 是一种模板语言，因此页面扩展名为 `.hbs`，该语言将动态数据渲染为静态 HTML 的形式发送到浏览器。

Ghost 还使用了一个名为 `express-hbs` 的附加库为 Handlebars 添加了一些附加功能，如布局和局部。

#### 基本helper语法

`{{` 和 `}}` 是 Handlebars 的开头和结尾标记，插入到html中，它们告诉 Ghost 需要对其中的数据进行处理。

`@site.title` 是一个特殊的数据对象，它获取实际的网站标题渲染模板。例如：`<h1>{{@site.title}}</h1>` 。

`{{#if}}` 用于条件判断，在其后输入要检查的值。如果该值为 true 或存在，则将呈现 Handlebars 标记 ( `{{#if}}{{/if}}` ) 之间的所有标记。如果值为假或不存在，则不会渲染。

```handlebars
{{#if feature_image}}
  Code to display if there is a feature image
{{/if}}

```

`{{#foreach}}` 助手遍历帖子列表。

为了使 Ghost 主题正常工作，必须使用所需的helper工具： `{{asset}}` , `{{body_class}}` , `{{post_class}}` , `{{ghost_head}}` , `{{ghost_foot}}` 。

#### 进阶语法

##### 功能助手：

| Tag 标签                                                                  | Description 说明                 |
| ----------------------------------------------------------------------- | ------------------------------ |
| [foreach](https://ghost.org/docs/themes/helpers/foreach/?ref=nigzu.com) | 专为处理帖子列表而设计的循环助手               |
| [get](https://ghost.org/docs/themes/helpers/get/?ref=nigzu.com)         | 用于自定义查询的特殊块助手                  |
| [has](https://ghost.org/docs/themes/helpers/has/?ref=nigzu.com)         | 就像 {{#if}} ，但除了测试布尔值外，还能进行更多操作 |
| [if](https://ghost.org/docs/themes/helpers/if/?ref=nigzu.com)           | 测试非常简单的条件句                     |
| [is](https://ghost.org/docs/themes/helpers/is/?ref=nigzu.com)           | 检查当前路线的上下文                     |
| [match](https://ghost.org/docs/themes/helpers/match/?ref=nigzu.com)     | 比较两个值是否相等                      |
| [unless](https://ghost.org/docs/themes/helpers/unless/?ref=nigzu.com)   | {{#if}} 的反义词                   |

###### 数据助手

| ag 标签                                                                                                | Description 说明             |
| ---------------------------------------------------------------------------------------------------- | -------------------------- |
| [@config](https://ghost.org/docs/themes/helpers/config/?ref=nigzu.com)                               | 提供对全局数据属性的访问               |
| [@custom](https://ghost.org/docs/themes/helpers/custom/?ref=nigzu.com)                               | 提供访问自定义主题设置的权限             |
| [@page](https://ghost.org/docs/themes/helpers/page/?ref=nigzu.com)                                   | 提供访问页面设置的权限                |
| [@site](https://ghost.org/docs/themes/helpers/site/?ref=nigzu.com)                                   | 访问全局设置                     |
| [@member](https://ghost.org/docs/themes/members/?ref=nigzu.com#the-member-object)                    | 提供成员数据访问权限                 |
| [authors](https://ghost.org/docs/themes/helpers/authors/?ref=nigzu.com)                              | 输出帖子作者                     |
| [comments](https://ghost.org/docs/themes/helpers/comments/?ref=nigzu.com)                            | 输出 Ghost 基于成员的评论系统         |
| [content](https://ghost.org/docs/themes/helpers/content/?ref=nigzu.com)                              | 以 HTML 格式输出完整的帖子内容         |
| [date](https://ghost.org/docs/themes/helpers/date/?ref=nigzu.com)                                    | 以您选择的格式输出日期                |
| [excerpt](https://ghost.org/docs/themes/helpers/excerpt/?ref=nigzu.com)                              | 输出自定义摘录或带 HTML 标记的帖子内容     |
| [facebook](https://ghost.org/docs/themes/helpers/facebook/?ref=nigzu.com)                            | 输出设置中 Facebook 个人资料的完整 URL |
| [social\_url](https://ghost.org/docs/themes/helpers/social%5Furl/?ref=nigzu.com)                     | 输出社交简介的完整 URL              |
| [img\_url](https://ghost.org/docs/themes/helpers/img%5Furl/?ref=nigzu.com)                           | 为提供的图像属性输出计算正确的 URL        |
| [link ](https://ghost.org/docs/themes/helpers/link/?ref=nigzu.com)                                   | 创建动态类链接                    |
| [navigation](https://ghost.org/docs/themes/helpers/navigation/?ref=nigzu.com)                        | 为导航链接输出格式化 HTML 的助手        |
| [post](https://ghost.org/docs/themes/helpers/post/?ref=nigzu.com)                                    | object 多于助手 - 包含特定帖子的所有数据  |
| [price](https://ghost.org/docs/themes/helpers/price/?ref=nigzu.com)                                  | 输出带有格式选项的价格                |
| [readable\_url](https://ghost.org/docs/themes/helpers/readable%5Furl/?ref=nigzu.com)                 | 返回人类可读的 URL                |
| [recommendations](https://ghost.org/docs/themes/helpers/recommendations/?ref=nigzu.com)              | 输出推荐地点列表                   |
| [tags](https://ghost.org/docs/themes/helpers/tags/?ref=nigzu.com)                                    | 输出帖子标签                     |
| [tiers](https://ghost.org/docs/themes/helpers/tiers/?ref=nigzu.com)                                  | 输出职位层级                     |
| [title](https://ghost.org/docs/themes/helpers/title/?ref=nigzu.com)                                  | post 范围内的帖子标题              |
| [total\_members ](https://ghost.org/docs/themes/helpers/total%5Fmembers/?ref=nigzu.com)              | 输出四舍五入并人性化的成员数             |
| [total\_paid\_members ](https://ghost.org/docs/themes/helpers/total%5Fpaid%5Fmembers/?ref=nigzu.com) | 输出付费会员人数，四舍五入并人性化          |
| [twitter](https://ghost.org/docs/themes/helpers/twitter/?ref=nigzu.com)                              | 输出设置中 Twitter 个人资料的完整 URL  |
| [url](https://ghost.org/docs/themes/helpers/url/?ref=nigzu.com)                                      | 在 post 范围内的帖子 URL          |

###### 共用助手

| Tag 标签                                                                                                                                                                            | Description 说明                         |
| --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------- |
| [asset](https://ghost.org/docs/themes/helpers/asset/?ref=nigzu.com)                                                                                                               | 为各种类型的资产输出可缓存和可破坏缓存的相对 URL             |
| [block](https://ghost.org/docs/themes/helpers/block/?ref=nigzu.com)                                                                                                               | 与 {{contentFor}} 一起使用，用于在模板层次结构中上下传递数据 |
| [body\_class ](https://ghost.org/docs/themes/helpers/body%5Fclass/?ref=nigzu.com)                                                                                                 | 输出用于 <body> 标记的动态 CSS 类                |
| [concat](https://ghost.org/docs/themes/helpers/concat/?ref=nigzu.com)                                                                                                             | 将多个事物串联起来                              |
| [encode](https://ghost.org/docs/themes/helpers/encode/?ref=nigzu.com)                                                                                                             | 对文本进行编码，以便在 URL 中安全使用                  |
| [ghost\_head](https://ghost.org/docs/themes/helpers/ghost%5Fhead%5Ffoot/?ref=nigzu.com) / [ghost\_foot](https://ghost.org/docs/themes/helpers/ghost%5Fhead%5Ffoot/?ref=nigzu.com) | 在文件顶部和底部输出重要的系统信息                      |
| [link\_class](https://ghost.org/docs/themes/helpers/link%5Fclass/?ref=nigzu.com)                                                                                                  | 根据当前浏览的页面添加动态类别                        |
| [log](https://ghost.org/docs/themes/helpers/log/?ref=nigzu.com)                                                                                                                   | 在开发模式下，在控制台中输出数据                       |
| [pagination](https://ghost.org/docs/themes/helpers/pagination/?ref=nigzu.com)                                                                                                     | 为分页链接输出格式化 HTML 的助手                    |
| [partials](https://ghost.org/docs/themes/helpers/partials/?ref=nigzu.com)                                                                                                         | 包含可重复使用的模板代码块                          |
| [plural ](https://ghost.org/docs/themes/helpers/plural/?ref=nigzu.com)                                                                                                            | 根据给定的输入内容输出不同的文本                       |
| [post\_class](https://ghost.org/docs/themes/helpers/post%5Fclass/?ref=nigzu.com)                                                                                                  | 输出用于邮筒容器的类                             |
| [prev\_post](https://ghost.org/docs/themes/helpers/prev%5Fnext%5Fpost/?ref=nigzu.com) / [next\_post](https://ghost.org/docs/themes/helpers/prev%5Fnext%5Fpost/?ref=nigzu.com)     | 在 post 范围内，返回上一篇或下一篇文章的 URL            |
| [reading\_time](https://ghost.org/docs/themes/helpers/reading%5Ftime/?ref=nigzu.com)                                                                                              | 显示帖子的预计阅读时间                            |
| [search](https://ghost.org/docs/themes/helpers/search/?ref=nigzu.com)                                                                                                             | 输出可正常工作的预设搜索按钮和图标                      |
| [translate](https://ghost.org/docs/themes/helpers/translate/?ref=nigzu.com)                                                                                                       | 以网站语言输出文本（i18n 的支柱）                    |

### 结构

#### 基本结构

Ghost 主题由多个不同类型的文件组成，但只需要三个文件即可运行：

- `index.hbs`
- `post.hbs`
- `package.json`

`index.hbs` 是网站的入口。默认情况下，该模板文件输出网站的主页。通过修改 `index.hbs` 模板，可以控制 Ghost 网站上帖子列表的显示方式。`index.hbs` 也用于有帖子集合的所有页面。这包括主页和后续页面，以及标签和作者页面。

`post.hbs` 。它用于渲染所有单个帖子和页面。通过修改该模板，可以改变帖子内容在网站上的显示方式。帖子和别页可共用一个模板，或单独构建，它们的主要区别在于：帖子会包含在集合（如主页或标签）的帖子列表中，而页面则不会。可以使用 `post-:slug.hbs` 为单个帖子创建自定义模板。

`package.json` 文件提供了Ghost 主题相关的元数据。这些元数据包括主题名称、版本、脚本、依赖关系、许可证等。Ghost 还使用 `package.json` 配置出版物的各个方面。最常见的三种配置属性包括：

- 每页帖子数：该属性告诉 Ghost 在一个集合中包含多少篇文章。
- 图片尺寸：Ghost 可以自动优化主题图片，该属性可指示 Ghost 生成何种尺寸的图片。
- 自定义设置：这些设置允许用户通过 Ghost 管理配置不同的选项，从而扩展主题的功能。例如，在 Casper 中，自定义设置允许用户选择正文字体是有衬线字体还是无衬线字体。

参考默认主题Casper的模板：[TryGhost/Casper](https://github.com/TryGhost/Casper?ref=nigzu.com)。

#### 进阶结构

推荐的主题项目结构：

```bash
├── /assets
|   └── /css
|       ├── screen.css
|   ├── /fonts
|   ├── /images
|   ├── /js
├── /partials
    ├── list-post.hbs
├── default.hbs
├── page.hbs
├── custom-{{template-name}}.hbs
├── tag.hbs
├── author.hbs
├── private.hbs
├── error.hbs
├── error-{{error-class}}xx.hbs
├── error-{{error-code}}.hbs
├── amp.hbs
├── robots.txt
├── index.hbs [必须]
└── post.hbs [必须]
└── package.json [必须]

```

必选模板如上文。主题模板是分层的，因此一个模板可以扩展另一个模板。这可以防止基础 HTML 重复出现。以下是一些常用的可选模板及其用途：

- `/partials` 目录可选，在网站上使用部分模板，在多个模板之间共享 HTML 块，减少代码重复。
- `default.hbs` 是一个基础模板，建议作为主题的基础布局，它包含每个页面上都有的枯燥的 HTML 内容，如 `<html>` 、 `<head>` 或 `<body>` 以及所需的 `{{ghost_head}}` 和 `{{ghost_foot}}` 以及页眉和页脚的 HTML。
- `page.hbs`,静态页面的可选模板。如果未指定，则将使用 `post.hbs` 。单个页面的自定义模板可使用 `page-:slug.hbs` 映射到页面。
- `home.hbs`，为主页提供特殊内容的可选模板。该模板仅用于呈现 `/` 。
- `custom-{{template-name}}.hbs`可在管理界面中按帖子选择的自定义模板。它们既可用于帖子，也可用于页面。
- `tag.hbs`，标签存档页面的可选模板。如果没有指定，则使用 `index.hbs` 模板。可使用 `tag-:slug` 为单个标记创建自定义模板。
- `author.hbs`，作者档案页面的可选模板。如果未指定，则使用 `index.hbs` 模板。可使用 `author{{slug}}` 为单个作者创建自定义模板。
- `private.hbs`，受密码保护的出版物上密码表格页面的可选模板。
- `error.hbs`处理任何 `404` 或 `500` 错误、`error-{{error-class}}xx.hbs`用于属于特定类别的错误（例如`error-4xx.hbs`）、`error-{{error-code}}.hbs`用于特定状态代码错误，（如 `error-404.hbs` ）。如果定义后一个优先级大于前一个。
- `amp.hbs`,用于 AMP（加速移动页面）的可选主题模板。如果您的主题没有提供 `amp.hbs` 文件，Ghost 将使用其默认值。
- `robots.txt`,主题可以包含一个 robots.txt，覆盖 Ghost 提供的默认 robots.txt。

`package.json`一些最常见的可选附加属性 ：

- `config.posts_per_page` \- 每页的默认帖子数为 5
- `config.image_sizes` \- 图像尺寸
- `config.card_assets` \- 配置 Ghost 自动包含的卡片 CSS 和 JS
- `config.custom` \- 为主题添加自定义设置
- `description` \- 简短描述您的主题及其独特之处
- `docs` \- 包含有关如何使用主题的文档的 URL。文档链接可在设计页面的 Ghost 管理器中找到
- `license` \- 使用有效的许可证字符串，建议使用 `MIT` 。

### 上下文

Ghost 主题中的每个页面都属于一个上下文，它决定了使用的模板和可用的数据，该上下文由 URL 决定。上下文将决定使用何种模板、可用数据以及 `{{body_class}}` 助手的输出内容。下面表格是 Ghost 中所有可用页面、上下文和模板的概览，有两点需要注意：

- 主页有多个索引。同样，只要您不在某个集合的首页， `paged` 上下文就会被包含在内。在网站的 `/page/2/` 上，上下文将是 `paged` 和 `index` 。
- 当特定模板不可用时（如 `author.hbs` ），Ghost 将退回到一个保证存在的模板。

| Context(s)      | Template   | Fallback template | Data                                      |
| --------------- | ---------- | ----------------- | ----------------------------------------- |
| home, index 索引页 | home.hbs   | index.hbs         | Collection of posts 收集帖子                  |
| post 文章         | post.hbs   | \-                | Post data 贴子数据                            |
| page 别页         | page.hbs   | post.hbs          | Page data 页面数据                            |
| author 作者       | author.hbs | index.hbs         | Author data and post collection 作者数据和贴子集合 |
| tag 标签          | tag.hbs    | index.hbs         | Tag data and post collection 标签数据和贴子集合    |

上下文借助Handlebars语法决定了页面输出的动态数据：

- `{{meta_title}}` 辅助程序会根据当前上下文输出不同的内容。如果上下文是 `post` ，那么辅助程序知道它可以使用 `post.meta_title` ，而在 `tag` 上下文中，它会使用 `tag.meta_title` 。
- 要检测主题中的上下文，请使用 `{{#is}}` 。只有在该上下文中才会执行所包含的代码块。

### GScan

GScan 将检查您的主题是否存在错误、弃用和兼容性问题。

- [GScan site](https://gscan.ghost.org/?ref=nigzu.com) 网站可在线测试正在构建的主题以获得完整验证报告。
- 在 Ghost 管理器中上传主题时，会自动使用 内置的`gscan` 对其进行检查，任何致命错误都会阻止主题的使用。
- `gscan` 也可用作命令行工具，全局安装 `gscan` npm 软件包：

```bash
# 安装 npm 包
npm install -g gscan
# 在任何地方使用 gscan <文件路径> 对文件夹运行 gscan 操作
gscan /path/to/ghost/content/themes/casper
# 在压缩文件上运行 gscan 命令
gscan -z /path/to/download/theme.zip

```

### 样式设计

贴子页面会为标题自动生成html元素ID，ID可用于css选择器，因此开发时手动定义的ID最好将其范围限定在页面的特定部分。例如 `#themename-my-id` 好于 `#my-id` 。

#### 响应式图片

响应式图片可以在 `package.json` 文件中定义。Ghost 会自动生成指定尺寸的图片副本，并像缓存一样工作，因此可以随时更改图片尺寸。建议图片大小不超过 10 种，以免媒体存储失控。

定义好图片尺寸后，将 `size` 和 `format` （可选）参数传递给主题中的 {{img\_url}} 辅助程序，以输出特定尺寸和特定格式的图片。

建议将图像从 PNG、GIF 或 JPEG 转换为 WebP，可以将其大小减少约 25%。所有现代浏览器都支持 WebP，但我们建议始终为原始文件类型添加回退功能，以获得更广泛的浏览器支持。为此请使用 `<picture>` 标记，它允许浏览器选择其支持的第一种格式。

所有功能图片和主题图片都会自动生成图片尺寸，并在图片更改、图片尺寸配置更改或主题更改时重新生成。图像会在首次请求时以特定尺寸生成。动态图片大小与外部托管的图片不兼容（Unsplash 插入的图片除外）。如果您将图像文件存储在第三方存储适配器上，那么返回的图像 URL 将由外部来源决定。

#### 小标题样式

有两种可用的小标题样式，可通过反复按小标题工具栏上的图标循环使用。

```html
<blockquote>Standard blockquote style</blockquote>

<blockquote class="kg-blockquote-alt">Alternative blockquote style</blockquote>

```

### Ghost主题中的特殊内容标记

Ghost文章编辑器允许作者调入动态内容块，如照片、视频、推特、嵌入、代码和标记符。要使作者指定的选项正常工作，主题需要支持由 `{{content}}` 助手输出的 HTML 标记和 CSS 类。使用以下示例可确保您的主题与最新版本的 Ghost 编辑器兼容。

#### 图片

1. 图片和嵌入内容将使用语义 `<figure>` 和 `<figcaption>` 元素输出。例如：

```html
{{/*  Output  */}}
<figure class="kg-image-card">
    <img class="kg-image" src="https://casper.ghost.org/v1.25.0/images/koenig-demo-1.jpg" width="1600" height="2400" loading="lazy" srcset="..." sizes="...">
    <figcaption>An example image</figcaption>
</figure>

```

- `.kg-image-card` 用于所有图像卡的 `<figure>` 元素上
- `.kg-image` 用于所有图像卡的 `<img>` 元素上
- `.kg-embed-card` 用于所有嵌入式卡片上的 `<figure>` 元素
1. 编辑器允许图像有三种尺寸选项：正常、宽和全宽。这些尺寸选项可通过在 HTML 输出中的 `<figure>` 元素中添加 `kg-width-wide` 和 `kg-width-full` 类来实现。下面是宽幅图像的示例：

```html
{{/*  Output  */}}
<figure class="kg-image-card kg-width-wide">
    <img class="kg-image" src="https://casper.ghost.org/v1.25.0/images/koenig-demo-1.jpg" width="1600" height="2400" loading="lazy" srcset="..." sizes="...">
</figure>

```

图像卡具有 `width` 和 `height` 属性。宽度和高度与源图片的尺寸和宽高比相对应，在编辑器中选择不同尺寸选项时不会改变。如果您的主题为图片设置了 `max-width` 样式，那么也必须设置 `height: auto` 样式，以避免图片出现拉伸或压扁。

1. 响应式图像尺寸，图像将具有 `srcset` 和 `sizes` 属性，以便将较小的图像提供给屏幕较小的设备。完整的输出将与此类似：

```html
{{/*  Output  */}}
<figure class="kg-card kg-image-card">
    <img src="https://myghostsite.com/content/images/2021/03/coastline.jpg"
        class="kg-image"
        alt="A rugged coastline with small groups of people walking around rock pools"
        loading="lazy"
        width="2000"
        height="3000"
        srcset="https://myghostsite.com/content/images/size/w600/2021/03/coastline.jpg 600w,
                https://myghostsite.com/content/images/size/w1000/2021/03/coastline.jpg 1000w,
                https://myghostsite.com/content/images/size/w1600/2021/03/coastline.jpg 1600w,
                https://myghostsite.com/content/images/size/w2400/2021/03/coastline.jpg 2400w"
        sizes="(min-width: 720px) 720px">
</figure>

```

#### 内容卡

编辑器中的每个内容卡都需要 CSS 和 Javascript 才能正确显示和运行。Ghost 会自动提供这些默认 CSS 和 Javascript 资产，并在 `{{ghost_head}}` 助手中以 `cards.min.css` 和 `cards.min.js` 的形式输出。

您可以通过配置主题的 `package.json` 来排除特定卡片的资产，从而覆盖个别卡片的默认样式和行为：

```json
"card_assets": {
    "exclude": ["bookmark", "gallery"]
}

```

或者，您也可以将 `card_assets` 设置为 false（默认为 true），从而禁用所有卡:`"card_assets": false`。

可用的卡片有 `audio` , `blockquote` , `bookmark` , `button` , `callout` , `file` , `gallery` , `header` , `nft` , `product` , `toggle` , `video` 和 `signup` 。

您可以使用自定义 CSS 来定制单个卡片的样式。每张卡片都有一个独特的类名，你可以针对这个类名应用自己的样式。下面列出了每种卡片类型的类名：

- 音频： `.kg-audio-card`
- 方括号： `blockquote` 或 `.kg-blockquote-alt`
- 书签： `.kg-bookmark-card`
- 按钮： `.kg-button-card`
- 呼出： `.kg-callout-card`
- 文件： `.kg-file-card`
- 画廊： `.kg-gallery-card`
- 页眉： `.kg-header-card`
- NFT： `.kg-nft-card`
- 产品： `.kg-product-card`
- 切换： `.kg-toggle-card`
- 视频： `.kg-video-card`
- 注册： `.kg-signup-card`

```css
.kg-product-card .kg-product-card-container {
    background-color: #f0f0f0;
}

```

参考文档：[Ghost 主题功能：编辑器](https://ghost.org/docs/themes/content/?ref=nigzu.com)和默认卡片样式：[Ghost/ghost/core/core/frontend/src/cards](https://github.com/TryGhost/Ghost/tree/main/ghost/core/core/frontend/src/cards?ref=nigzu.com)

### 搜索

Ghost 有一个本地搜索功能，使用搜索的最简单方法是在导航栏或网站的任何地方添加一个 `#/search` URL。除此之外，还可以使用数据属性直接在主题中实现搜索。

最快捷的方法是使用 `{{search}}` 助手输出带有搜索图标的按钮。更多详情，请参阅帮助文档。或者，将 `data-ghost-search` 数据属性添加到主题中的任何元素。下面是默认主题 Casper 中的一个示例：

```handlebars
<button class="gh-search" data-ghost-search>{{> "icons/search"}}</button>

```

这两种方法都允许访问者通过点击元素打开搜索模式或使用快捷方式 `Cmd/Ctrl + K` 搜索内容。

如果网站规模较大，帖子数量超过 10,000 篇，数据结构复杂，或需要高级搜索功能，建议使用 Algolia。Ghost 拥有开源工具，可预先填充 Algolia 搜索索引，并使用网络钩子和 Netlify 函数保持索引更新。

### 会员

会员可以通过使用门户功能在任何主题中激活，门户功能是一种可嵌入的会员功能，可以通过管理用户界面启用和自定义。还可以通过 URL 或数据属性在主题中访问门户屏幕。例如，门户链接可以使用绝对链接或相对链接：

```html
// Absolute URLs takes readers to the homepage and opens a Portal screen.
<a href="https://example.com/#/portal/signup">Subscribe</a>

// Relative URLs open Portal on the current page.
<a href="#/portal/signup">Subscribe</a>

```

使用 `data-portal` 数据属性控制门户用户界面时，会在元素中添加额外的 `gh-portal-open` 和 `gh-portal-close` 类，以便自定义打开和关闭状态的样式。

另外，也可以直接在主题中建立完全自定义的会员和注册流程。参考文档：[Ghost主题开发：创建自定义会员流程](https://ghost.org/docs/themes/members/?ref=nigzu.com)。

#### 会员内容可见性

所有登录网站的成员都有一个访问级别。与此相对应，所有帖子的 `content` 中都附加了 `visibility` 设置。

`access` 是一个变量，用于计算查看帖子的成员的访问级别和应用于帖子的访问级别设置。如果成员的访问权限符合或超过帖子的访问权限级别， `access` 将返回 `true` ；如果不符合，则返回 `false` 。

```handlebars
{{#post}}
  <h1>{{title}}</h1>

  {{#if access}}
    <p>Thanks for being a member...</p>
  {{else}}
    <p>You need to become a member in order to read this post... </p>
  {{/if}}

  {{content}}
{{/post}}

```

使用 `{{content}}` 助手，无法访问文章（由 `access` 属性决定）的访问者将在内容区域看到默认的行动呼吁，提示用户升级订阅。与帖子内容中的免费公开预览结合使用时，CTA 将显示在免费预览之后。可以通过在主题中提供 `./partials/content-cta.hbs` 模板文件来覆盖默认 CTA。Ghost 提供的默认内容 CTA 可用作参考。

`@member` 对象可用于根据成员的访问级别来确定主题中的哪些内容可以公开。这可以通过 `#if` 语句来实现：

```handlebars
{{#if @member}}
  <p>Thanks for becoming a member 🎉</p>
{{else}}
  <p>You should totally sign up... 🖋</p>
{{/if}}

```

使用 `@member.paid` 允许您向已激活付费订阅的会员公开不同的内容。`@member.paid` 返回 `true` ，用于状态为 "激活"、"试用"、"未支付 "和 "逾期 "的有效订阅会员。要取消付款失败会员的访问权限，请更新 Stripe 设置，以便在所有付款尝试失败后自动取消订阅。

```handlebars
{{#if @member.paid}}
  <p>Thanks for becoming a paying member 🎉</p>
{{/if}}

```

`visibility` 属性是相对于帖子或页面而言的，可根据查看者的状态为模板提供额外的属性信息。 `visibility` 有 3 种可能的值： `public` 、 `members` 或 `paid` 。

```handlebars
<h1>
  {{title}}
  <svg>
    <use xlink:href="#icon-{{visibility}}"></use>
  </svg>
</h1>

```

默认情况下，所有文章（包括设置为 `members-only` 或 `paid-members only` 的文章）都将显示在文章存档中，除非 `visibility` 参数与 `#foreach` 助手一起包含。

将可见性标志与 `#has` 助手一起使用，可以在 `public` 、 `members` 和 `paid` 帖子之间实现更独特的样式。例如：

```handlebars
{{#foreach posts}}
  <article>
    {{#has visibility="paid"}}
      <span class="premium-label">Premium</span>
    {{/has}}
    <h2><a href="{{url}}">{{title}}</a></h2>
  </article>
{{/foreach}}

```

更多和会员有关的主题设置参考官方文档。

### 路由

Ghost 的所有路由配置都定义在 `content/settings/routes.yaml` 中，如果手动编辑文件，则需要重启 Ghost 才能看到更改，但如果在管理器中上传文件，则路由会立即自动更新。

所有新安装的 Ghost 都默认使用 `routes.yaml` 设置传统的发布结构。网站主页是网站文章的反序列表，每篇文章都有自己的 URL，由 `{slug}` 参数定义，如 `my-great-post` 。此外，还有按标签和作者分类的附加文章档案。

```yaml
## routes.yaml
routes:
collections:
  /:
    permalink: /{slug}/
    template: index
taxonomies:
  tag: /tag/{slug}/
  author: /author/{slug}/

```

#### 自定义单页路由

模板路由允许您将单个 URL 映射到 Ghost 主题中的特定模板文件。例如：让 `/features/` 加载 `features.hbs`，以及使用自定义路由来模拟子目录，还有使用`data`属性来在自定义路由的页面使用存储在 Ghost 中的数据：

```yaml
routes:
  /features/: features
  /about/team/:
    template: team
    data: page.team

```

现在， `site.com/team/` 中的数据将在 `site.com/about/team/` 上自定义 `team.hbs` 模板中的 `{{#page}}` 块助手内可用，旧 URL 将重定向到新 URL，以防止内容在两个地方重复。

事实上，可以让路由输出任何内容，例如自定义 RSS 源或 JSON 端点。例如创建了一个自定义模板文件，并使用{{#get}}辅助 API 查询加载筛选过的帖子列表，您就可以在自定义路由上返回这些帖子，并自定义格式：

```yaml
routes:
  /podcast/rss/:
    template: podcast-feed
    content_type: text/xml

```

#### 自定义集合路由

编辑默认集合的一个最简单的例子就是将其移动到一个新的位置，为自定义主页腾出空间，以及进行筛选。

```yaml
routes:
  /: home

collections:
  /blog/:
    permalink: /blog/{slug}/
    template: index
  /podcast/:
    permalink: /podcast/{slug}/
    template: podcast
    filter: primary_tag:podcast

```

##### 创建多语言网站

对于以多种语言发布内容，并希望为每个地区创建不同区域和 URL 模式的网站来说，集合还有一个非常受欢迎的用途。

```yaml
collections:
  /:
    permalink: /{slug}/
    template: index
    filter: 'tag:-hash-de'
  /de/:
    permalink: /de/{slug}/
    template: index-de
    filter: 'tag:hash-de'

```

#### 自定义分类和频道

Taxonomies 是分类，帖子分组。帖子可以出现在多个分类标准中。可以自定义分类标准，可以不分类：

```yaml
taxonomies:
  tag: /topic/{slug}/
  author: /host/{slug}/

```

如果你想要比分类标准更灵活，但又不像集合那么死板的东西，那么可以用channels 。频道是与特定过滤器匹配的分页内容的自定义流。这样，您就可以通过将现有帖子组合或划分为内容中心，创建内容子集和超子集。频道不会影响帖子的 URL 或在网站中的位置，因此帖子可以属于任意数量的频道。将频道视为一组永久搜索结果的最佳方式。它是对整个网站内容的过滤切片，而不会修改内容本身。

```yaml
routes:
  /apple-news/:
    controller: channel
    filter: tag:[iphone,ipad,mac]
  /editors-column/:
    controller: channel
    filter: tag:column+primary_author:cameron

```

#### 可用的路由属性

| Property      | Description                                                                                                                                                                                                                                                                   |
| ------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| template      | 决定此路由将使用哪个 Handlebars 模板文件。如果未指定，默认为 index.hbs 。                                                                                                                                                                                                                              |
| permalink     | 集合中任何帖子的生成 URL。可包含基于帖子数据的动态变量：\- {id} \- 一组唯一的字符，如 5982d807bcf38100194efd67\- {slug} \- 职位标题，例如 my-post\- {year} \- 出版年份，如： 2019 。\- {month} \- 出版月份，如： 04 。\- {day} \- 出版日期，如： 29 。\- {primary\_tag} \- 帖子中列出的第一个标记的标题，如： news 。\- {primary\_author} \- 第一作者的标题，如： cameron 。 |
| filter        | 使用 Ghost Content API 的全部功能和语法，对集合和频道中返回的帖子进行广泛过滤  例如， author:cameron+tag:news 将返回卡梅伦发布的所有帖子，并标记为 "新闻"。根据需要进行混合和匹配。                                                                                                                                                            |
| order         | 为内容选择任意数量的字段和排序顺序：\- published\_at desc \- 默认，最新文章在前\- published\_at asc \- 按时间顺序排列，最早的在前\- featured desc, published\_at desc \- 特写文章，然后是普通文章，最新文章在前                                                                                                                          |
| data          | 从 Ghost API 获取数据并将其与指定路由相关联。数据源路由将重定向到新的自定义路由。\- post.slug \- 用 => {{#post}} 获取数据\- page.slug \- 用 => {{#page}} 获取数据\- tag.slug \- 用 => {{#tag}} 获取数据\- author.slug \- 用 => {{#author}} 获取数据                                                                                  |
| rss           | 可通过将 rss 属性设置为 false 来禁用自动生成的 RSS 源。                                                                                                                                                                                                                                          |
| content\_type | 指定当前路由的 mime 类型，默认值： HTML                                                                                                                                                                                                                                                     |
| controller    | 向路由添加自定义控制器，以执行其他功能。目前唯一支持的值是 channel                                                                                                                                                                                                                                         |

### 自定义主题设置

自定义主题设置由主题开发人员在 `package.json` 文件中的 `config.custom` 键处指定，以便在Ghost Admin设置，有五种自定义主题设置可供选择：`select`、`boolean`、`color`、`image`、 `text`。

```json
{
    "config": {
        "custom": {
            "typography": {
                "type": "select",
                "options": ["Modern sans-serif", "Elegant serif"],
                "default": "Modern sans-serif"
            },
            "cta_text": {
                "type": "text",
                "default": "Sign up for more like this",
                "group": "post",
                "description": "Used in a large CTA on the homepage and small one on the sidebar as well" 
            }
        }
    }
}

```

设置key必须全部小写，不含特殊字符，并以 `snake_case` 表示，其中每个空格用 `_` 表示,如`cta_text`。描述必须少于 100 个字符。

在发布新主题版本时更改设置的key，对于从旧版本升级的网站所有者来说是一个破坏性的更改。使用旧key的设置将被删除，网站所有者输入的任何值也将丢失，而使用当前key的新设置将以其默认值创建。

在 `package.json` 文件中定义后，可在 Handlebars 模板中使用 `@custom` 对象访问自定义设置。

```handlebars
<body class="{{body_class}} {{#match @custom.typography "Elegant serif"}}font-alt{{/match}}">
    ...
    <section class="footer-cta">
        {{#if @custom.cta_text}}<h2>{{@custom.cta_text}}</h2>{{/if}}
        <a href="#portal/signup">Sign up now</a>
    </section>
</body>

```

主题设置属于 "设计与品牌 "中的 "主题 "选项卡，分为三类：Site wide、Homepage、Post，默认情况下，所有自定义设置都显示在全站类别中。针对主页或文章显示的自定义设置可通过可选的 `"group"` 属性进行定义，该属性的值为 `"homepage"` 或 `"post"` 。

#### 自定义字体的支持

自定义字体允许用户从一个精选列表中为自己的主题选择标题和正文字体。选择自定义字体后，Ghost 会通过 `{{ghost_head}}` 在前端加载字体文件，并设置两个 CSS 变量来引用它们：

```html
<link rel="preconnect" href="https://fonts.bunny.net">
<link rel="stylesheet" href="https://fonts.bunny.net/css?family=fira-mono:400,700|ibm-plex-serif:400,500,600">
<style>
  :root {
    --gh-font-heading: Fira Mono;
    --gh-font-body: IBM Plex Serif;
  }
</style>

```

要在主题中使用自定义字体，请在主题的 CSS 文件中应用所提供的变量，如果没有设置自定义字体，可以使用主题自己的字体作为后备：

```css
<style>
  body {
    font-family: var(--gh-font-body, Helvetica);
  }

  h1, h2, h3, h4, h5, h6 {
    font-family: var(--gh-font-heading, var(--theme-font-heading));
  }
</style>

```