Typecho是一个轻量级的博客程序,在使用过程中难免会有功能是没有的,正所谓萝卜青菜各有所好,要实现自己想要的功能但又不能破坏程序本有的代码结构,那就需要制作成插件了。
制作的插件需要一个接口,才可以使之嵌入到博客程序当中,要实现的功能才会生效,接下来通过转载木然轩的一篇插件开发教程简单说明typecho插件的制作方法:
给插件取个名字,假设叫LoginBeautify
吧,名字注意不能有_
。然后在Typecho
的插件目录创建一个和插件名一致的文件夹(也就是LoginBeautify
),在新建的这个文件夹下创建文件Plugin.php
。这个是Typecho
的约定,Typecho
会自动扫描插件目录,解析目录下的Plugin.php
。
在Plugin.php
内键入以下内容,主要是插件的描述信息,填写一下就行:
一、创建插件
<?php
if (!defined('__TYPECHO_ROOT_DIR__')) exit;
/**
* 登录界面美化
*
* @package LoginBeautify
* @author jlice
* @version 1.0.0
* @link https://jlice.top
*/
class LoginBeautify_Plugin implements Typecho_Plugin_Interface
{
}
这里需要注意:插件必须以class 插件名_Plugin implements Typecho_Plugin_Interface{插件内容}
的方式实现,所有的代码都必须包含在这个大括号之内。
二、插件的配置
1.activate
和deactivate
分别是启用和禁用插件时运行的代码。
2.config
和personalConfig
分别是插件的后台配置面板和后台个人设置面板。
需要注意的是,上面这些方法都是静态的(有static
修饰),粗糙点说就是不能用$this
。
什么是接口点?
这里我称之为:“接口点”(原文叫钩子),假如Typecho
的作者觉得某个地方可以交给插件去完成,可以在这个地方放一个接口点,然后插件挂载到这个接口点上,程序在运行时,会检查接口点有没有挂载插件,如果有会执行插件的代码。
通过上面的理解,我们可以知道,插件要声明注册到哪个接口点,执行什么代码,这样Typecho
才能知道何时执行以及执行什么代码。当然,一个插件也可以挂载到多个接口点。实际上,Typecho
在启用或禁用插件时就会把插件的数据保存到数据库,位于options
表里。
Typecho
预留的接口点是以 Typecho_Plugin::factory()->function();
的方法实现的。
如果要看所有的钩子,可以参考官方文档,或者在代码里搜索。这里我推荐 sublime text 3 一个代码编辑器,可以搜索文件夹中文件里面的代码。
例如:
Searching 233 files for "Typecho_Plugin::factory"
C:\Users\said\Desktop\32214344\build\admin\common.php:
16
17 /** 注册一个初始化插件 */
18: Typecho_Plugin::factory('admin/common.php')->begin();
19
20 Typecho_Widget::widget('Widget_Options')->to($options);
C:\Users\said\Desktop\32214344\build\admin\editor-js.php:
108 });
109
110: <?php Typecho_Plugin::factory('admin/editor-js.php')->markdownEditor($content); ?>
111
112 var th = textarea.height(), ph = preview.height(),
C:\Users\said\Desktop\32214344\build\admin\footer.php:
4 <?php
5 /** 注册一个结束插件 */
6: Typecho_Plugin::factory('admin/footer.php')->end();
7
C:\Users\said\Desktop\32214344\build\admin\header.php:
13
14 /** 注册一个初始化插件 */
15: $header = Typecho_Plugin::factory('admin/header.php')->header($header);
16
17 ?><!DOCTYPE HTML>
找到合适的接口点
接口点那么多,怎么能知道哪个接口点符合自己的需求呢?这个问题,em...,其实不太好回答。
我们注意到两个目录:一个是var/Widget/
,这里是Typecho
的核心代码,里面有Typecho
定义的各种Widget
;另一个是admin/
,这里是后台管理的代码。Widget
是组件的意思,例如Widget_Archive
就是输出文章的,例如首页和文章页面。Widget
里的接口点可以定制这些组件的行为。具体有哪些组件可以参考官方文档,或者直接看var/Widget/
这个目录就可以了。
接口点的位置有两个层面的意思,或者说为了指定要挂载哪个接口点,我们需要确定两件事:一是这个接口点在哪,对于admin/
下的,需要指定.php
文件位置,对于var/Widget/
里的接口点,只需要指明类名即可(也就是Widget
的名字);二是这个接口点的名字,也就是function
的名字。
下面是一些例子:
// var/Widget/Upload.php
$result = Typecho_Plugin::factory('Widget_Upload')->trigger($hasUploaded)->uploadHandle($file);
// Widget: Widget_Upload function: uploadHandle
// var/Widget/Contents/Post/Edit.php
$this->pluginHandle()->finishPublish($contents, $this);
// Widget: Widget_Contents_Post_Edit function: finishPublish
// admin/write-js.php
Typecho_Plugin::factory('admin/write-js.php')->write();
// php: admin/write-js.php function: write
p.s.需要注意的是第一个例子里的trigger
并不是钩子的名字,这个是Typecho
用来判断是否有插件挂载到这里用的。
由于我们要做登录界面美化,也就是改登录界面背景,很自然地想到后台管理的登录界面,也就是admin/login.php
,虽然我们在这个文件里并没有发现接口点,但在它的引入文件footer.php
却发现了:
/** 注册一个结束插件 */
Typecho_Plugin::factory('admin/footer.php')->end();
p.s. 在看文件的时候我们不要把include
给忽略了,这好比把一个文件分割成了几个文件,这是php的基本知识。
于是,我们的LoginBeautify
插件找到了它的接口点:
启用插件
public static function activate()
{
Typecho_Plugin::factory('admin/footer.php')->end = array('LoginBeautify_Plugin', 'end');
}
把整个插件内容做为一个集合添加到这个接口点里去,end是一个函数,下面会继续写它的内容。
禁用插件
public static function deactivate(){}
有些插件禁用虽然回收一些东西,但我们这里没有,所以括号内留空。
插件配置面板
public static function config(Typecho_Widget_Helper_Form $form)
{
$url = new Typecho_Widget_Helper_Form_Element_Text('bgUrl', NULL,'','未登录背景', _t("背景URL"));
$form->addInput($url);
}
``
这里的意思是在启用插件后,在设置里添加一个text文本框,分别是:文本框名,选择项,默认值,标题,说明。
个人设置
`public static function personalConfig(Typecho_Widget_Helper_Form $form){}`
不需要,留空。
###函数end内容编写###
要写什么内容就要看我们要实现什么样的功能了,这里我们要实现一个基本功能,判断用户有没有登录,没有就添加背景图片。
由于`end`没有输入参数,所以我们这里增加的`end`方法也没有输入参数。如果钩子有输入参数,我们对应增加的方法里应该有对应的输入参数。
我们注意到`login.php`的最开始有如下代码:
<?php
include 'common.php';
if ($user->hasLogin()) {
$response->redirect($options->adminUrl);
}
这几行代码的意思是:引入`common.php`,如果用户已经登录了,就跳转到管理地址。可是,`$user`、`$response`和`$options`这些变量哪来的呢?
查看`common.php`。可以发现如下代码:
Typecho_Widget::widget('Widget_Options')->to($options);
Typecho_Widget::widget('Widget_User')->to($user);
Typecho_Widget::widget('Widget_Security')->to($security);
Typecho_Widget::widget('Widget_Menu')->to($menu);
`Typecho_Widget::widget`是一个工厂方法,可以返回类的实例。`to()`方法可以把这个实例赋值给某个变量。
因此,在我们的插件里页可以采用类似的做法:
public static function end()
{
Typecho_Widget::widget('Widget_User')->to($user);
//把设置里的bgUrl值附给$url
$url = Typecho_Widget::widget('Widget_Options')->plugin('LoginBeautify')->bgUrl;
if (!$user->hasLogin()) {
echo '<script>$("body").css("background", "url(' . $url . ')");</script>';
}
}
这里,我们通过`jQuery`代码来修改页面背景的,这样整个插件代码就写完了。
#完整代码#:
<?php
if (!defined('__TYPECHO_ROOT_DIR__')) exit;
/**
- 登录界面美化
* - @package LoginBeautify
- @author jlice
- @version 1.0.0
- @link https://jlice.top
*/
class LoginBeautify_Plugin implements Typecho_Plugin_Interface
{
public static function activate()
{
Typecho_Plugin::factory('admin/footer.php')->end = array('LoginBeautify_Plugin', 'end');
}
public static function deactivate() {}
public static function config(Typecho_Widget_Helper_Form $form)
{
$url = new Typecho_Widget_Helper_Form_Element_Text(_t('bgUrl'), NULL, NULL, _t("背景URL"));
$form->addInput($url);
}
public static function personalConfig(Typecho_Widget_Helper_Form $form) {}
public static function end()
{
Typecho_Widget::widget('Widget_User')->to($user);
$url = Typecho_Widget::widget('Widget_Options')->plugin('LoginBeautify')->bgUrl;
if (!$user->hasLogin()) {
echo '<script>$("body").css("background", "url(' . $url . ')");</script>';
}
}
}
本文主要内容转自[木然轩][1],这只是一个基本插件的教程,有了这个基础可以查看其它人写的插件代码,像我这种不懂PHP的人都能看明白大部分^_^
看代码还得有好工具,虽然宝塔面板后台看也不麻烦,但免不了有时本地需要,推荐sublime text 3这个工具,免安装,和宝塔后台看的代码高亮一个样。