Initial baseline: LaraBlog core with plugin commerce surface.
Captures the current working tree after theme slots, ArticleAccess, and the payment / paid-content plugins so subsequent work has a reviewable git history.
This commit is contained in:
+116
@@ -0,0 +1,116 @@
|
||||
# 皮肤(主题)开发指南
|
||||
|
||||
## 目录格式
|
||||
```
|
||||
themes/{slug}/
|
||||
theme.json # 元数据
|
||||
assets/ # 静态资源(CSS/图片/预览)
|
||||
style.css
|
||||
preview.svg # 后台卡片预览(建议 16:10)
|
||||
views/ # Blade,命名空间 theme::
|
||||
layout.blade.php
|
||||
home.blade.php
|
||||
article.blade.php
|
||||
...
|
||||
```
|
||||
|
||||
### theme.json 示例
|
||||
```json
|
||||
{
|
||||
"name": "my-theme",
|
||||
"title": "我的皮肤",
|
||||
"version": "1.0.0",
|
||||
"description": "说明文字",
|
||||
"slots": "*"
|
||||
}
|
||||
```
|
||||
|
||||
### 必须声明 `slots`
|
||||
皮肤应在 `theme.json` 声明支持的注入槽(后台「皮肤」卡片会校验):
|
||||
|
||||
| 写法 | 含义 |
|
||||
|---|---|
|
||||
| `"slots": "*"` 或 `"all"` | 支持全部标准槽(推荐) |
|
||||
| `"slots": ["head", "sidebar", "my_slot"]` | 显式列表;可混用 `"*"` 再加自定义槽 |
|
||||
| 省略 `slots` | **不合规**:后台标「未声明」;启用时警告 |
|
||||
|
||||
校验还会扫 `views/**/*.blade.php` 里的 `@themeslot` / `ThemeSlot::render`(非 default 主题会把未覆盖的 default 视图算进有效槽)。声明了但视图未调用 →「声明与视图不一致」。
|
||||
|
||||
## 视图约定
|
||||
- 使用 `@extends('theme::layout')`
|
||||
- 控制器传:`$articles` / `$article` / `$categories` / `$settings` / `$seo`
|
||||
- 静态资源 URL:`app(ThemeManager::class)->assetUrl('style.css')` → `/themes/{slug}/style.css`
|
||||
- 文案:`__('frontend.nav.home')` 等,勿写死中英文
|
||||
|
||||
## 内容注入点(ThemeSlot)
|
||||
|
||||
主题应在固定位置调用 `@themeslot('槽名')`(或 `ThemeSlot::render('槽名')`)。
|
||||
插件与后台「注入 / 广告 / 统计」都会写入同一套槽。
|
||||
|
||||
### 同一位置可多条
|
||||
`Hook::gather('theme.{slot}')` 会按注册顺序把**后台片段 + 各插件**拼成一段 HTML。
|
||||
同一槽塞 3 个插件广告 + 后台一段,都会出来(纵向叠放,由主题 CSS 决定外观)。
|
||||
|
||||
### 可控边界(换别人做的 theme)
|
||||
| 可控 | 不可强控 |
|
||||
|---|---|
|
||||
| 标准槽名(API):`head` / `sidebar` / … | 像素级宽高、是否做成卡片 |
|
||||
| 主题是否调用了 `@themeslot`(合规皮肤应全挂) | 侧栏在左还是右、主栏实际像素 |
|
||||
| 建议尺寸写在 `ThemeSlot::catalog()` / 后台 helper | 第三方主题漏掉某个槽 → 该注入静默不显示 |
|
||||
|
||||
结论:**槽名是硬约定,版式是软建议**。别人做 theme 只要挂齐标准槽,内容就能到「大概那个位置」;精确到「300×250 居中」做不到,也不该做进核心。合规检查可后续做:扫描 views 是否包含全部标准 `@themeslot`。
|
||||
|
||||
尺寸/位置说明见 `ThemeSlot::catalog()`(后台「注入」Tab 的 helper 同步显示)。
|
||||
|
||||
| 槽名 | 典型用途 | 建议尺寸(软) |
|
||||
|---|---|---|
|
||||
| `head` | 统计 / 额外 CSS·JS | 无版面 |
|
||||
| `body_start` / `body_end` | body 首尾脚本 | 无版面 |
|
||||
| `header_after` | 页头横幅、公告 | 通栏高约 60–120px |
|
||||
| `nav_after` | 导航后临时入口 | 文字链 |
|
||||
| `content_before` / `content_after` | 主栏前后 | 主栏宽约 640–760px |
|
||||
| `article_top` / `article_bottom` | 文章广告 | 主栏宽 × 90–250px |
|
||||
| `sidebar_before` / `sidebar` / `sidebar_after` | 侧栏广告 / 临时链接 | 侧栏约 280–320px,多条叠放 |
|
||||
| `footer_before` / `footer_after` | 页脚附加 | 通栏 |
|
||||
|
||||
### 后台怎么填
|
||||
`/admin` → **站点设置** → Tab「注入 / 广告 / 统计」:
|
||||
1. **统计代码** → `head`
|
||||
2. **侧栏广告** → `sidebar`
|
||||
3. **临时链接 HTML** → `sidebar_after`(可写 `<a href="...">活动</a>`)
|
||||
4. **文章顶/底广告** → `article_top` / `article_bottom`
|
||||
|
||||
也可继续用 **站点片段(Stylevars)** 做纯文本侧栏块;友情链接仍走「友情链接」资源。
|
||||
|
||||
### 插件怎么注入
|
||||
```php
|
||||
use App\Domain\Plugin\Hook;
|
||||
use App\Domain\Theme\ThemeSlot;
|
||||
|
||||
Hook::listen(ThemeSlot::event(ThemeSlot::SIDEBAR), function (string $html): string {
|
||||
return $html.'<p><a href="/promo">活动页</a></p>';
|
||||
});
|
||||
```
|
||||
|
||||
### 主题里任意位置
|
||||
在任意 Blade 加一行即可,例如正文中间:
|
||||
|
||||
```blade
|
||||
@themeslot('article_top')
|
||||
{{-- 或自定义新槽:插件 listen theme.my_slot,主题写 @themeslot('my_slot') --}}
|
||||
```
|
||||
|
||||
新槽无需改核心:约定 `theme.{name}` 事件即可。
|
||||
|
||||
## 发布
|
||||
```bash
|
||||
php artisan themes:publish
|
||||
# 或后台「皮肤」→ 启用 / 发布静态资源
|
||||
```
|
||||
资源复制到 `public/themes/{slug}/`。
|
||||
|
||||
## 回退
|
||||
`ThemeManager` 先注册 `default` views,再 `prepend` 当前主题;缺视图自动回退 default。
|
||||
|
||||
## 切换
|
||||
后台「皮肤」卡片启用,或改 Settings `general.active_theme`。
|
||||
Reference in New Issue
Block a user