feat: 前台 .shtml 后缀 canonical + strict_types 全量启用 + 对外 API(Sanctum+Scramble 文档)+ pm2 ecosystem + GitHub Actions CI + 插件/主题/架构/API 文档 + REDIS_PREFIX 说明
This commit is contained in:
+106
@@ -0,0 +1,106 @@
|
||||
# 主题(皮肤)开发指南
|
||||
|
||||
## 目录结构
|
||||
|
||||
```
|
||||
themes/{name}/
|
||||
├── theme.json # 主题清单(必填)
|
||||
├── views/ # Blade 视图(激活后前置到全局视图路径)
|
||||
│ ├── partials/ # head / header / sidebar / footer 等公共片段
|
||||
│ ├── index.blade.php
|
||||
│ ├── show.blade.php
|
||||
│ ├── list.blade.php
|
||||
│ └── ... # 缺省视图自动回退默认主题(resources/views/)
|
||||
└── assets/ # CSS / JS / 图片(/themes/{name}/assets/... 访问)
|
||||
```
|
||||
|
||||
## theme.json
|
||||
|
||||
```json
|
||||
{
|
||||
"title": "主题标题",
|
||||
"version": "1.0.0",
|
||||
"description": "主题描述",
|
||||
"author": "作者",
|
||||
"screenshot": null
|
||||
}
|
||||
```
|
||||
|
||||
## 视图解析规则
|
||||
|
||||
1. 激活主题的 `views/` 目录被**前置到全局视图路径**
|
||||
2. 页面视图用 `@include('partials.header')` 等**按名字解析** → 主题有同名 partial 就用主题的,否则用默认主题的
|
||||
3. 页面视图同理:主题提供 `index.blade.php` 则覆盖默认首页,否则用 `resources/views/index.blade.php`
|
||||
|
||||
所以做一个新皮肤通常只需要:`theme.json` + `assets/style.css` + 覆盖 `partials/`(head/header/sidebar/footer)+ 需要特别定制的页面视图。
|
||||
|
||||
## 布局结构(约定)
|
||||
|
||||
### 默认主题(resources/views/)
|
||||
|
||||
```blade
|
||||
@include('partials.head') {{-- <head> 含 SEO meta --}}
|
||||
<body>
|
||||
@include('partials.header') {{-- 站点头 --}}
|
||||
<div class="container main-layout"> {{-- 两栏容器 --}}
|
||||
<main class="content">...页面内容...</main>
|
||||
@include('partials.sidebar') {{-- 侧边栏(自动获得共享数据) --}}
|
||||
</div>
|
||||
@include('partials.footer') {{-- 页脚(含备案号) --}}
|
||||
</body></html>
|
||||
```
|
||||
|
||||
### sablog 主题(两栏经典风)
|
||||
|
||||
```blade
|
||||
@include('partials.head')
|
||||
<body>
|
||||
@include('partials.header') {{-- 打开 <div id="outmain"> + header,自闭合 --}}
|
||||
<div id="page"> {{-- 页面视图自己开闭 #page --}}
|
||||
<div id="content">...内容...</div>
|
||||
@include('partials.sidebar')
|
||||
</div>{{-- #page --}}
|
||||
@include('partials.footer') {{-- <div id="footer"> + 关闭 #outmain --}}
|
||||
</body></html>
|
||||
```
|
||||
|
||||
> 关键约定:**header 打开的容器由页面视图自闭合,footer 只负责自己打开的内容**。避免把 footer 渲染进 flex 容器导致错位(历史教训)。
|
||||
|
||||
## 页面视图清单(控制器会传的数据)
|
||||
|
||||
| 视图 | 控制器 | 变量 |
|
||||
|------|--------|------|
|
||||
| `index` | HomeController | `$posts`(分页) |
|
||||
| `show` | PostController | `$post, $comments, $contentHtml` |
|
||||
| `list` | Category/Archive | `$posts, $category? / $archiveTitle?` |
|
||||
| `archives` | ArchiveController | `$archives` |
|
||||
| `tags` | TagController | `$tags` |
|
||||
| `tag` | TagController | `$tag, $posts` |
|
||||
| `search` | SearchController | `$posts, $keyword` |
|
||||
| `links` | LinkController | `$links` |
|
||||
| `comments` | CommentController | `$comments` |
|
||||
| `login` / `register` / `profile` | AuthController | — |
|
||||
| `membership.index` / `membership.mine` | 会员插件 | `$plans / $subscriptions` |
|
||||
| `payments.sandbox` / `payments.result` | 支付插件 | `$payment` |
|
||||
|
||||
## 侧边栏共享数据(SidebarComposer 自动注入所有前台视图)
|
||||
|
||||
`$categories`、`$recentPosts`、`$recentComments`、`$hotTags`、`$links`、`$blogStats`、`$siteName`、`$siteDescription`、`$siteIcp`
|
||||
|
||||
## 主题辅助函数
|
||||
|
||||
```blade
|
||||
{{ theme('asset', 'style.css') }} {{-- 主题资产 URL --}}
|
||||
{{ theme('var', 'key', '默认值') }} {{-- 主题变量(后台可编辑) --}}
|
||||
{{ theme('name') }} {{-- 当前主题名 --}}
|
||||
```
|
||||
|
||||
## 资产
|
||||
|
||||
- 开发期:`GET /themes/{name}/assets/{path}` 流式返回(带缓存头)
|
||||
- 生产:`php artisan theme:publish` 复制到 `public/themes/`,由 Web 服务器托管
|
||||
|
||||
## 打包与安装
|
||||
|
||||
- 目录打成 ZIP(根目录含 theme.json),后台「主题管理」上传安装,或远程市场安装
|
||||
- 不能删除当前激活的主题
|
||||
Reference in New Issue
Block a user