模块简介
Cms 是站点展示层模块,负责主题模板、站点菜单、横幅、广告、友情链接、站点配置以及主题商店等能力。它既服务前台页面渲染,也为其他模块提供一组适合站点展示的数据能力。
如果 System 是后台基础设施,那么 Cms 更像站点外壳:
- 前台入口由它接管
- 当前主题由它决定
- 菜单、广告、横幅、站点配置等展示数据由它维护
- 主题的发现、切换、配置、示例数据导入和商店安装由它完成
能力状态约定
稳定可用:已经在当前模块主流程中实际使用,可作为应用商店展示给开发者的正式能力扩展入口:明确开放给其他模块或主题接入,属于推荐扩展点预留能力:代码已经存在,但当前仓库内使用较少或尚未形成完整生态,接入前建议先验证
核心特点
- 通过
App\Cms\Web\Index以兜底方式接管前台路由,并按主题模板匹配页面 - 支持主题目录扫描、当前主题切换、主题表单配置和值读取
- 提供菜单、横幅、广告、友情链接、站点配置等可复用展示数据能力
- 提供主题示例数据导入/清理能力,可直接联动
Content模块的数据模型 - 提供主题商店能力,支持从云端获取主题列表、详情以及安装/升级/卸载动作
- 为
web视图注册RawPhpExtension和json过滤器,便于主题模板编写
与其他模块的关系
- 依赖
System的配置能力保存当前主题和主题设置 - 主题示例数据导入会直接写入
Content的分类、文章、页面等模型 - 面向前台的内容展示通常与
Content模块搭配使用
对外开放的数据模型
// 站点菜单定义
App\Cms\Models\Menu
App\Cms\Models\MenuData
// 站点配置
App\Cms\Models\CmsConfig
// 横幅、广告、友情链接
App\Cms\Models\CmsBanner
App\Cms\Models\CmsAd
App\Cms\Models\CmsLink
// 站点信息
App\Cms\Models\CmsSite
这些模型适合被其他模块读取或关联。管理端页面本身不建议作为模块间集成入口。
对外开放的 Service
ThemeService
状态:稳定可用、扩展入口
// App\Cms\Service\ThemeService
// 扫描 theme/*/theme.json,返回全部主题元数据
all(): array
// 按主题目录名读取主题信息
get(string $dir): array
// 返回当前主题目录名,不存在时回退到 site 或第一个主题
currentName(): string
// 返回当前主题完整信息
current(): array
// 返回主题默认设置与数据库保存值合并后的结果
settingValue(string $dir): array
// 返回后台主题管理需要的主题列表,并补充 current 和 value
adminThemes(): array
// 返回主题预览图实际文件路径
previewFile(string $dir, string $preview = ''): string
这是其他模块读取当前主题、主题配置和主题元信息的标准入口。
ThemeDemoService
状态:稳定可用、扩展入口
// App\Cms\Service\ThemeDemoService
// 读取主题目录下的 demo.json
read(string $dir): array
// 导入主题示例数据,包含分类、单页、文章、菜单、链接、横幅、站点配置
import(string $dir): array
// 按 demo.json 定义清理示例数据
clear(string $dir): array
这个 Service 适合:
- 安装主题后快速灌入演示站点数据
- 在应用商店里为主题提供“一键导入示例数据”
注意:它会直接操作 Content 和 Cms 的数据表,不是纯只读接口。
CloudThemeStoreService
状态:稳定可用
// App\Cms\Service\CloudThemeStoreService
// 获取云端主题列表,并标记本地安装状态和当前启用状态
listThemes(?string $cloudKey = null, ?string $cloudServer = null): array
// 获取主题详情
themeDetail(string $identifier, ?string $cloudKey = null, ?string $cloudServer = null): array
// 为安装、升级、卸载主题创建待执行 token
prepareStoreAction(array $payload, ?string $cloudKey = null, ?string $cloudServer = null): string
// 执行待处理的主题商店任务
runStoreActionToken(string $token, OutputInterface $output): array
// 主题商店任务互斥锁
acquireStoreRunningLock()
releaseStoreRunningLock($handle): void
// 读取和删除待执行 token
getStoreToken(string $token): array
deleteStoreToken(string $token): void
这是主题商店流程与日志输出依赖的核心服务。
Menu
状态:稳定可用、扩展入口
// App\Cms\Service\Menu
// 按菜单名与条件构建查询
query(string $name = '', array $where = []): Builder
// 返回菜单树,并根据当前路径标记 active
lists(string $name = '', array $where = [], ?string $path = '')
当其他模块需要读取某个站点菜单并高亮当前路径时,可以直接用它。
ApiList
状态:稳定可用、扩展入口
这是 Cms 与 Content 列表读取逻辑共用的参数辅助类,主要解决“排除、偏移、数量、布尔值解析、树过滤”等通用问题。
// App\Cms\Service\ApiList
// 把 exclude / exclude_id 解析成整型 ID 数组
parseExcludeIds(array $params): array
// 把 exclude / exclude_id 解析成字符串哈希表,便于快速判断
parseExcludeSet(array $params): array
// 判断当前项是否命中排除条件,会检查索引、id、label、title、url
isExcludedItem(array $item, int $index, array $excludeSet): bool
// 统一处理 hidden、exclude、offset、limit,并可叠加自定义过滤
filterGroupItems(array $data, array $params, ?callable $filter = null): array
// 把请求参数解析成 [offset, limit],支持 limit=10 和 limit=2,10 两种写法
parseOffsetLimit(array $params, int $defaultLimit = 0, int $minLimit = 0): array
// 在 parseOffsetLimit 基础上额外返回当前是否使用了范围模式
parseOffsetLimitWithMode(array $params, int $defaultLimit = 10, int $minLimit = 1): array
// 把字符串、数字等输入统一转成布尔值
toBool(mixed $value): bool
// 对普通数组做偏移和限量截取
sliceArray(array $list, int $offset, int $limit): array
// 对 Collection 做偏移和限量截取
sliceCollection(Collection $list, int $offset, int $limit): Collection
// 递归排除树结构中的指定节点
excludeTreeNodes(Collection $list, array $excludeIds): Collection
ApiList 常用参数约定
exclude/exclude_id:排除项,支持数组和逗号分隔字符串offset:偏移量,从第几条开始取limit:数量,既支持10,也支持2,10paging:是否走分页输出
如果新模块要继续做站点列表读取或模板标签扩展,建议直接复用它,保持参数行为一致。
Cms
状态:稳定可用、扩展入口
// App\Cms\Service\Cms
// 从 HTML 内容提取纯文本摘要
extractDescriptions(?string $content = '', int $len = 255): string
// 从 HTML 内容提取图片地址
extractImages(?string $content = ''): array
// 把远程图片抓取到当前站点存储,并返回原图 URL 到本地图 URL 的映射
localImages(array $images = []): array
适合内容采集、文章清洗、导入场景。
Translator
状态:预留能力
// App\Cms\Service\Translator
// 把文案统一按 theme 语言域进行翻译
translate(string $original, ...$params): string
当前这个类更适合被理解为“给主题/模板引擎预留的多语言适配器”,而不是通用业务翻译服务。
适用场景:
- 主题渲染代码里需要统一走
theme语言域 - 模板引擎、模板标签或主题扩展类希望有一个固定翻译入口
当前仓库中它基本还没有实际业务调用,属于预留能力。
模块事件
当前 Cms 模块没有定义额外的模块级 Event 类
当前也没有暴露面向其他模块订阅的业务事件
命令
theme:add
状态:稳定可用
# 命令类
App\Cms\Command\ThemeAddCommand
php dux theme:add theme-name
# 安装指定主题最新版本
php dux theme:add theme-name:1.0.0
# 安装指定主题版本
theme:update
状态:稳定可用
# 命令类
App\Cms\Command\ThemeUpdateCommand
php dux theme:update
# 更新已安装的全部主题
php dux theme:update theme-name
# 更新指定主题到最新版本
php dux theme:update theme-name:1.2.0
# 更新指定主题到目标版本
theme:del
状态:稳定可用
# 命令类
App\Cms\Command\ThemeDelCommand
php dux theme:del theme-name
# 卸载指定主题
theme:push
状态:稳定可用
# 命令类
App\Cms\Command\ThemePushCommand
php dux theme:push site
# 发布 theme/site 目录对应的主题包
如果需要扩展主题或站点展示能力,优先通过以下方式接入:
- 调用
ThemeService、ThemeDemoService、Menu等 Service - 复用
ApiList统一列表参数行为 - 在
theme/目录新增主题并通过theme.json、demo.json声明元数据
其他模块接入建议
- 需要读取当前主题或主题设置时,用
ThemeService,不要自己读theme.json和配置表。 - 需要前台可复用的列表过滤行为时,直接复用
ApiList。 - 需要菜单高亮时,用
Menu::lists(),传入当前路径即可拿到active标记。 - 需要采集或导入外部 HTML 内容时,可以先用
Cms::extractDescriptions()、extractImages()、localImages()做清洗。 - 如果模块要给主题商店或安装流程接入主题能力,直接对接
CloudThemeStoreService。