Files
laralog/docs/themes.md
T

152 lines
6.6 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 主题(皮肤)开发指南
## 目录结构
```
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": "screenshot.png",
"inject_points": ["head", "header", "sidebar_top", "sidebar_bottom", "content_top", "content_bottom", "post_content_top", "post_content_bottom", "footer", "body_end"]
}
```
## 视图解析规则
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 服务器托管
## 内容注入点(广告 / 统计 / 临时链接)
主题视图内置 10 个注入点(Blade `@stack`),后台「主题注入」页管理:
| 注入点 | 位置 | 典型用途 |
|--------|------|----------|
| `theme:head` | `</head>` 前 | 统计代码、广告、验证 |
| `theme:header` | 页头下方 | 顶部横幅/公告 |
| `theme:sidebar_top` | 侧边栏顶部 | 首屏广告 |
| `theme:sidebar_bottom` | 侧边栏底部 | 广告/临时链接 |
| `theme:content_top` | 内容区顶部 | 列表/文章上方横幅 |
| `theme:content_bottom` | 内容区底部 | 分页后广告 |
| `theme:post_content_top` | 文章正文前 | 正文顶部广告 |
| `theme:post_content_bottom` | 文章正文后 | 正文底部广告 |
| `theme:footer` | 页脚前 | 版权上方声明 |
| `theme:body_end` | `</body>` 前 | 统计代码 |
特性:
- **同一位置可添加多条**注入块(名称 + HTML + 排序 + 启停),按排序渲染
- 插件可通过 filter `theme.inject.{point}` 追加
- 主题变量(stylevar 复活):后台「主题注入」→「主题变量」Tab,视图用 `{{ theme('var', 'key') }}` 引用任意 HTML
新主题须在对应 partial/视图放置 `@stack('theme:xxx')` 才能接收注入。
**声明注入点**`theme.json``inject_points` 声明主题实现了哪些注入点(缺省视为全部支持),后台主题卡片会展示,切换主题时一目了然。
**多注入排序**:同一位置可添加多条,后台「主题注入」页按列表拖拽排序,保存后按顺序渲染。
## 预览图
`theme.json``screenshot` 指向 `assets/` 下的预览图(如 `screenshot.png`),后台主题管理以卡片形式展示。可用无头浏览器截图生成:`node` + playwright 打开站点首页保存为 `themes/{name}/assets/screenshot.png`
## 移动端适配
主题 CSS 需自带 `@media (max-width: 768px)` 断点:容器改全宽、两栏改单栏、导航换行。内置 sablog / modern 已实现,新主题请参照。
## TOC 目录
文章页自动为 Markdown 正文提取目录(h2-h6 生成锚点 + 折叠目录块)。主题需在 show 视图接收 `$toc` 变量并按 `.toc` / `.toc-level-N` 类样式化,或自行实现。
## 社交账号
后台「博客设置 → 社交账号」配置微博/知乎/B站/小红书/抖音/视频号/公众号/GitHub/X/Facebook/邮箱 + 自定义其他平台。数据经 `$socialLinks` 共享给所有前台视图(侧边栏可展示),URL 类账号同时输出到 JSON-LD `sameAs`
## 打包与安装
- 目录打成 ZIP(根目录含 theme.json),后台「主题管理」上传安装,或远程市场安装
- 不能删除当前激活的主题