Typecho 插件开发手册
一、插件的基本结构
在 Typecho 中,插件通常是一个独立的 PHP 文件,默认放置在usr/plugins/目录下。插件文件名即为插件名,插件类名也应与文件名相同。插件必须实现 Typecho\_Plugin\_Interface 接口。
基本结构:
php点击折叠面板
<?php
if (!defined('__TYPECHO_ROOT_DIR__')) exit;
/**
* 插件的描述信息
*
* @package PluginName
*/
class PluginName_Plugin implements Typecho_Plugin_Interface
{
// 插件激活方法
public static function activate() {}
// 插件停用方法
public static function deactivate() {}
// 插件配置面板
public static function config(Typecho_Widget_Helper_Form $form) {}
// 个人用户的配置面板
public static function personalConfig(Typecho_Widget_Helper_Form $form) {}
// 实现的插件功能方法
// ...
}说明
- Typecho\_Plugin\_Interface:插件类必须实现该接口,包含 activate、deactivate、config、personalConfig 四个方法。
- activate:插件激活时调用,用于注册插件方法、初始化数据等。
- deactivate:插件停用时调用,用于清理数据、注销插件方法等。
- config:插件的配置界面,用于在后台展示插件的设置选项。
- personalConfig:针对个人用户的配置界面。
二、激活插件
在 activate 方法中,可以进行以下操作:
- 注册插件方法 :使用 Typecho\_Plugin::factory 注册插件的方法到指定的 Hook Point。
- 创建数据库表 :如果插件需要额外的数据表,可以在激活时创建。
初始化数据 :初始化插件所需的数据或配置。
php点击折叠面板
public static function activate() { // 注册插件方法到 Hook Point Typecho_Plugin::factory('Widget_Archive')->beforeRender = array('PluginName_Plugin', 'beforeRender'); // 返回激活成功的信息 return _t('插件已激活'); }
三.停用插件
在deactivate方法中,可以进行以下操作:
- 注销插件方法:清理注册的插件方法(Typecho 会自动处理)。
- 删除 数据库 表:如果插件创建了额外的数据表,可以选择在停用时删除。
- 清理数据:清理插件的配置信息或缓存。
四、定义插件的配置界面
在 config 方法中定义插件的配置选项。
php点击折叠面板
public static function config(Typecho_Widget_Helper_Form $form)
{
// 添加一个文本框
$text = new Typecho_Widget_Helper_Form_Element_Text('text', NULL, '默认值', _t('文本框标签'), _t('文本框提示'));
$form->addInput($text);
// 添加一个单选框
$radio = new Typecho_Widget_Helper_Form_Element_Radio('radio', array('1' => '选项1', '2' => '选项2'), '1', _t('单选框标签'));
$form->addInput($radio);
// 添加一个复选框
$checkbox = new Typecho_Widget_Helper_Form_Element_Checkbox('checkbox', array('1' => '选项1', '2' => '选项2'), NULL, _t('复选框标签'));
$form->addInput($checkbox);
}说明:
- 使用 Typecho\_Widget\_Helper\_Form\_Element\_* 类来创建不同类型的表单元素。
- 调用 $form->addInput() 方法将元素添加到配置界面。
五、处理插件的用户配置
在插件的方法中,可以通过Helper::options()->plugin('PluginName')获取用户的配置信息。
php点击折叠面板
public static function someMethod()
{
$options = Helper::options()->plugin('PluginName');
$textValue = $options->text; // 获取文本框的值
// ...
}说明:
- Helper::options():获取全局的配置对象。
- plugin('PluginName'):获取指定插件的配置信息。
六、注册插件方法(Hook Point)
在 activate 方法中,使用 Typecho_Plugin::factory 注册插件的方法到指定的 Hook Point。
php点击折叠面板
public static function activate()
{
Typecho_Plugin::factory('Widget_Archive')->beforeRender = array('PluginName_Plugin', 'beforeRender');
}说明: 具体插入点可以参考文章后半段,有专门介绍各插入点的作用及位置
- Typecho\_Plugin::factory('类名')->方法名:指定要拦截的类和方法(Hook Point)。
- array('PluginName\_Plugin', '方法名'):插件的方法回调。
七、定义 自定义 路由
如果插件需要 自定义 URL 路由,可以在activate 方法中定义。
php点击折叠面板
public static function activate()
{
// 添加自定义路由
Helper::addRoute('plugin_route', '/plugin/route/', 'PluginName_Action', 'actionMethod');
}
public static function deactivate()
{
// 删除自定义路由
Helper::removeRoute('plugin_route');
}Helper::addRoute:添加自定义路由。
- 第一个参数:路由名称。
- 第二个参数:路由规则(URL 模式)。
- 第三个参数:处理该路由的类名。
- 第四个参数:处理方法。
Helper::removeRoute:删除自定义路由。
八、加载插件的类和方法
如果插件包含多个类或文件,可以通过require_once或自动加载的方式引入。
php点击折叠面板
// 在插件的主文件中
require_once 'libs/Helper.php';
// 使用命名空间和自动加载
spl_autoload_register(function ($class) {
$prefix = 'PluginName\\';
$base_dir = __DIR__ . '/src/';
$len = strlen($prefix);
if (strncmp($prefix, $class, $len) !== 0) {
return;
}
$relative_class = substr($class, $len);
$file = $base_dir . str_replace('\\', '/', $relative_class) . '.php';
if (file_exists($file)) {
require $file;
}
});require_once:直接引入文件。spl_autoload_register:注册自动加载函数,按照命名空间和目录结构自动加载类。
九、文件载入与资源管理
插件可能需要加载 CSS、JS 文件或其他资源,可以通过以下方式实现。
在模板中加载资源:
php点击折叠面板
// 在插件的方法中
public static function header()
{
$cssUrl = Helper::options()->pluginUrl . '/PluginName/assets/style.css';
echo '<link rel="stylesheet" type="text/css" href="' . $cssUrl . '">';
}
public static function footer()
{
$jsUrl = Helper::options()->pluginUrl . '/PluginName/assets/script.js';
echo '<script type="text/javascript" src="' . $jsUrl . '"></script>';
}注册到 Hook Point:
php点击折叠面板
public static function activate()
{
Typecho_Plugin::factory('Widget_Archive')->header = array('PluginName_Plugin', 'header');
Typecho_Plugin::factory('Widget_Archive')->footer = array('PluginName_Plugin', 'footer');
}Helper::options()->pluginUrl:获取插件目录的 URL。header、footer:在页面的头部和尾部输出内容。
十、模板的使用与扩展
插件可以自定义模板,或者扩展主题的模板功能。在插件目录中创建模板文件:
- 创建themes目录 :在插件目录下创建
themes目录,用于存放模板文件。 编写模板文件 :例如,创建
themes/plugin-template.php
在插件中调用模板:php点击折叠面板
public static function renderTemplate() { $template = __DIR__ . '/themes/plugin-template.php'; if (file_exists($template)) { include $template; } else { echo '模板文件不存在'; } }在路由处理方法中调用:
php点击折叠面板
public function actionMethod() { self::renderTemplate(); }
十一、完整的插件示例
php点击折叠面板
usr/
└── plugins/
└── HelloWorld/
├── HelloWorld_Plugin.php
├── Action.php
├── assets/
│ ├── style.css
│ └── script.js
└── themes/
└── hello.php十二、钩子(Hook)插入点
在 Typecho 插件开发中,可以通过 Typecho_Plugin::factory('类名')->方法名的形式来拦截和扩展 Typecho 的核心功能。以下是所有可用的插入位置(Hook Points),按照类名分类,并注明调用的位置及意义。
十三、插入位置的定义方式
插入位置通常是通过以下几种方式定义的:
方法(Method):
- 在 Typecho 的核心类中,某些方法被定义为插入位置。例如,
Widget_Contents_Post_Edit类中的insert方法就是一个插入位置。 - 插件可以通过
Typecho_Plugin::factory('Widget_Contents_Post_Edit')->insert来拦截这个方法,并在其中执行自定义代码。
属性(Property):
- 在 Typecho 的核心类中,某些方法被定义为插入位置。例如,
在 Typecho 的核心类中,某些属性被定义为插入位置。例如,Widget\_Contents\_Post\_Edit 类中的 insert 属性就是一个插入位置。
插件可以通过 Typecho\_Plugin::factory('Widget\_Contents\_Post\_Edit')->insert 来拦截这个属性,并在其中执行自定义代码。
13.1示例
假设我们有一个Widget_Contents_Post_Edit类,其中定义了一个insert方法:
php点击折叠面板
class Widget_Contents_Post_Edit extends Typecho_Widget
{
public function insert()
{
// 插入文章的逻辑
}
}在插件中,我们可以通过以下方式拦截这个insert方法:
php点击折叠面板
class XXX_Plugin implements Typecho_Plugin_Interface
{
public static function activate()
{
Typecho_Plugin::factory('Widget_Contents_Post_Edit')->insert = array('XXX_Plugin', 'publish');
}
public static function publish($post)
{
// 自定义的插入逻辑
}
}在这个例子中,XXX_Plugin 插件在 Widget_Contents_Post_Edit 类的 insert 方法执行时,会调用 XXX_Plugin::publish 方法来执行自定义的插入逻辑
十四、常见Hooks整理
1.Widget\_Contents\_Post\_Edit
- insert:在插入文章时触发。
- update:在更新文章时触发。
- delete:在删除文章时触发。
finishPublish:在文章发布完成后触发。
2.Widget\_Contents\_Page\_Edit
- insert:在插入页面时触发。
- update:在更新页面时触发。
- delete:在删除页面时触发。
finishPublish:在页面发布完成后触发。
3.Widget\_Comments\_Edit
- insert:在插入评论时触发。
- update:在更新评论时触发。
- delete:在删除评论时触发。
- finishComment:在评论操作完成后触发。
finishDelete:在评论删除后触发。
4.Widget\_Users\_Edit
- insert:在创建用户时触发。
- update:在更新用户信息时触发。
- delete:在删除用户时触发。
- finishCreate:在用户创建完成后触发。
finishDelete:在用户删除后触发。
5.Widget\_Metas\_Category\_Edit
- insert:在创建分类时触发。
- update:在更新分类信息时触发。
- delete:在删除分类时触发。
finishCreate:在分类创建完成后触发。
6.Widget\_Metas\_Tag\_Edit
- insert:在创建标签时触发。
- update:在更新标签信息时触发。
- delete:在删除标签时触发。
finishCreate:在标签创建完成后触发。
7.Widget\_Feedback
- comment:在用户提交评论时触发。
trackback:在接收Trackback时触发。
8.Widget\_Register
register:在用户注册时触发。
9.Widget\_Login
- loginSucceed:在用户登录成功后触发。
loginFail:在用户登录失败后触发。
10.Widget\_Archive
- beforeRender:在渲染文章内容之前触发。
- afterRender:在渲染文章内容之后触发。
- beforeOutput:在输出文章内容之前触发。
- afterOutput:在输出文章内容之后触发。
- handleInit:在 Archive Widget 初始化时触发。
select:在构建内容查询时触发。
11.Widget\_Comments
- beforeRender:在渲染评论列表之前触发。
afterRender:在渲染评论列表之后触发。
12.Widget\_Abstract\_Contents
- contentEx:在获取文章完整内容时触发。
- excerptEx:在获取文章摘要内容时触发。
filter:在获取内容列表时触发。
13.Widget\_Abstract\_Comments
- contentEx:在获取评论内容时触发。
- excerptEx:在获取评论摘要时触发。
filter:在获取评论列表时触发。
14.Widget\_Abstract\_Metas
filter:在获取分类或标签列表时触发。
15.Widget\_Abstract\_Users
filter:在获取用户列表时触发。
16.Widget\_Abstract\_Options
filter:在获取系统选项时触发。
17.Widget\_Abstract
- beforeRender:在任何 Widget 渲染之前触发。
- afterRender:在任何 Widget 渲染之后触发。
- \_\_\_construct:在 Widget 初始化时触发。
- \_\_\_init:在 Widget 初始化完成后触发。
\_\_\_execute:在执行 Widget 主逻辑时触发。
18.Typecho\_Widget
- widget:在创建 Widget 实例时触发。
- widgetStart:在 Widget 开始执行时触发。
widgetEnd:在 Widget 执行结束时触发。
19.Typecho\_Widget\_Helper\_Form
render:在渲染表单之前触发。
20.Typecho\_Widget\_Helper\_Form\_Element
render:在渲染表单元素之前触发。
21.Typecho\_Db
- query:在执行 数据库 查询时触发。
fetchAll:在获取查询结果时触发。
22.Typecho\_Router
- router:在路由解析时触发。
dispatch:在路由调度时触发。
23.Typecho\_Response
redirect:在执行页面重定向时触发。
24.Typecho\_Cookie
- set:在设置 Cookie时触发。
get:在获取 Cookie时触发。
25.Typecho\_Feed
output:在输出RSS Feed时触发。
26.Typecho
- init:在系统初始化时触发。
- header:在输出页面头部时触发。
footer:在输出页面尾部时触发。
使用方法示例:php点击折叠面板
Typecho_Plugin::factory('Widget_Contents_Post_Edit')->insert = array('YourPlugin_Class', 'yourMethod');说明:
- 插入位置(Hook Point):即可拦截的方法名。
- 触发时机:在对应的方法执行时触发,允许插件在该时机执行自定义逻辑。
- 使用场景:插件可以通过这些 Hook Points 实现对 Typecho 功能的扩展和定制,例如在文章发布后发送通知,在用户登录失败后记录日志等。
注意事项: - 确保方法存在:请确保您定义的插件类和方法存在且可被调用,避免出现错误。
- 性能考虑:插件开发时应注意性能,避免阻塞核心功能的执行。
- 充分测试:某些 Hook Points 可能仅在特定情况下触发,开发时需充分测试。
通过以上整理,您可以清晰地了解 Typecho 插件开发中可用的所有插入位置,以及它们的调用位置和意义,方便在插件中实现所需的功能。
- 上一篇:利用AI写了个友情链接在线提交功能
- 下一篇:没有了啦!



