鸿 网 互 联 www.68idc.cn

当前位置 : 服务器租用 > cms安装教程 > WordPress > >

Wordpress插件开发系列(上)

来源:互联网 作者:佚名 时间:2015-10-18 05:56
Wordpress插件 开发 系列 (上) 2010-05-31 15:41:20 来源:LAMP兄弟连 作者:张庆 浏览: 1028 次 评论: 0 条 一、Wordpress插件机制浅析 Wordpress通过插件机制,使一套基于基本的CMS系统的博客系统有了很大的扩展能力。 第一、Wordpress的插件与文件系统的
Wordpress插件开发系列(上)
2010-05-31 15:41:20 来源:LAMP兄弟连 作者:张庆 浏览:1028次 评论:0

一、Wordpress插件机制浅析 Wordpress通过插件机制,使一套基于基本的CMS系统的博客系统有了很大的扩展能力。 第一、Wordpress的插件与文件系统的接口为wp-content\plugins文件夹。接口主文件可以直接放置在该文件夹下,如果牵涉的文件较多,也可以再建立一个文件夹..

一、Wordpress插件机制浅析
    Wordpress通过插件机制,使一套基于基本的CMS系统的博客系统有了很大的扩展能力。
    第一、Wordpress的插件与文件系统的接口为wp-content\plugins文件夹。接口主文件可以直接放置在该文件夹下,如果牵涉的文件较多,也可以再建立一个文件夹,放在该文件夹下,该文件夹最好与接口主文件的名字相同:如主接口文件为myplugin.php,则文件夹名字可以为myplugin。
    插件大体上可划分为两个部分:前面是注释,注释下是代码区。
    注释部分大体如下示例:
1 /*
2 Plugin Name: MyCopyright
3 Plugin URI:http://www.why100000.com
4 Version: 0.1
5 Author: 网眼
6 Author URI:http://blog.why100000.com
7 Description: 把字符串“<!--mycopyrigth-->”替换为版权信息:show copyright once there are letters match “<!--mycopyrigth-->”.
8 you should config your copyright information in this file,with this verison.
9 */

    不要简单的看待以上的注释,不是随便写的,是固定的格式,可看做是插件的元信息(meta)。冒号前面的形如“Plugin Name”的信息都是有用的,作为插件的相关信息,会出现在系统设置等菜单下,作为本插件的标识信息。冒号后面的信息可以根据需要改写。冒号连接的一行信息类似于表中的一条记录,且不能换行。
    再例如,Wordpress2.3.3有个插件,其头部注释如下:
1 /*
2 Plugin Name: Hello Dolly
3 Plugin URI:http://wordpress.org/#
4 Description: This is not just a plugin, it symbolizes the hope and enthusiasm of an entire generation summed up in two words sung most famously by Louis Armstrong: Hello, Dolly. When activated you will randomly see a lyric from <cite>Hello, Dolly</cite> in the upper right of your admin screen on every page.
5 Author: Matt Mullenweg
6 Version: 1.5
7 Author URI:http://photomatt.net/
8 */

    第二、代码部分就复杂了。不过一般应该有类似add_action('admin_footer', 'hello_dolly');的PHP代码,也就是至少需要执行add_action函数,当Wordpress执行admin_footer系统函数的时候,执行插件自定义的hello_dolly函数。hello_dolly函数中就写有特点插件的逻辑。
    大家可以去看插件hello.php,很简单,功能是:当点击Wordpress后台管理的菜单项时,在页面右上角随机出现一些类似“毛主席语录”的“口号”(插件的Description里准确描述了其功能)。插件里有两处用了add_action函数:
1 add_action('admin_footer', 'hello_dolly'); add_action('admin_head','dolly_css');

    分别执行了自定义函数hello_dolly和dolly_css,用于显示信息和定义CSS样式。
    第三、我模仿网络上的例子,写了一个最简化的Wordpress插件,全部代码如下:
1 <?php /* Plugin Name: MyCopyright Plugin URI: http://www.why100000.comVersion: 0.1 Author: 网眼 Author URI: http://blog.why100000.comDescription: 把字符串“&lt;!--mycopyrigth--&gt;”替换为版权信息:show copyright once there are letters match “&lt;!--mycopyrigth--&gt;”. you should config your copyright information in this file,with this verison. */ //WP执行the_content函数时,调用插件自定义函数why100000_showcopyright,对文章内容进行过滤 add_filter('the_content', 'why100000_showcopyright');function why100000_showcopyright($content){ $search = "<!--mycopyright-->"; $replace = "<font color='red'>本文由网眼原创。转载请注明<a href='http://blog.why100000.com' target='_blank'>原创作者:网眼(张庆)</a></font>"; $content= str_replace($search, $replace, $content); return$content; } ?>

     功能是:把文章中的字符串“<!--mycopyrigth-->” 替换为版权信息字符串。add_filter其实是一个回调函数,用于在Wordpress的the_content函数执行的时候,处理一些事务。具体意义参见自定义why100000_showcopyright函数。
    用法:保存为一个PHP文件,拷贝到插件目录下,或见一个文件夹,拷贝到文件夹下。这样,在插件管理界面里,就可以看见该插件的列表信息,点击“启用”使插件生效。然后,写博客的时候,在源代码里添加<!--mycopyright-->注释,保存博客后,浏览博客,会看到该注释被替换成了红色字体的字符串“本文由网眼原创。转载请注明原创作者:网眼(张庆)”,且包含一个链接。
    这个简单的例子可以增加一些额外的功能,以使其更强大。
    这仅仅是WP插件的应用层的知识。要进一步了解Wordpress的插件机制,需要阅读Wordpress的源代码。好在是开源的,应该从里面学到更多的经验和技巧。
二、Wordpress插件示例之一
    这个Wordpress插件,除过能够在插件管理面板管理外(可以被开启和禁用),还能够在“设置”菜单下对插件进行配置,使插件的功能可以得到扩展。本插件可以实现对博客文章中的任意字符串进行替换。
    以下代码中,why100000_keyword和why100000_replace作为选项文本域标识变量,其值被option.php取到并保存到数据库的wp_options表中。
    get_option("why100000_keyword")和get_option("why100000_replace")语句用于从wp_options表中取出数据。
01 <?php
02 /*
03   Plugin Name: MyCopyright
04   Plugin URI:http://www.why100000.com
05   Version: 0.1
06   Author: 网眼(张庆-陕西西安-开开工作室-http://www.myopenit.cn)
07   Author URI:http://blog.why100000.com
08   Description: 把字符串“&lt;!--mycopyrigth--&gt;”替换为版权信息:show copyright once there are letters match “&lt;!--mycopyrigth--&gt;”.
09   you should config your copyright information in this file,with this verison.
10 */
11 //加到“设置”主菜单下
12 add_action('admin_menu','why100000_add_options_page');
13 function why100000_add_options_page(){
14     add_options_page('MyCopyright', 'MyCopyright-Config', 8,'mycopyright.php', 'why100000_myCopyright_mainpage');
15 }
16 function why100000_myCopyright_mainpage(){
17 ?>
18     <form name="formamt" method="post"action="options.php">
19     <?php wp_nonce_field('update-options') ?>
20     <divclass="wrap">
21         MyCopyright is active.<br><br>
22         <h2>MyCopyright Config (版权插件配置)</h2>
23         <div id="msgall">
24             <fieldsetclass="options">
25                 <legend>keyword(原字符串):</legend>
26                 <p>
27                     <textarea >"width: 80%;" rows="5" cols="40"name="why100000_keyword"><?php echo get_option("why100000_keyword");?></textarea>
28                 </p>
29             </fieldset>
30             <fieldsetclass="options">
31                 <legend>replacement(代替的字符串):</legend>
32                 <p>
33                     <textarea >"width: 80%;" rows="5" cols="40"name="why100000_replace"><?php echo get_option("why100000_replace");?></textarea>
34                 </p>
35             </fieldset>
36         </div>
37         <pclass="submit">
38             <input type="submit" value="<?php _e('Update Options &raquo;') ?>" name="update_message"/>
39         </p>
40         <input type="hidden" name="action"value="update">
41         <input type="hidden" name="page_options"value="why100000_keyword,why100000_replace">
42     </div>
43     </form>
44     <?php
45 }
46 add_action('activate_mycopyright/mycopyright.php','why100000_copyright_install');
47 //插件第一次被“启用”时执行,作为初始值保存到表wp_options中
48 function why100000_copyright_install(){
49     add_option("why100000_keyword", "<!--mycopyright-->");
50     add_option("why100000_replace", "我的版本");
51 }
52 //WP执行the_content函数时,调用插件自定义函数why100000_showcopyright,对文章内容进行过滤
53 add_filter('the_content','why100000_showcopyright');
54 function why100000_showcopyright($content){
55     $search = get_option("why100000_keyword");  //"<!--mycopyright-->";
56     $replace= get_option("why100000_replace");  //代替的字符串;
57     $content= str_replace($search, $replace,$content);
58     return$content;
59 }
60 ?>

三、Wordpress插件示例之二-对示例一的重构
    示例一已经完全可以工作了,这个在Wordpress2.3.3和2.9.1版本中已经得到证实。但示例一有几个缺陷。
    由于Wordpress的插件众多,全世界有很多程序员包括我们中国的程序员,都在为它开发插件,这些插件往往被一起安装在一套Wordpress系统中协调工作,这未免会产生冲突的情况。
    为了隔离各个插件的代码,我们需要想一些办法。而把插件代码封装在一个类结构中是个行之有效的方法之一。正确应用一些检测函数,可以保证只要插件类名不冲突,类所包含的成员函数就不会与其它插件冲突。这大大增强了插件代码的健壮性。而且插件类名是否冲突也作为代码容错检测的一部分,使系统不至于出现严重的崩溃。
    请参看下面的一个完整的Wordpress插件代码,是参考以上考虑,对示例一的代码的完全重构。
01 <?php
02 /*
03   Plugin Name: MyCopyright
04   Plugin URI:http://www.why100000.com
05   Version: 0.1
06   Author: 网眼(张庆-陕西西安-开开工作室-http://www.myopenit.cn)
07   Author URI:http://blog.why100000.com
08   Description: 把字符串“&lt;!--mycopyrigth--&gt;”替换为版权信息:show copyright once there are letters match “&lt;!--mycopyrigth--&gt;”.
09   you should config your copyright information in this file,with this verison.
10 */
11 if (!class_exists("why100000_Plugin")){
12     classwhy100000_Plugin{
13     //构造函数
14     function why100000_Plugin(){}
15     //加到“设置”主菜单下
16     function why100000_add_options_page(){
17         add_options_page('MyCopyright', 'MyCopyright-Config', 8,'mycopyright.php',
18 array(&$this,'why100000_myCopyright_mainpage'));
19     }
20     function why100000_myCopyright_mainpage(){
21 ?>
22         <form name="formamt" method="post"action="options.php">
23         <?php wp_nonce_field('update-options') ?>
24         <divclass="wrap">
25             MyCopyright is active.<br><br>
26                 <h2>MyCopyright Config (版权插件配置)</h2>
27                 <div id="msgall">
28                     <fieldsetclass="options">
29                     <legend>keyword(原字符串):</legend>
30                     <p>
31                     <textarea >"width: 80%;" rows="5" cols="40"name="why100000_keyword"><?php echo get_option("why100000_keyword");?></textarea>
32                     </p>
33                     </fieldset>
34                     <fieldsetclass="options">
35                     <legend>replacement(代替的字符串):</legend>
36                     <p>
37                     <textarea >"width: 80%;" rows="5" cols="40"name="why100000_replace"><?php echo get_option("why100000_replace");?></textarea>
38                     </p>
39                     </fieldset>
40                 </div>
41                 <p class="submit"><input type="submit" value="<?php _e('Update Options &raquo;') ?>" name="update_message"/></p>
42                 <input type="hidden" name="action"value="update">
43                 <input type="hidden" name="page_options"value="why100000_keyword,why100000_replace">
44             </div>
45         </form>
46         <?php
47         }
48         //插件第一次被“启用”时执行,作为初始值保存到表wp_options中
49         function why100000_copyright_install(){
50             add_option("why100000_keyword", "<!--mycopyright-->");
51             add_option("why100000_replace", "我的版本");
52         }
53         //WP执行the_content函数时,调用该函数,对文章内容进行过滤
54         function why100000_showcopyright($content){
55             $search = get_option("why100000_keyword");  //"<!--mycopyright-->";
56             $replace= get_option("why100000_replace");  //代替的字符串;
57             $content= str_replace($search, $replace,$content);
58             return$content;
59         }
60     }
61 }
62 if (class_exists("why100000_Plugin")){
63     $MyPlugin = newwhy100000_Plugin();
64 }
65 if (isset($MyPlugin)){
66     add_action('activate_mycopyright/mycopyright.php', array(&$MyPlugin,'why100000_copyright_install'));
67     add_action('admin_menu', array(&$MyPlugin,'why100000_add_options_page'));
68     add_filter('the_content', array(&$MyPlugin,'why100000_showcopyright'));
69 }
70 ?>

    于是,我们归纳出一个相对完善的Wordpress插件代码书写构架:
01 <?php
02 /* 插件注释部分...... */
03 /* 插件代码部分: */
04 /* 插件类定义: */
05 if (!class_exists("插件类名")){
06 class 插件类名
07 {
08     /* 全部插件函数...... */
09 }
10 }
11 /* 实例化插件类: */
12 if (class_exists("插件类名")){
13 $MyPlugin = new 插件类名();
14 }
15 /* 定义插件事件函数: */
16 if (isset($MyPlugin)){
17 add_action('activate_....php', array(&$MyPlugin, ...));
18 add_action('admin_menu', array(&$MyPlugin, ...));
19 add_filter('the_content', array(&$MyPlugin, ...));
20 }
21 ?>

四、在Wordpress插件中使用样式表
    要让插件功能非凡,难免需要java script和CSS的参与。本节将举例在Wordpress插件中插入CSS代码。下一节将试图添加JS脚本。
    1、插件的文件夹结构
    插件主文件可以直接放置在plugin文件夹下,也可以建立一个文件夹,放置在该文件夹下。由于插件的相关文件可能较多,所以为了清晰的管理插件,建议把插件文件部署于自己的文件夹下。而且JS、CSS、图片文件也按文件夹分类放置,通常的文件夹可以取名为js、css和images。
    一个示例的文件夹结构如下:
        ├─ ~\plugins
        │  ├─ css           (样式表文件)
        │  ├─ images        (图片文件)
        │  ├─ js            (脚本文件)
        │  ├─ php          (相关PHP脚本)
        │  ├─ myplugin.php  (插件主文件)
    2、示例插件实现的功能
        在文章末尾加一段文字:<span id="myalert">弹出警告对话框</span>,用样式表中的样式代码改变其样式。文章末尾添加的文字,可以在插件设置面板里进行定制修改,比较灵活。
    3、完整代码及其解释
        要往文章中加入CSS代码,一种是直接打开Wordpress的themes有关模板文件直接添加,但仅仅作用于这个模板页面。这样做可以系统的运行效率比较高,但不够灵活。而使用插件来实现,实现的结果对所有的themes有效。
    在Wordpress插件中使用样式表,主要使用了add_head这个API事件。
    首先编辑css.css文件,内容如下:
1 #myalert{
2    background-color:#006;
3    color:#fff;
4    cursor:hand;
5 }

    保存于css文件夹下。该段样式表可以按需要定制,但要确保不能与其它样式冲突,否则得不到预期的结果。该段样式表代码对id="myalert"的标签进行修饰。
    然后定义插件类的成员函数why100000_addHeaderCode(),输出引用样式表的标签。注意css文件的路径。函数完整代码如下:
1 function why100000_addHeaderCode(){
2     echo '<link type="text/css" rel="stylesheet" href="'. get_bloginfo('wpurl') . '/wp-content/plugins/test-css-js/css/css.css">';
3 }

    然后调用以下代码:
1 add_action('wp_head',array(&$MyPlugin_testcssjs,'why100000_addHeaderCode'));

    使生成文章页面head部分时,添加<link ...>对样式表的调用。
    本例的完整代码如下,关键代码有注释
view source
print?
01 <?php
02 /*
03   Plugin Name: Test_CSS_JS
04   Plugin URI:http://www.why100000.com
05   Version: 0.1
06   Author: 网眼(张庆-陕西西安-开开工作室-http://www.myopenit.cn)
07   Author URI:http://blog.why100000.com
08   Description: 测试样式表和JS脚本:在文章末尾加一段文字,改变样式,点击弹出对话框。
09 */
10 if (!class_exists("why100000_Test_css_js")){
11     classwhy100000_Test_css_js{
12     //构造函数
13     function why100000_Test_css_js(){}
14     //加到“设置”主菜单下
15     function why100000_add_options_page(){
16         add_options_page('Test_CSS_JS', 'Test_CSS_JS-CFG', 8,basename(__FILE__), array(&$this, 'why100000_Test_CSS_JS_mainpage'));
17     }
18     function why100000_Test_CSS_JS_mainpage(){
19 ?>
20         <form name="formamt" method="post"action="options.php">
21         <?php wp_nonce_field('update-options') ?>
22         <divclass="wrap">
23             Test_CSS_JS is active.<br><br>
24             <h2>Test_CSS_JS Config(插件配置)</h2>
25             <div id="msgall">
26                 <fieldsetclass="options">
27                 <legend>Word(字符串):</legend>
28                 <p><textarea >"width: 80%;" rows="5" cols="40"name="why100000_word"><?php echo get_option("why100000_word");?></textarea></p>
29                 </fieldset>
30             </div>
31             <p class="submit"><input type="submit" value="<?php _e('Update Options &raquo;') ?>" name="update_message"/></p>
32             <input type="hidden" name="action"value="update">
33             <input type="hidden" name="page_options"value="why100000_word">
34         </div>
35         </form>
36 <?php
37         }
38         //插件第一次被“启用”时执行,作为初始值保存到表wp_options中
39         function why100000_install(){
40  
41         add_option("why100000_word", "<span id=\"myalert\">弹出警告对话框</a>");
42         }
43         //添加head信息
44         function why100000_addHeaderCode(){
45             echo '<link type="text/css" rel="stylesheet" href="'. get_bloginfo('wpurl') . '/wp-content/plugins/test-css-js/css/css.css">';
46         }
47         //WP执行the_content函数时,调用该函数,对文章内容进行过滤
48         function why100000_appendString($content){
49             $content .= get_option("why100000_word");
50             return$content;
51         }
52     }
53 }
54 if (class_exists("why100000_Test_css_js")){
55     //$MyPlugin_testcssjs 变量不能与别的插件冲突!
56     $MyPlugin_testcssjs = newwhy100000_Test_css_js();
57 }
58 if (isset($MyPlugin_testcssjs)){
59     add_action('activate_test-css-js/test-css-js.php',array(&$MyPlugin_testcssjs, 'why100000_install'));
60     add_action('admin_menu', array(&$MyPlugin_testcssjs,'why100000_add_options_page'));
61     add_action('wp_head',array(&$MyPlugin_testcssjs,'why100000_addHeaderCode'),1);
62     add_filter('the_content', array(&$MyPlugin_testcssjs,'why100000_appendString'));
63 }
64 ?>
网友评论
<