Replace the loose page-count label with a SaBlog-style 6 / 316 chip, wire inject/stylevar HTML into list and post views, and flush page cache when ads are saved. Co-authored-by: Cursor <cursoragent@cursor.com>
6.1 KiB
6.1 KiB
开发规范
面向所有为 LaraLog 写代码的人(核心 / 插件 / 主题作者)。教程见 tutorial-plugin.md、tutorial-theme.md,配套示例见 plugins/demo.hello-world/、themes/demo/。
1. 代码规范
- PHP 8.2+,所有文件以
declare(strict_types=1);开头 - 命名空间:核心
App\...;插件Plugins\{Vendor}\{Name}\...(Vendor/Name 用Str::studly规则) - 文件命名:类文件与类名一致(PSR-4 自动加载)
- 方法/属性/变量:
camelCase;常量:UPPER_SNAKE;数据库表:snake_case - 中文文案直接写在代码/语言包中(本项目默认中文,不硬编码英文 UI)
- 不写无意义注释;只在「为什么」不明显处加一行注释
- 安全红线:不提交
.env、密钥、证书;用户输入一律e()转义或框架验证;数据库操作用 Eloquent/查询构造器(防注入)
2. 目录约定
app/Blog/ # 前台域模块:Controllers / Jobs / Services / Support / View
app/Filament/ # 后台资源与页面
plugins/ # 插件,目录名 vendor.name
themes/ # 主题,目录名即主题名
routes/web.php # 前台规范路由;routes/legacy.php 老 URL 301(新增老入口兼容放这里)
3. 插件规范(详见 docs/plugins.md)
- 目录
plugins/{vendor}.{name}/,目录名是插件唯一标识 - 类自动加载:系统启动时扫描
plugins/*/src注册 PSR-4(Plugins\{Vendor}\{Name}),无需改 composer.json plugin.json必填:title/version/description/author/type/provider;可选usage/requires/filament_pages/filament_resources- 入口类
src/ServiceProvider.php继承App\Blog\Support\PluginServiceProvider,不要命名为 PluginServiceProvider - 依赖声明在
requires(vendor.name),系统强制校验:依赖未启用不能启用本插件;停用/卸载被依赖者阻止 - 后台扩展一律走钩子注入(
filament.post_form/filament.post_table),禁止改核心资源文件 - 可购买实体约定:实现
payableLabel(): string与payableUrl(): ?string即接入订单展示(支付插件零改动) - 插件视图放插件目录并用
loadViews()注册命名空间;前台页面用@include('partials.header')复用主题公共片段
钩子清单
| Hook | 类型 | 参数 | 用途 |
|---|---|---|---|
post.rendered |
filter | (string $html, Post): string |
文章渲染后处理 |
comment.created |
action | Comment |
新评论创建 |
payment.paid |
action | Payment |
支付成功分发 |
filament.post_form |
action | Schema |
文章表单注入 |
filament.post_table |
action | Table |
文章表格注入 |
seo.structured_data |
filter | (array): array |
JSON-LD 扩展 |
theme.inject.{point} |
filter | (string): string |
注入点追加 HTML |
文章表单是左 2 右 1:插件用
PostForm::appendToSidebar()/PostForm::appendToAccessSection()注入,不要往根节点追加整行 Section。表格仍用pushColumns()。
4. 主题规范(详见 docs/themes.md)
- 目录
themes/{name}/,theme.json必填;views 前置到全局视图路径,同名覆盖、缺失回退 - 语义化 HTML(header/nav/main/aside/footer/article/time)是 SEO 要求,不是可选项
- 保留注入点
@stack('theme:xxx'),并尽量在 theme.json 声明inject_points - 必须有移动端断点(≤768px 两栏改单栏)
- 资产开发期流式返回、生产
theme:publish
5. 队列任务规范
- 实现
App\Blog\Jobs\AiJob接口(handle(LlmClient)由容器注入)+ShouldQueue - 入队
dispatch(new XxxJob($id))->onQueue('ai') - 消费者二选一:
php artisan workerman:serve(常驻+WS)或php artisan queue:work --queue=default,ai(等价,见 docs/deploy.md) - LLM 一律走
LlmClient(OpenAI 兼容,base_url/key/model 可配),不要直连第三方 SDK
6. 测试规范
- 新增功能必须配 Feature 测试(
tests/Feature/),跑php artisan test全绿再提交 - 示例参照:
PluginDependencyTest(依赖校验)、PostFormInjectionTest(表单注入)、MarketPurchaseTest(商城购买流)、MembershipFlowTest(会员/支付流) - 测试用 RefreshDatabase + 沙箱,不触碰真实支付/真实 LLM 凭据
7. 提交规范
- 一次提交一件事,信息用中文描述「做了什么 + 为什么」
- 不提交:
.env、密钥/证书、storage/media-library/temp/、构建产物 - 完成后更新对应
docs/文档
8. 后台导航约定
- 顶栏 网站 打开前台新窗口,写文章 进新建文章
- 管理 → 页面缓存:查看/清理前台整页缓存,不要只藏在用户菜单里
- 管理 → 语言:只展示当前
APP_LOCALE和已有语言包。文章还没有多语言版本,不要假装已经做了 - 文章置顶用
sticky_level(0/1/2/3),列表排序orderedForList()。3 = 置顶头条,永远最前 - 前台 RSS / Sitemap / llms.txt 开新窗口。
/llms.txt和/posts/{slug}.md是核心路由,不要做成静态文件,新文章要马上出现 - 首页浏览模式:
home_view_mode+?view=list|full+ cookiell_home_view。分页用blog_paginate()(onEachSide(1)) - 老 sablog 正文清洗放
SablogHtmlNormalizer,导入 / 渲染 /sablog:fix-content共用,不要各写一套 strip_tags - 广告位用
partials.theme-inject。保存主题注入要清页面缓存。stylevars 跟theme_vars_{theme}走,不要再忽略这张表
9. 常用命令速查
php artisan test # 全量测试
php artisan dev:watch # 开发热重载(改插件/核心代码自动重启 workerman)
php artisan migrate # 插件迁移自动加载
php artisan workerman:serve start # 队列消费者 + WebSocket
php artisan theme:publish # 主题资产发布到 public