简介
本文件为 DouPHP 主题定制系统的开发文档,面向希望基于默认主题进行二次开发的开发者。内容涵盖多主题架构设计、主题目录与配置管理、资源组织方式、CSS 变量与主题切换机制、动态样式生成、主题继承与覆盖、后台可视化配置界面、主题开发与打包分发规范等。文档以仓库实际实现为依据,提供可追溯的源码路径与图示说明。
项目结构
DouPHP 的主题系统采用“按主题目录隔离”的设计:每个主题位于 theme/<slug>/ 目录下,包含模板文件、样式、脚本与公共资源。系统通过策略类判定当前生效主题,并通过控制器与服务完成主题的启用、删除、元数据解析与参数同步。前台页面渲染时根据当前主题选择对应模板文件。
graph TB
A["前台请求"] --> B["页面控制器<br/>PageController"]
B --> C["主题策略<br/>SiteThemePolicy"]
C --> D["当前主题目录名"]
D --> E["模板引擎<br/>DouView / DouViewCompiler"]
E --> F["主题目录<br/>theme/<slug>/"]
F --> G["模板文件 *.dwt"]
F --> H["样式与脚本<br/>css/js/images"]
F --> I["主题设置<br/>inc/..setting.php"]
图表来源
- PageController.php:133-138
- SiteThemePolicy.php:46-55
- DouView.php
- DouViewCompiler.php
章节来源
- PageController.php:133-138
- SiteThemePolicy.php:46-55
核心组件
- 主题策略:负责判定当前生效的前台主题目录名,并在未授权商业主题+正式域名场景下回退到默认主题。
- 后台主题控制器:提供主题列表、安装、启用、删除、模块支持同步等入口。
- 主题服务:实现主题元数据解析、主题启用时的目录复制与配置更新、缓存清理、云端预览链接获取、支持模块同步等。
- 主题设置读取器:读取主题 inc/..setting.php 中的键值对,用于后台展示主题相关提示或尺寸信息。
- 模板引擎:根据当前主题目录加载对应的 .dwt 模板文件并编译渲染。
章节来源
- SiteThemePolicy.php:46-78
- ThemeController.php:141-169
- ThemeService.php:59-167
- ThemeSettingsReader.php:43-62
- DouView.php
- DouViewCompiler.php
架构总览
下图展示了从后台操作到前台渲染的完整流程:管理员在后台启用主题后,系统更新站点配置;前台请求到来时,策略类计算有效主题,模板引擎据此加载主题下的模板与资源。
sequenceDiagram
participant Admin as "管理员"
participant Ctrl as "ThemeController"
participant Svc as "ThemeService"
participant Policy as "SiteThemePolicy"
participant View as "DouView / Compiler"
participant Theme as "theme/<slug>"
Admin->>Ctrl : 提交启用主题
Ctrl->>Svc : enableTheme(slug)
Svc->>Svc : 复制默认主题到目标目录
Svc->>Svc : 更新 site_theme 配置
Svc-->>Ctrl : 返回
Note over Svc,View : 清除模板缓存
Admin->>Ctrl : 访问前台页面
Ctrl->>Policy : effectiveTheme()
Policy-->>Ctrl : 返回有效主题 slug
Ctrl->>View : 渲染 <slug>/<page>.dwt
View->>Theme : 加载模板与资源
Theme-->>View : 返回渲染结果
View-->>Admin : 输出 HTML
图表来源
- ThemeController.php:141-169
- ThemeService.php:143-167
- SiteThemePolicy.php:46-55
- PageController.php:133-138
详细组件分析
主题策略 SiteThemePolicy
- 职责:计算当前生效主题目录名;在未授权且使用商业主题(m\d{3})且为正式域名的情况下强制回退到 default。
- 关键点:
- 读取站点配置 site.site_theme。
- 通过 domain 检查判断是否正式域名。
- 使用正则匹配商业主题命名规则。
- 影响:确保未授权环境下不会暴露商业主题效果,保障授权控制。
flowchart TD
Start(["开始"]) --> ReadCfg["读取 site.site_theme"]
ReadCfg --> CheckLicense{"已授权?"}
CheckLicense --> |是| ReturnTheme["返回 site.site_theme"]
CheckLicense --> |否| CheckSlug{"主题匹配 m\\d{3}?"}
CheckSlug --> |否| ReturnTheme
CheckSlug --> |是| CheckDomain{"正式域名?"}
CheckDomain --> |否| ReturnTheme
CheckDomain --> |是| Fallback["回退到 default"]
Fallback --> End(["结束"])
ReturnTheme --> End
图表来源
- SiteThemePolicy.php:46-78
章节来源
- SiteThemePolicy.php:46-78
后台主题控制器 ThemeController
- 职责:提供主题管理的 HTTP 入口,包括启用、删除、模块支持同步、跳转至参数设置页等。
- 关键点:
- 调用 ThemeService 执行具体逻辑。
- 根据 act 参数决定重定向到主题参数设置或主题列表。
- 集成云服务和日志记录。
章节来源
- ThemeController.php:141-169
主题服务 ThemeService
- 职责:主题元数据解析、主题启用与删除、缓存清理、云端预览链接获取、支持模块同步、参数行补全。
- 关键点:
- parseThemeMeta:从主题 style.css 头部注释解析主题信息(名称、版本、作者、缩略图等),并识别是否为商业主题。
- enableTheme:将默认主题复制到目标主题目录,更新 site_theme 配置,必要时更新缩略图尺寸,并清理模板缓存。
- deleteTheme:删除主题目录及关联数据。
- syncSupportModuleFromApi:从云端拉取 need_module,本地非商业主题则写入全部已装模块。
- ensureThemeParameterRows:确保主题参数项存在。
classDiagram
class ThemeService {
+buildThemeListData(site_theme, theme_blocked) array
+fetchCloudPreviewFrameUrl(uniqueId) string
+buildThemeInstallData(getRequest) array
+resolveSetRedirectUrl(actRaw) string
+enableTheme(slug) void
+deleteTheme(slug) void
+clearSupportModule() void
+syncSupportModuleFromApi() bool
+ensureThemeParameterRows() void
-parseThemeMeta(slug) array|null
}
图表来源
- ThemeService.php:59-302
章节来源
- ThemeService.php:59-302
主题设置读取器 ThemeSettingsReader
- 职责:读取主题 inc/..setting.php 中的 key:value 行,供后台展示主题相关提示或尺寸信息。
- 关键点:
- 若指定主题则读取该主题设置,否则读取当前站点主题。
- 仅当文件存在时返回解析后的数组,否则返回 false。
章节来源
- ThemeSettingsReader.php:43-62
模板引擎与主题渲染
- 前台控制器根据当前主题目录查找同名 .dwt 模板,不存在则回退到 page.dwt。
- 模板引擎负责加载主题目录下的模板与公共片段(如 header.tpl、footer.tpl)。
- 编译过程由 DouViewCompiler 处理,最终输出 HTML。
sequenceDiagram
participant PC as "PageController"
participant SV as "DouView"
participant VC as "DouViewCompiler"
participant TH as "theme/<slug>"
PC->>PC : 确定当前主题目录
PC->>SV : view("<page>.dwt", data)
SV->>VC : 编译模板
VC->>TH : 加载模板与片段
TH-->>VC : 模板内容
VC-->>SV : 编译结果
SV-->>PC : 渲染 HTML
图表来源
- PageController.php:133-138
- DouView.php
- DouViewCompiler.php
章节来源
- PageController.php:133-138
主题目录结构与资源组织
- 主题根目录:theme/<slug>/
- css/:样式文件,推荐主样式为 css/style.css,也可兼容旧版 style.css。
- images/:图片资源,建议包含 screenshot.png 作为主题截图。
- js/:前端脚本。
- inc/:公共片段与主题设置文件(..setting.php)。
- *.dwt:页面模板文件。
- 元数据解析:系统从 style.css 头部注释中解析主题名称、URI、描述、版本、作者等信息,并标记是否为商业主题。
章节来源
- ThemeService.php:268-302
- style.css(默认主题):1-200
CSS 变量与主题切换机制
- 主题切换:通过后台启用主题,系统更新 site.site_theme 配置;前台渲染时依据该配置选择主题目录。
- 样式覆盖:新主题会复制默认主题目录内容,便于在此基础上修改样式与模板;可通过覆盖默认主题的文件实现差异化。
- CSS 变量:建议在主题主样式中使用 CSS 自定义属性(变量)集中管理颜色、字号、间距等,便于运行时通过 JS 修改 :root 变量实现即时换肤。
章节来源
- ThemeService.php:143-167
- SiteThemePolicy.php:46-55
动态样式生成与用户自定义样式
- 运行时样式修改:可在前端通过 JavaScript 动态修改 :root 中的 CSS 变量,实现颜色、字体等实时切换。
- 用户自定义样式:可将用户设置的样式写入主题 inc/..setting.php 或通过后台参数存储,并在模板中以内联样式或外部样式表形式输出。
- 注意:避免频繁 DOM 操作与大量内联样式,优先使用 CSS 变量与类名切换以提升性能。
主题继承与覆盖机制
- 继承基础:启用新主题时,系统会将默认主题目录复制到目标主题目录,保留默认实现。
- 覆盖策略:在新主题目录中仅覆盖需要变更的文件(如模板、样式、片段),其余沿用默认主题。
- 最佳实践:保持主题目录精简,只包含差异部分;通过清晰的命名约定区分覆盖文件。
章节来源
- ThemeService.php:143-167
主题配置界面与可视化配置
- 后台入口:ThemeController 提供主题管理入口,结合 ThemeService 完成启用、删除、模块支持同步等操作。
- 参数设置:通过 resolveSetRedirectUrl 跳转到主题参数设置页,支持颜色选择器、布局选项等可视化配置。
- 主题设置文件:inc/..setting.php 提供 key:value 形式的主题配置提示,便于后台展示与校验。
章节来源
- ThemeController.php:141-169
- ThemeService.php:120-137
- ThemeSettingsReader.php:43-62
主题开发规范与最佳实践
- 命名约定:
- 主题目录使用短横线或字母数字组合,商业主题遵循 m\d{3} 命名。
- 样式主文件建议使用 css/style.css,兼容旧版 style.css。
- 截图文件 images/screenshot.png。
- 性能优化:
- 减少不必要的样式与脚本加载,按需引入。
- 使用 CSS 变量与类名切换替代频繁内联样式。
- 压缩与合并静态资源,合理使用缓存。
- 兼容性处理:
- 针对移动端与桌面端使用媒体查询适配。
- 避免使用过新的 CSS/JS 特性,或提供降级方案。
- 测试主流浏览器与设备。
主题打包、分发与版本管理
- 打包:将主题目录压缩为 zip,包含 css、images、js、inc、*.dwt 与必要的配置文件。
- 分发:可通过云平台上传与管理主题,后台支持从云端安装与预览。
- 版本管理:在 style.css 头部注释中维护版本号,便于升级与回滚;利用系统缓存清理确保新版本生效。
章节来源
- ThemeService.php:88-118
- ThemeService.php:268-302
依赖关系分析
- 控制器依赖服务:ThemeController 依赖 ThemeService 执行主题管理逻辑。
- 服务依赖策略:ThemeService 在启用主题时更新配置,前台渲染时由 SiteThemePolicy 计算有效主题。
- 模板引擎依赖主题目录:DouView 与 DouViewCompiler 根据当前主题目录加载模板与片段。
- 设置读取器依赖主题文件:ThemeSettingsReader 读取 inc/..setting.php 提供后台提示。
graph LR
Ctrl["ThemeController"] --> Svc["ThemeService"]
Svc --> Pol["SiteThemePolicy"]
Page["PageController"] --> Pol
Page --> View["DouView / Compiler"]
View --> Th["theme/<slug>"]
Svc --> SetR["ThemeSettingsReader"]
图表来源
- ThemeController.php:141-169
- ThemeService.php:59-302
- SiteThemePolicy.php:46-78
- PageController.php:133-138
- ThemeSettingsReader.php:43-62
章节来源
- ThemeController.php:141-169
- ThemeService.php:59-302
- SiteThemePolicy.php:46-78
- PageController.php:133-138
- ThemeSettingsReader.php:43-62
性能考虑
- 模板缓存:启用或删除主题后会清理模板缓存,确保渲染效率与一致性。
- 资源加载:避免在主题中引入过多第三方库,按需加载并压缩。
- 样式优化:使用 CSS 变量与类名切换,减少运行时样式计算开销。
- 图片优化:使用合适的图片格式与尺寸,启用 CDN 与缓存。
故障排查指南
- 主题未生效:
- 检查 site.site_theme 配置是否正确。
- 确认主题目录是否存在必要文件(style.css、screenshot.png、模板文件)。
- 查看是否因未授权商业主题+正式域名被策略回退到 default。
- 样式异常:
- 检查 CSS 变量定义与引用是否正确。
- 确认是否有覆盖冲突或优先级问题。
- 模板错误:
- 检查模板文件名与控制器期望一致。
- 查看模板片段是否缺失或路径错误。
章节来源
- SiteThemePolicy.php:46-78
- ThemeService.php:143-167
- PageController.php:133-138
结论
DouPHP 的主题系统通过策略模式与模板引擎实现了灵活的多主题架构。开发者可以基于默认主题快速创建新主题,并通过样式覆盖与动态样式机制实现个性化定制。后台提供了完整的主题管理与可视化配置能力,支持云端安装与预览。遵循开发规范与最佳实践,可显著提升主题的可维护性与性能表现。
附录
- 主题元数据字段:Theme Name、Theme URI、Description、Version、Author、Author URI。
- 主题设置文件格式:每行 key:value,用于后台提示与校验。
- 商业主题命名:m\d{3},在未授权+正式域名下会被禁用并回退到 default。