Files
larablog/docs/themes.md
T
ak 263b98b218 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.
2026-08-12 01:15:38 +08:00

4.5 KiB
Raw Blame History

皮肤(主题)开发指南

目录格式

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 示例

{
  "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
  • 静态资源 URLapp(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 页头横幅、公告 通栏高约 60120px
nav_after 导航后临时入口 文字链
content_before / content_after 主栏前后 主栏宽约 640760px
article_top / article_bottom 文章广告 主栏宽 × 90250px
sidebar_before / sidebar / sidebar_after 侧栏广告 / 临时链接 侧栏约 280320px,多条叠放
footer_before / footer_after 页脚附加 通栏

后台怎么填

/admin站点设置 → Tab「注入 / 广告 / 统计」:

  1. 统计代码head
  2. 侧栏广告sidebar
  3. 临时链接 HTMLsidebar_after(可写 <a href="...">活动</a>
  4. 文章顶/底广告article_top / article_bottom

也可继续用 站点片段(Stylevars 做纯文本侧栏块;友情链接仍走「友情链接」资源。

插件怎么注入

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 加一行即可,例如正文中间:

@themeslot('article_top')
{{-- 或自定义新槽:插件 listen theme.my_slot,主题写 @themeslot('my_slot') --}}

新槽无需改核心:约定 theme.{name} 事件即可。

发布

php artisan themes:publish
# 或后台「皮肤」→ 启用 / 发布静态资源

资源复制到 public/themes/{slug}/

回退

ThemeManager 先注册 default views,再 prepend 当前主题;缺视图自动回退 default。

切换

后台「皮肤」卡片启用,或改 Settings general.active_theme