# 主题开发教程（10 分钟上手）

配套示例：**`themes/demo/`**。本文用最小结构带你做一个能用的主题。

## 1. 最小主题结构

```
themes/demo/
├── theme.json            # 主题清单（必填）
├── views/
│   └── partials/         # 覆盖公共片段
│       ├── head.blade.php
│       ├── header.blade.php
│       └── footer.blade.php
└── assets/
    └── style.css         # 主题样式（/themes/demo/assets/style.css 访问）
```

**核心机制**：激活主题的 `views/` 目录被前置到全局视图路径。页面视图（`index`/`show`/`list`…）按名字解析——主题有同名视图就用主题的，**没有就自动回退默认视图**（`resources/views/`）。

所以最小主题只需要覆盖 `partials/`（head/header/sidebar/footer），页面样式自己定，其他全部继承默认。

## 2. theme.json

```json
{
    "title": "Demo 演示主题",
    "version": "1.0.0",
    "description": "一句话描述",
    "author": "你的名字",
    "screenshot": "screenshot.png",
    "inject_points": ["head", "header", "footer"]
}
```

- `screenshot`：`assets/` 下的预览图，后台主题卡片展示（可选）
- `inject_points`：声明实现了哪些注入点（后台会展示）；缺省视为全部支持

## 3. 覆盖 partials

`views/partials/head.blade.php` 需要包含：`<title>`、meta、CSS 引用。**必须保留注入点** `@stack('theme:head')`（后台「主题注入」的内容会渲染到这里）：

```blade
<link rel="stylesheet" href="{{ theme('asset', 'style.css') }}">
@stack('head')
@stack('theme:head')
```

`header.blade.php` / `footer.blade.php` 同理，尾部保留 `@stack('theme:footer')` / `@stack('theme:body_end')`。

## 4. 视图解析规则

| 场景 | 结果 |
|------|------|
| 主题有 `index.blade.php` | 覆盖默认首页 |
| 主题没有 | 用 `resources/views/index.blade.php` |
| 主题只有 partials | 页面用默认，公共片段用主题的 |

想完全自定义某类页面，就在主题 views 下放同名文件（如 `show.blade.php`、`tag.blade.php`），控制器传的变量清单见 `docs/themes.md`。

## 5. 主题变量（可后台编辑）

`theme.json` 之外，可以在后台「主题注入 → 主题变量」里给主题加任意键值，视图用：

```blade
{{ theme('var', 'footer_about', '默认文本') }}
```

适合放广告位 HTML、自定义文案等，不用改代码。

## 6. 资产与发布

- **开发期**：`GET /themes/{name}/assets/{path}` 流式返回（带缓存头），改 CSS 刷新即生效
- **生产**：`php artisan theme:publish` 拷贝到 `public/themes/`，由 Web 服务器托管

## 7. 打包与安装

```bash
cd themes/demo && zip -r ../demo.zip . -x ".*"
```

后台「主题管理」→ 上传 ZIP 安装 → 启用。**不能删除当前激活的主题**。

## 8. 好主题的检查清单

- [ ] 移动端适配：`@media (max-width: 768px)` 两栏改单栏（参照 sablog/modern）
- [ ] 语义化 HTML：`<header>/<nav>/<main>/<aside>/<footer>/<article>/<time>`（SEO 关键）
- [ ] 保留全部注入点 `@stack('theme:xxx')`
- [ ] 深色模式可选（modern 有示例）
- [ ] 文章 TOC：`show` 视图接收 `$toc` 变量，样式化 `.toc` / `.toc-level-N`（可选）
- [ ] 截图 `screenshot.png`（无头浏览器截首页生成）

## 常见问题

- **页面还是旧的**：确认主题已启用、文件在 `views/` 下、缓存已清（后台「缓存管理」或 `php artisan view:clear`）
- **CSS 不生效**：检查 `theme('asset', 'style.css')` 路径，生产环境要先 `theme:publish`
- **想参考完整实现**：`themes/sablog/`（经典两栏）、`themes/modern/`（简约 + 深色模式）
