---
url: https://docs.zblogcn.com/php/dev-theme.md
description: 介绍 Z-BlogPHP 主题的文件结构、模板文件与保留模板、模板语法标签及编译机制，以及缩略图等模板功能的调用方法。
---

# 主题开发

Z-BlogPHP 主题控制网站的前台展示。本篇介绍主题的文件结构、模板文件、模板语法标签及编译机制，以及缩略图等模板功能的调用方法。

## 文件结构（主题）

以下基于通过「[创建应用](/php/dev-start#创建应用 "创建应用")」生成的初始文件：

```text
/path/zb_users/theme/demoTheme
│  screenshot.png [必需]缩略图 320*240像素, 横向；
│  theme.xml      [必需]自述文件；
│  main.php       [可选]应用内置管理页，在创建主题时填写才会生成；
│  include.php    [可选]应用嵌入页，在创建主题时填写才会生成；
│
├─include         [可选]主题自带「文件模块」，使用{module:abc}「嵌入调用」该目录下的abc.php文件；
├─script          [可选]JS目录；
├─style           [必需]样式目录, 内存样式表及所需图片；
│      style.css  [必需]不限于这个文件名，一套主题也可以拥有多个样式（各自独立使用）；
│
├─css             [可选]并不会自动创建，用于不应该放在style文件夹中的样式内容；
└─template        用于存放模板文件；建议优先确立以下 6 个模板文件及内容；
       index.php  首页及列表页
       single.php 文章页(单页)
       search.php 搜索结果页，不存在时使用index.php
       header.php 公共头部文件
       footer.php 公共尾部文件
       404.php    建议设置
└─template.json   [可选]模板文件描述信息；
```

## 主入口模板

默认情况下，系统只会尝试直接调用`index.php`、`single.php`、`search.php`、`404.php`四个模板文件（如果存在的话）；

其他模板则通过「嵌入调用」组合其自身内容到「主模板」之中；

### 示例

* 理论上可以直接使用如下示例作为四个「主模板」文件的基础结构；**「`Your Code`部分除外」**；
* `{template:header}` `{template:footer}` `{template:sidebar}` 为「Z-BlogPHP 体系内」常用模板，`{template:hero}`则可自由命名，用于拆分相应位置的代码；「[模板书写 - 嵌入调用](/php/dev-theme#嵌入调用 "模板书写 - 嵌入调用")」
* 关于「模板描述信息」「嵌入调用」「变量输出标签」等部分的详情，参见：「[模板书写](/php/dev-theme#模板书写 "模板书写")」

```html
{* Template Name: 首页及列表页 * Template Type: index|list *}
<!-- ↑ 「模板描述信息」，包括适配的「页面类型」，放在模板文件第一行 -->
<!DOCTYPE html>
<html lang="{$language}"><!-- {$language} 为「变量输出标签」 -->

<head>
  {template:header}<!-- 公共头部文件 -->
</head>

<body class="{$type}"><!-- 同为「变量输出标签」，对应上方 Template Type -->
  {template:hero}
  <!-- ↓Your Code↓ -->
  <!-- ↓Your Code↓ -->
  <nav id="divNavBar">
    <!-- 导航「模块」调用 -->
    <ul>{module:navbar}</ul>
  </nav>
  <main id="divMiddle">
    <div id="divMain">列表索引或正文内容</div>
    <!-- 「侧栏」调用 -->
    <div id="divSidebar">{template:sidebar}</div>
  </main>
  <!-- ↑Your Code↑ -->
  <!-- ↑Your Code↑ -->
  {template:footer}<!-- 公共尾部文件 -->
</body>

</html>

```

## 模板文件及缺省机制

* 因为「保留模板」机制，当主题未提供某一模板文件时，系统会从`zb_system/defend/default`中读取使用；「[在线查看](https://github1s.com/zblogcn/zblogphp/blob/HEAD/zb_system/defend/default/index.php "zb_system/defend/default")」
* 因此可以缺省部分不需要自定义内容结构的模板文件，尤其是「[侧栏模块相关](/php/dev-theme#侧栏模块相关模板 "侧栏模块相关")」的部分；

### 页面公共模板文件

| 模板文件   | 说明         |
| ---------- | ------------ |
| header.php | 公共头部文件 |
| footer.php | 公共尾部文件 |

### 首页与列表页相关模板

| 模板文件       | 说明                   |
| -------------- | ---------------------- |
| index.php      | 首页及列表页主模板文件 |
| post-multi.php | 摘要文章模板           |
| post-istop.php | 置顶文章模板           |
| pagebar.php    | 页码模板               |

### 日志/独立页相关模板

| 模板文件               | 说明                       |
| ---------------------- | -------------------------- |
| single.php             | 文章页(单页)主模板文件     |
| post-single.php        | 日志页文章模板             |
| post-page.php          | 独立页面模板               |
| comments.php            | 评论区模板                 |
| comment.php           | 每条评论内容显示模板       |
| commentpost.php        | 评论发送表单模板           |
| commentpost-verify.php | 评论验证码模板（1.5 新增） |

### 侧栏模块相关模板

* 模块展现外框架模板

| 模板文件    | 说明                                                                   |
| ----------- | ---------------------------------------------------------------------- |
| sidebar.php | 默认侧栏模板，可自定义 `sidebar2.php`~`sidebar9.php` 用于后续侧栏调用  |
| module.php  | 模块显示模板，可定义模块标题等格式，模块具体内容格式由下列细节模板决定 |

* 模块内容细节模板（1.5 版本及以上）

| 模板文件              | 说明             | 备注（默认列表行数） |
| --------------------- | ---------------- | -------------------- |
| module-archives.php   | 文章归档模块     | 没有限制             |
| module-authors.php    | 作者列表模块     | 没有限制             |
| module-calendar.php   | 日历模块         | 没有限制             |
| module-catalog.php    | 分类列表模块     | 没有限制             |
| module-navbar.php     | 导航条模块       | 没有限制             |
| module-statistics.php | 站点信息模块     | 没有限制             |
| module-comments.php   | 最近评论列表模块 | **10**条             |
| module-previous.php   | 最近文章列表模块 | **10**条             |
| module-tags.php       | 标签列表模块     | **25**条             |

## 模板书写

### template.json 配置（1.7.0 以后支持）

对主题模板文件添加描述信息，在网站 `\zb_users\theme\主题ID\` 文件夹下创建 template.json：

```json
{
    "id": "主题ID",
    "templates": [
        {
            "filename": "index",
            "type": "list",
            "name": "列表自动模板"
        },
        {
            "filename": "single",
            "type": "single",
            "name": "文章/单页自动模板"
        }
    ]
}
```

`type` 类型取值：

```plain
- index           首页
- list            列表页
  - author        作者页
  - category      分类页
  - date          时间页
  - tag           标签页
- single          单页面（含文章与页面）
  - article       文章页
  - page          单页页面页
- search          搜索
- 404             404
- none            显示设置隐藏
```

### 描述信息（可选）

放在模板文件第一行：

```plain
{* Template Name:「模板用途描述」 *}
```

可以同时声明模板类型（针对「主入口模板」），`type` 取值同上：

```plain
{* Template Name: 首页及列表页 * Template Type: index|list *}
```

**注：「描述信息」和「类型声明」的必要性仅体现在`同一「页面类型」有多个「入口模板」可供用户选择`时的选项输出，或者`针对不同「页面类型」细化建立了不同的模板文件`。对于后者需要自行实现判断调用，或引导用户选择设置。**

**重要：在`{}`内部，`*`与其他内容之间要有空格；**

### 嵌入调用

* 嵌入模板文件

  `{template:hearder}` - 嵌入模板文件 hearder.php 的文件内容。

  * 「[嵌入调用示例](#%e7%a4%ba%e4%be%8b "嵌入调用示例")」

* 嵌入模块内容

  `{module:navbar}` - 嵌入「`导航栏`模块」

  * 「模块」或者说「侧栏模块」，一般是指 **「后台管理」→`模块管理`** 中列出的项目；
  * `navbar`为「`导航栏`模块」的「filename(文件名)」，其他「模块」同理；

  **注：除`include`文件夹内的「文件模块」外其他模块其实是存在数据库的，另外不建议使用「文件模块」，主题更新时用户修改的内容会被覆盖。**

### 模板标签

在「[模板文件示例](#%e7%a4%ba%e4%be%8b "模板文件示例")」示例中使用了`{$language}`和`{$type}`两个语法标签，称为「变量输出标签」或「模板标签」，实际会编译为`<?php echo $language;?>`和`<?php echo $type;?>`来输出对应变量的值；

在 Z-BlogPHP 模板中，可通过`{$var}`、`{$obj.a}`来输出「文本或数字类型」的「变量或对象属性」，其中后者会编译为`<?php echo $obj->a;?>`；

**系统内定义的「模板标签列表」请点击右边链接查看：「[Z-BlogPHP 模板标签手册](./../../markup/index.html "Z-BlogPHP 模板标签手册")」；**

**注：**

1. 部分标签只能在特定的页面类型（`$type`取值）或上下文中才能使用；
2. `{module:navbar}`可视为`{$modules["navbar"].Content}`的简写语法；
3. 除系统标签外，可通过「接口机制」或「原生 PHP 语法①」自定义或修改作为标签输出的变量；

→①：[模板内使用 PHP](#%e6%a8%a1%e6%9d%bf%e5%86%85%e4%bd%bf%e7%94%a8-php "模板内使用 PHP")；

### 文章图片与缩略图

系统内置了缩略图基类，可通过以下模板标签获取文章图片：

**获取文章第一张原图**

```php
{$article.AllImages[0]}
```

返回文章中第一张图片的 URL。

**获取文章图片总数**

```php
{$article.ImageCount}
```

返回 `$article.AllImages` 数组的计数。

**获取文章缩略图**

```php
{$article.Thumbs(640, 360, 1, false)[0]}
```

参数说明：

* `640` — 缩略图宽度（像素）
* `360` — 缩略图高度（像素）
* `1` — 裁剪模式（0=按比例缩放，1=裁剪填充）
* `false` — 是否强制重新生成（true=强制重新生成，false=使用缓存）
* `[0]` — 取第一张图片的缩略图

**PHP 代码调用方式**

```php
{php}
// 获取文章所有图片
$images = $article->AllImages;

// 生成缩略图（宽度 640，高度 360，裁剪模式，使用缓存）
$thumbs = $article->Thumbs(640, 360, 1, false);
$thumbUrl = $thumbs[0]; // 第一张图的缩略图地址
{/php}
```

**注意事项**

1. 缩略图功能需要 GD 库支持；
2. 1.7.4 版本起支持 `webp` 和 `avif` 格式，可提高图片加载速度；
3. 如果文章没有图片，`$article.AllImages` 返回空数组，使用前建议判断：

```php
{if $article.ImageCount > 0}
  <img src="{$article.Thumbs(640, 360, 1, false)[0]}" alt="{$article.Title}">
{/if}
```

### 模板内使用 PHP

在相应内容输出前，可以使用如下语法额外对数据进行处理；

```php
{php}
// 这里可以写原生 PHP；
$myVar = "变量值";
{/php}
<p>输出一个自定义变量：{$myVar}</p>
<p>当前 Z-BlogPHP 版本是：{$version}</p>

//还可以用<?php ?>符号在{php}{/php}里以实现代码高亮
{php}<?php

//原生php代码

?>{/php}
```
