从零开始编写并托管WordPress插件:NoBaidu抵制百度插件

最近被一篇称为《搜索引擎百度已死》的文章被刷屏了,笔者本身就非常不喜欢百度,趁放寒假没有事情干,琢磨这在自己的网站上写一个插件。当访问者从百度进入网站,则在页面顶部显示一段用户自定义的阻止标语。顺便搞清楚Wordpress插件的原理。

上图就是NoBaidu的一个截图,本文按照我的编写顺序,分为——

  • 如何编写一个Wordpress插件
  • 如何将编好的插件托管到云端

另外,插件的源代码在我的github中开源,读者可以对照理解。

如何编写一个wordpress插件

编写Wordpress插件的教程网上很多,我就不重新造轮子了,我自己是在 如何开发一个WordPress如何开发一个WordPress插件 这篇文章中学到的,其核心要义就是钩子函数——

在Wordpress渲染一个页面的时候,在很多关键位置设置钩子(比如页面渲染开头,渲染器启动后等位置),而插件可以自定义的在任何钩子上挂载自己的函数,这样当页面渲染到了指定位置时,插件可以做一些自己的事情。

add_filter('robots_txt', array(this, 'robots_txt_edit'), 10, 2);</code></pre> <!-- /wp:code -->  <!-- wp:paragraph --> 比如下面代码就可以在robots.txt渲染时,运行<span class="lang:default decode:true  crayon-inline ">this->robots_txt_edit 指定的插件处理模块。

而以NoBaidu插件为例,我们需要支持如下逻辑——

  • 当普通用户访问时,检查用户的请求头的REFERER域是不是baidu域名下的URL
  • 当用户来自百度时,注册一个钩子函数,在页面渲染开始时,加入一个固定在页面顶部的,包含了自定义文字的HTML元素。
  • 当请求robots.txt时,返回禁止Baidu爬虫的robots文字

除此之外,还需要一些额外的代码,来保证我们的插件可以正常使用

  • 在用户是管理员的时候,生成插件设置页面,在其中可以设置显示的自定义抵制文字,用户选择是否组织百度爬虫,以及抵制文字是显示在顶端还是页面中部等等...
  • 编写插件安装、卸载时的逻辑,保证安装时初始化配置信息,卸载时删除配置信息,做到无残留

上述的逻辑,都集中到了下面的代码中,该代码使用一个类包裹了所有的函数(其作用类似于C++中的Namespace,用于最小化命名冲突)

<?php  
/*
 * Plugin Name: No-baidu plugin
 * Plugin URI: http://mhy12345.xyz/no-baidu/
 * Description: 当访问者通过百度访问网站时,此插件将在页面的顶端,显示一段抵制信息.
 * Version: 1.1
 * Author: mhy12345
 * Author URI: http://mhy12345.xyz/no-baidu/
 * License: GPL
 * */
include 'no-baidu-options.php';
class NoBaiduPlugin
{
	protected static instance; 	privateoptions;
	private function __construct() { //挂载钩子函数
		add_filter('robots_txt', array(this, 'robots_txt_edit'), 10, 2); 		add_action("wp_head", array(this, "no_baidu_main"));
		register_activation_hook( __FILE__, array(this, 'no_baidu_install')); 		register_deactivation_hook( __FILE__, array(this, 'no_baidu_remove'));
		this->options = get_option('no_baidu_option', false); 	} 	public static function get_instance() { //单例模式 		if (null === self::instance) {
			self::instance = new self(); 		} 		return self::instance;
	}
	public function no_baidu_main(){ //判断是否显示抵制文字,并调用对应的文本生成代码
		if(stristr(_SERVER["HTTP_REFERER"],"www.baidu.com")) 		{ 			if (this->options['method'] == 0) {
				wp_enqueue_style( 'no_baidu_style', plugins_url( 'css/no-baidu-view-header.css', __FILE__ ));
				include "views/header.php";
			}
			else {
				wp_enqueue_style( 'no_baidu_style', plugins_url( 'css/no-baidu-view-page.css', __FILE__ ));
				include "views/page.php";
			}
		}
	}
	public function no_baidu_install() {  //插件安装时,进行默认设置
		no_baidu_options = Array();no_baidu_options['method'] = 0;
		no_baidu_options['change_robots'] = 0;no_baidu_options['warn_text'] = '我们发现您是通过百度找到这个页面的,不过我们并不推荐这么做,不妨考虑用其他搜索引擎。';
		add_option("no_baidu_option", no_baidu_options); 	} 	public function no_baidu_remove() {  //插件卸载时,取消设置 		delete_option("no_baidu_option"); 	} 	public function robots_txt_edit(output, public) //修改robots.txt 	{ 		if (this->options['change_robots'] == 1) {
			output .= "User-agent: baiduspider\nDisallow: /\n";output .=  apply_filters('robots_txt_rewrite_footer', "\n\n\n\n# This robots.txt file was modified by No-baidu: https://wordpress.org/plugins/robotstxt-rewrite/\n");
		}
		return output; 	} }no_baidu_plugin = NoBaiduPlugin::get_instance();
if (is_admin()) include_once ('no-baidu-options.php'); //如果是管理员页面,生成Setting界面
?>

看懂了上面的代码,是不是觉得Wordpress编写插件非常简单? 上述代码中引用的其他php代码,大家可以在我的github中自行查阅。

将自己写好的插件托管到wordpress云端

WordPress官网的Plugin目录最低端,有一个Add Your Plugin分区,这个分区详细介绍了该如何将你的Wordpress插件托管至wordpress.org,一般来说,读完上述的文章,你就已经能够自主把自己的插件丢到云端了。不过我准备从自己的经历出发,来大致讲一讲流程。

WordPress.org自己维护了一个svn仓库,最终会获得自己插件的专属仓库,你可以使用svn提供的版本控制,自行升级、修订等等。而想要获得自己插件的svn仓库,你就需要把自己的插件的最初版提交给官方审核。提交入口在这里。这里写几个提交的注意事项吧——

  • 最重要的是要知道php没有命名空间之说,所以一切全局变量都应该防止冲突。一个比较取巧的做法就是像上文一样,将你自己的程序包裹在一个class里面,而class以自己的插件名称命名。(我就因为配置的class命名为MySettingClass被官方打回来了)
  • 不要有额外的文件,之前写插件的时候,把网上别人插件的代码拷贝到了自己的目录,本来只是想照着抄一抄,结果忘删了,这个也被审核人发现了。
  • README.txt按照官方的标准格式写。

网站上面说的是7个工作日,结果我第一天晚上提交了初版的zip包,第二天早上就收到了审核者的邮件。按照要求修改了一些类名,并删除了无关文件后,我直接把zip包附在了回复中,第三天早上就拿到了通过的消息,并且获得了svn仓库的访问权限。开源社区真的非常强大?

第一次要求修改的邮件
成功通过审核

接下来就是上传仓库了,如果读者会使用git的话,就别自己去学svn了,照着官方指南走一遍,就完全学会了。和git的pull, add, commit, push, tag如出一辙。

当你的first commit上传到远程仓库,并且readme.txt没有什么问题的话,你应该是可以立即在插件商店中搜索到自己写的插件的。

到这里我们在wordpress上面第一个插件就做好啦!

如果你觉得本文有用的话,欢迎到我的github仓库Star或Contribute~

让我们一起抵制Baidu吧~

参考文章

  • 【一个前人的代码】:http://ju.outofmemory.cn/entry/222836
  • 【如何开发Wordpress插件】:https://www.wpdaxue.com/writing_a_plugin.html
  • 【官方文档】:https://wordpress.org/plugins/developers/

发表评论

电子邮件地址不会被公开。 必填项已用*标注

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据