# {{主题名}}主题 · 部署文档（模板）

> 版本 {{x.y.z}} ｜ 最后更新：{{YYYY-MM-DD}}
> 适用对象：把本主题部署到新 WordPress 站点（本地 → 生产）的运维 / 开发人员。
>
> **职责**：说明主题怎么装、装完必须配什么、服务器要注意什么、出问题怎么查——交付给运维/他人时随主题一起给。
> **来源**：本技能包自带的部署文档模板（结构：环境 → 安装 → 必做配置 → 目录结构 → 样式构建 → 服务器注意 → 上线清单 → 排错），业务内容已换成占位符。
> **落地位置**：新主题根目录 `部署文档.md`（文件名去掉「模板」两字）。
>
> **复制后必须改的地方**：
> TODO 1. 把全部 `{{占位符}}` 替换为本项目真实内容；用不到的小节整段删除，不要留空标题。
> TODO 2. 按实际主题补全「一、主题概览」与「五、目录结构」，删掉不存在的文件行。
> TODO 3. 「四、安装后必须完成的配置」里的常量表要与 `inc/config.php` 逐项对齐（名称、默认值、含义）。
> TODO 4. 「八、上线检查清单」要保留可勾选的 `- [ ]` 形式，并把占位条目换成本项目的真实验证步骤。
> TODO 5. 本文件**不得写入任何真实密钥**，只写常量名与取值方式。

---

## 一、主题概览

{{一句话说明这个主题做什么}}（经典 PHP 主题，非 FSE / 区块主题）。

| 能力 | 说明 |
| --- | --- |
| {{能力 1}} | {{说明}} |
| {{能力 2}} | {{说明}} |
| 文章系统 | {{列表卡片 / 面包屑 / 侧栏模块 / 分类标签归档 / 搜索，按实际填写}} |
| SEO | {{哪些标签交给 SEO 插件，哪些由主题补齐}} |

**不依赖**：{{WindPress 等 Tailwind 插件}}——样式是**预编译产物**，随主题分发。
**凭证要求**：{{需要哪些密钥，从哪里获取}}。

---

## 二、环境要求

| 项目 | 要求 | 说明 |
| --- | --- | --- |
| WordPress | ≥ {{6.5}}（实测 {{版本}}） | {{用到哪些较新的 API}} |
| PHP | ≥ {{7.4}}（实测 {{8.2}}） | 主题不使用 PHP 8 专有语法 |
| PHP 扩展 | {{mbstring（必需）}}、{{curl}}、{{gd}} | {{分别用在哪}} |
| 数据库 | MySQL 5.5.5+ / MariaDB | 与 WordPress 要求一致 |
| Web 服务器 | nginx 或 Apache | nginx 有若干注意事项，见第七节 |
| Node / npm | **仅构建期需要**，生产不需要 | 产物 `assets/css/tailwind.css` 随主题分发 |

---

## 三、安装

### 方式 A：后台上传（推荐）

1. 后台 →「外观 → 主题 → 安装主题 → 上传主题」，选择 `{{主题目录名}}-v{{x.y.z}}.zip`，安装并**启用**。
2. zip 内已含预编译样式，安装后前台即有完整样式，无需任何构建步骤。

### 方式 B：手动解压

把 zip 解压到 `wp-content/themes/`，确认得到 `wp-content/themes/{{主题目录名}}/`（**顶层目录必须是 `{{主题目录名}}`**），然后后台启用。

> ⚠️ 若这个 zip 来自他人：`inc/config.php` 可能含密钥。公开分发前先替换为自己的凭证，见 4.1。

---

## 四、安装后必须完成的配置

### 4.1 密钥与接口配置（**最关键**）

主题默认值是占位值（`{{占位值示例}}`），**必须**改成生产值，否则 {{相关功能}} 调用失败。

**推荐把配置写进 `wp-config.php`**——`inc/config.php` 里每个常量都用 `defined()` 保护，先在 `wp-config.php` 定义即可覆盖主题默认值，这样密钥不进主题目录，也不怕主题升级被覆盖：

```php
/* {{主题名}}主题配置（放在 wp-config.php 的 "stop editing" 注释之前） */
define( '{{PREFIX}}_API_BASE', '{{https://api.你的域名}}' );   // 结尾不要带 /
define( '{{PREFIX}}_APP_ID', '{{YOUR_APP_ID}}' );
define( '{{PREFIX}}_APP_SECRET', '{{YOUR_APP_SECRET}}' );
```

也可以直接改 `inc/config.php`（适合只有一套环境的场景）。全部可配置项：

| 常量 | 默认 | 含义 |
| --- | --- | --- |
| `{{PREFIX}}_API_BASE` | `{{占位值}}` | 上游 API 基址（不带结尾斜杠） |
| `{{PREFIX}}_APP_ID` | `{{占位值}}` | 公开标识，参与签名 |
| `{{PREFIX}}_APP_SECRET` | `{{占位值}}` | **仅服务端使用，严禁下发前端** |
| `{{PREFIX}}_CACHE_TTL` | `{{600}}` | 服务端缓存秒数 |
| `{{PREFIX}}_RATE_WINDOW` | `{{60}}` | 限流窗口（秒） |
| `{{PREFIX}}_RATE_RULES` | `{{write 5 / read 60}}` | 每 IP 在窗口内的最大请求数 |
| `{{PREFIX}}_PROXY_IP_HEADER` | 空 | 真实访客 IP 的请求头。**站点在 CDN 之后时必须填 `HTTP_CF_CONNECTING_IP`（Cloudflare）或 `HTTP_X_FORWARDED_FOR`（通用反代）**；留空则按 `REMOTE_ADDR` 限流，CDN 后会导致全站共用一个限流桶 |
| `{{PREFIX}}_TIMEOUT` | `{{20}}` | 普通接口超时（秒） |
| `{{PREFIX}}_TIMEOUT_LONG_POLL` | `{{40}}` | 长轮询超时（秒），**必须大于上游挂起时长**；无此接口时删除 |

配置后验证：{{打开某页面执行某操作，看到什么结果即表示成功}}。

### 4.2 阅读设置

1. 新建页面：{{「首页」（slug 建议 `home`）}}与{{「文章」（slug 建议 `articles`）}}，内容留空。
2. 「设置 → 阅读」→ 选择「一个静态页面」，**主页**选{{「首页」}}，**文章页**选{{「文章」}}。

> 说明：{{首页由 front-page.php 渲染，页面自身内容不显示}}；未指定文章页时，导航里的「文章」链接会自动隐藏（不会报错）。

### 4.3 固定链接

`设置 → 固定链接` 任选一种。若结构**不含** `index.php`（例如 `/archives/%postname%/`），需要服务器做 WordPress 重写（nginx 示例见 7.1）。

### 4.4 内容与分类

- 文章：建议每篇都设**特色图片**（列表卡片封面）与**摘要**（列表与 meta description 都取它）。
- 分类 / 标签：{{建好后各术语的 SEO 数据在哪里填写}}。

### 4.5 SEO

1. 安装并启用 `{{SEO 插件名}}`（主题不重复输出该插件已负责的标签，二者必须分工，见 6.3）。
2. {{首页 / 关键页面的 SEO 标题、元描述、焦点关键词在哪里填}}。
3. **换域名后**：{{重新索引步骤}}；随后检查 `/sitemap_index.xml` 中的域名是否已更新。
4. 归档收录策略：{{分类与标签默认 index；搜索页与 404 由插件自动 noindex}}。

---

## 五、目录结构

```
{{主题目录名}}/
├── style.css                    只放主题头（真实样式在 assets/css/）
├── functions.php                主题入口：常量、加载 inc、资源入队、{{{按需}关闭 WindPress 前台运行时}}
├── front-page.php               首页{{（类型）}}
├── header.php / footer.php      页头（含 <main> 开标签）/ 页脚（闭合 <main>）
├── home.php / archive.php / search.php / index.php
│                                文章列表 / 归档 / 搜索 / 兜底（共用 template-parts/post-list.php）
├── single.php                   文章详情（面包屑 + 正文 + 标签 + 上下篇 + 侧栏 + 评论）
├── page.php / 404.php           单页 / 404
├── searchform.php               搜索表单
├── comments.php                 评论区（列表 + 分页 + 空态 + 表单）
├── template-parts/
│   ├── post-list.php            列表片段（网格卡片 + 分页 + 空态）
│   └── {{related-posts.php}}    {{侧栏模块}}
├── inc/
│   ├── config.php               集中配置层（所有常量，支持 wp-config.php 覆盖）
│   ├── class-{{api-client}}.php {{上游 API 客户端}}
│   ├── {{rest-api.php}}         {{REST 转发（校验 + 限流 + 过滤）}}
│   ├── {{seo.php}}              {{SEO 补齐}}
│   └── comments.php             评论区渲染与表单（回调、头像、评论数、表单字段）
├── assets/
│   ├── css/tailwind.css         ★ 预编译样式产物（Tailwind 4 + daisyUI 5，勿手改）
│   ├── css/theme.css            少量自定义样式（正文排版、分页外观等）
│   ├── css/src/main.css         Tailwind 构建入口
│   ├── js/{{main.js}}           {{前端脚本}}
│   └── img/                     {{图标 / favicon}}
├── package.json                 样式构建脚本（仅开发期需要 Node）
├── screenshot.png               后台主题缩略图（1200×900）
└── 部署文档.md                  本文件
```

**REST 接口**（命名空间 `{{mytheme}}/v1`，是否需登录：{{}}，是否限流：{{}}）：

| 路由 | 方法 | 用途 |
| --- | --- | --- |
| `/wp-json/{{mytheme}}/v1/{{route-1}}` | {{POST}} | {{用途}} |
| `/wp-json/{{mytheme}}/v1/{{route-2}}` | {{GET}} | {{用途}} |

返回约定：{{统一结构，例如 {code, msg, data}，各 code 含义}}。

---

## 六、样式与构建

### 6.1 样式是预编译产物（部署与运行都不需要 Node）

`assets/css/tailwind.css` 已随主题分发，部署和运行都**不需要** Node/npm，也**不需要**装 WindPress。

### 6.2 修改样式后必须重新构建

改了模板 / 脚本里的 **Tailwind 类名**（或 `assets/css/src/main.css` 的 `@source`）后，要在**开发机**重新构建，再把新的 `assets/css/tailwind.css` 一起上传：

```bash
cd wp-content/themes/{{主题目录名}}
npm install          # 首次
npm run build:css    # 生成 assets/css/tailwind.css（带 --minify，上线用这个）
npm run watch:css    # 开发期监听；产物未压缩，不要拿去上线
```

自定义样式（不涉及 Tailwind 类名）直接写 `assets/css/theme.css`，无需构建。

### 6.3 与 SEO 插件的分工（重要，不要重复输出）

- **插件负责**：`<title>`、`meta description`、`rel=canonical`、`meta robots`、Open Graph、Twitter Card、JSON-LD、sitemap、robots.txt。
- **主题负责**：{{主题自己输出的标签，例如 meta keywords、图片 alt 回退、RSS、canonical 修正}}。
- 因此：**不要在主题里再加 description / OG / canonical**，同页两套声明会互相冲突。

---

## 七、Web 服务器注意事项（重点）

### 7.1 nginx

1. **长轮询 / 慢接口超时**：{{哪个接口会挂起多久}}，务必保证 `fastcgi_read_timeout` ≥ {{60}} 秒（宝塔默认 300 秒，通常无需改）：
   ```nginx
   fastcgi_read_timeout 300s;
   ```
2. **REST 路径不要被拦**：`/wp-json/` 与 `/index.php/wp-json/` 必须放行；若配了 WAF / 限流，请把上表的 REST 路由加入白名单，否则会误伤业务功能。
3. **404 页面坑位**：若 vhost 里写了 `error_page 404 /404.html;` 且 `fastcgi_intercept_errors on;`，WordPress 的 404 页面会被 nginx 的静态页顶掉（主题的 `404.php` 与 SEO 插件的 404 noindex 都不生效）。想用主题 404 页就注释掉这两行。
4. **伪静态**：固定链接不含 `index.php` 时需加：
   ```nginx
   location / { try_files $uri $uri/ /index.php?$args; }
   ```
5. **静态资源缓存建议**（可选）：对 `/wp-content/themes/{{主题目录名}}/assets/` 下的 css/js/img 设置较长 `expires`；主题已用 `filemtime()` 做版本号，改文件后 URL 自动变化，不会读到旧缓存。
6. **CDN / 反向代理（重要，否则限流会掐断核心功能）**：站点在 Cloudflare 等 CDN 之后时，源站看到的 `REMOTE_ADDR` 是 CDN 节点 IP，所有访客会共用一个限流桶。必须在 `wp-config.php`（或 `inc/config.php`）把 `{{PREFIX}}_PROXY_IP_HEADER` 设为 `HTTP_CF_CONNECTING_IP`（Cloudflare）或 `HTTP_X_FORWARDED_FOR`（通用反代）。验证方法：配好后用两个不同访客 IP 各自请求 {{N+1}} 次，第二个 IP 的前 {{N}} 次应仍然通过。

### 7.2 Apache

`.htaccess` 由 WordPress 自动生成即可；无需额外配置。

---

## 八、上线检查清单

- [ ] 主题已启用，后台「外观 → 主题」能看到预览图（screenshot.png）
- [ ] `wp-config.php`（或 `inc/config.php`）已改成**生产**的地址与凭证，且没有残留 `YOUR_` / `example.com` 之类的占位值
- [ ] {{核心功能 1 的端到端验证步骤与预期结果}}
- [ ] {{核心功能 2 的端到端验证步骤与预期结果}}
- [ ] 「设置 → 阅读」已指定静态首页与文章页，导航链接可点
- [ ] 文章列表显示封面图与摘要；文章详情有面包屑、上下篇与侧栏模块
- [ ] 分类 / 标签归档可访问，搜索可用，404 页面显示主题样式（不是服务器默认页）
- [ ] 每页 `<h1>` 有且只有一个（浏览器控制台执行 `document.querySelectorAll('h1').length`）
- [ ] SEO 插件已启用；首页 `<title>` / `description` / `canonical` 正确（查看页面源代码）
- [ ] `/sitemap_index.xml` 与 `/robots.txt` 可访问且域名正确
- [ ] 手机端无横向滚动条、无 JS 报错（F12 控制台）
- [ ] nginx：超时充足、REST 路径未被拦截、CDN 取 IP 的请求头已配置

---

## 九、常见问题排查

| 现象 | 排查方向 |
| --- | --- |
| 前台完全没有样式 | 确认 `assets/css/tailwind.css` 存在（正常约 {{66–71}} KB）；缺失时重新上传或用 `npm run build:css` 重建 |
| 单个新类名不生效 | 忘了 `npm run build:css`；或该类名写在未被 `@source` 覆盖的目录；或由 JS 动态拼接而非字面量 |
| 接口报错 / 拿不到数据 | ① 基址是否正确（不能带结尾斜杠）；② 服务器能否访问该地址（`curl` 测试）；③ 凭证是否有效；④ 看上游返回的错误码含义 |
| 提示「请求过于频繁」 | ① `{{PREFIX}}_PROXY_IP_HEADER` 是否按「站点是否在 CDN 之后」配置正确；② 同一出口 IP 下同时开很多标签页会吃满配额；③ 等一个窗口或调 `{{PREFIX}}_RATE_RULES` |
| {{业务特有现象}} | {{排查方向}} |
| favicon 还是旧的 | 浏览器强缓存，Ctrl+F5 或清缓存 |
| 改了模板类名样式没变 | 需要在开发机执行 `npm run build:css`，并把新的 `assets/css/tailwind.css` 一起上传 |

---

## 十、升级与回滚

- **升级**：备份数据库与旧主题目录 → 上传新 zip 覆盖（后台上传会提示「替换现有版本」）→ 清一次浏览器缓存验证。
  `inc/config.php` 若被覆盖，请确认生产凭证仍在（**推荐把凭证写在 `wp-config.php`**，就不会被覆盖）。
- **回滚**：恢复 `wp-content/themes/{{主题目录名}}/` 目录即可；数据库层面主题只写自身数据（文章 / 页面 / 选项），不会锁死站点。
- 主题停用后前台切回其它主题；恢复启用即回到本主题页面。

---

## 十一、安全须知

1. `app_secret` 只存在服务端（`wp-config.php` 或 `inc/config.php`），**不要**发给前端、不要写进 JS、不要提交进公开仓库。
2. 打包分发的 zip 若内含凭证 → 不要在公开渠道分发；一旦外流，请立刻在上游 API 侧重置 `app_secret`。
3. {{公开接口的安全措施：参数白名单校验 + IP 限流}}；访问量大时建议再叠加 nginx 层面的 `limit_req`。
4. {{第三方内容（如富文本邮件 / 用户投稿）的隔离措施：服务端白名单过滤 + 前端 sandbox iframe}}。
5. 本部署文档**不要**写入任何真实密钥，只写常量名与取值方式。
