跳转到内容
TubePress — 免费、自托管 & 持续维护
开发者参考

钩子与插件开发

用 TubePress 的 WordPress 风格 action 与 filter 钩子系统扩展功能:15+ 个钩子点、插件生命周期,以及如何构建和打包你自己的插件。

插件是在不修改核心代码的情况下为 TubePress 添加功能的方式。它们通过一套类似 WordPress 风格的小型系统接入 CMS,包含动作(触发即忘事件)和过滤器(修改某个值并返回)。三个内置插件——Age Gate、Backup Pro 和 CTR Ranking——完全使用此处记录的同一套 API 构建。

钩子系统

静态的 HookSystem 类管理两种类型的钩子。回调按优先级升序执行(默认为 10);回调抛出的任何异常都会被捕获并记录,因此一个有问题的插件永远不会导致页面崩溃。

// Actions — do something when an event fires
HookSystem::addAction('head.meta', function () {
    echo '<meta name="rating" content="adult">';
}, 10);

// Filters — receive a value, return a (possibly) changed value
HookSystem::addFilter('theme.template_data', function ($data, $template) {
    if ($template === 'home') {
        $data['promo'] = Promo::current();
    }
    return $data;
});
方法用途
addAction($hook, $cb, $priority = 10)注册一个动作监听器。
doAction($hook, ...$args)触发一个动作(核心会调用这些)。
addFilter($hook, $cb, $priority = 10)注册一个过滤器。
applyFilter($hook, $value, ...$args)将一个值通过其过滤器处理并返回。
hasAction() / hasFilter()检查是否有任何监听器。
removeAction() / removeFilter()移除某个钩子的所有监听器。

可用的钩子点

核心会触发这些钩子。你也可以在插件中定义并触发自己的钩子。

动作

钩子触发时机
head.meta<head> 内,CSS 之后——添加 meta 标签、验证标签等。
footer.scripts</body> 之前,JS 之后——添加统计代码或小组件。
routes.registered所有核心路由注册完毕后,在通用页面捕获之前。
router.before_dispatch在匹配的处理程序运行之前。参数:解析后的路径。

过滤器

钩子修改内容(参数)
theme.template_data模板渲染前的数据数组。参数:($data, $templateName)
head.css合并后的 CSS 输出字符串。
footer.scripts合并后的 JS 输出字符串。
video.card.html完整的视频卡片 HTML。参数:($html, $video)。返回非空字符串以替换它。

插件结构

插件是 plugins/ 下的一个文件夹,包含清单文件和一个实现 PluginInterface 的类。

plugins/myplugin/
├── plugin.json     Manifest (name, slug, version, …)
├── myplugin.php    Main class implementing PluginInterface
├── icon.svg        Optional icon shown in the admin
└── …               Your assets, templates, migrations

清单文件的格式与内置插件相同:

{
  "name": "My Plugin",
  "slug": "myplugin",
  "description": "What it does, in one sentence.",
  "version": "1.0.0",
  "author": "You",
  "requires": "1.0.0",
  "icon": "icon.svg"
}

主类实现了 PluginInterface 的六个生命周期方法:

方法调用时机
boot()插件激活期间的每次请求——在此注册钩子、路由和资源。
activate()管理员启用插件时。
deactivate()管理员停用插件时。
install()首次激活——创建数据表,填充初始设置。
uninstall()插件被移除——执行清理。
info()以数组形式返回清单数据。

注册路由与资源

将所有注册工作放在 boot() 中:

public function boot(): void
{
    // A front-end route
    Router::get('/promo/{code}', [PromoController::class, 'show']);

    // Inject a meta tag
    HookSystem::addAction('head.meta', [$this, 'meta']);

    // Tweak every video card
    HookSystem::addFilter('video.card.html', [$this, 'badge'], 20);
}
设计上自给自足。插件应自行添加所需的一切——包括自有的数据库结构、设置项、路由、管理页面和定时任务——并在卸载时一并移除,无需修改基础 CMS。CTR Ranking 插件是这方面的良好示例。

插件中的定时任务

boot() 中使用 CronManager 注册定期任务——它基于内置伪 cron 运行,无需系统 crontab。CTR 插件重新计算评分以及 Backup Pro 执行定时备份均使用此方式。

内置插件参考

分发与授权

你可以将插件保持私有、自由分享,或通过市场出售——这将添加签名授权和按域名激活功能。有关展示层面的等效内容,请参阅主题开发;模板代码中的所有可用内容,请参阅主题 API 参考

还有疑问?

从您的控制面板提交工单,我们的团队将为您提供帮助。

体验在线演示 → 下载 TubePress →