wordpress显示当前页面钩子列表的widget

不明白wordpress的filter和action为何物的,不必往下再看。

玩wordpress稍微进阶一点之后,wppers就会明白filter和action机制是WP的精髓所在。除非简单粗暴地修改源码,否则插件php部分的功能的实现都是通过添加或修改各种钩子来实现的。
尤其是开发程度比较高的插件,追求大而全,会在不同的时机伸出各种各样的钩子。可能这些插件的很多功能是用不到的,把用不到的功能空跑一遍当然就会影响速度。这就造成了很多人口中的“插件影响速度”。

然而我是个大插件党。人家写好的功能,何苦自己再搞一遍呢?又累又不安全。
但我一直追求最小功能的原则,会把自己用不到的功能屏蔽掉。小插件还好说,搜一下add_filter和add_action,然后判断一下用途做出取舍即可。可对于源码量上M的重型插件来说,这么搜就是给自己找不痛快。
那么,把某个页面(index/search/page/single)上的钩子打印出来,不就可以了吗?
搜了一圈没找到现成的,只好自己动手。即使是在调试的时候,我也不愿意多打哪怕一行字。所以就作成了widget的形式,只有super user能看到内容。至于单栏爱好者……调试的时候先换成个2017呗?

用法很简单,后台挂上这个widget,在第二栏里填写想查看的filter或者action就可以了,中间用半角逗号分割。回前台刷新就能看到结果。如果是类的成员函数,函数前会显示类名。
不是不能作成打印所有钩子,只是觉得没必要,关注重点区域就好。

下面是代码,想要的收走。

class APIP_Widget_Hook_List extends WP_Widget {

	public function __construct() {
		$widget_ops = array(
			'classname' => 'APIP_Widget_Hook_List',
			'description' => '显示当前页面的钩子列表',
			'customize_selective_refresh' => true,
		);
		parent::__construct( 'APIP_Widget_Hook_List', '钩子列表', $widget_ops );
	}

	public function widget( $args, $instance ) {
		$title =  empty($instance['title']) ? '钩子列表' : $instance['title'];
        $filters = explode(',',$instance['hooks']);
        if ( !is_super_admin() )
            return;
        if ( empty( $filters ) )
            return;
		echo $args['before_widget'];
		if ( $title ) {
			echo $args['before_title'] . $title . $args['after_title'];
		}
        $content = '<ul>';
        $session = '';
        $line = '';
        foreach ($filters as $filter){
            $tags = $GLOBALS['wp_filter'][ $filter ];
            if (empty($tags))
                continue;
            $session = sprintf('<li><strong>%s</strong></li>', $filter );
            foreach ( $tags as $priority => $tag )
            {
                foreach ( $tag as $identifier => $function )
                {
                    if ( is_string( $function['function'] ) )
                    {
                        $line = sprintf('<li>&nbsp;&nbsp;%1$s</li>', $function['function'] );
                    }
                    else
                    {
                        $cname = is_string($function['function'][0]) ? $function['function'][0] : get_class($function['function'][0]);
                        $line = sprintf('<li>&nbsp;&nbsp;%1$s::%2$s</li>', $cname, $function['function'][1]);
                    }
                    $session .= $line;
                }
            }
            $content .= $session;
        };
        $content .= '</ul>';
        echo $content;

		echo $args['after_widget'];
	}

	public function update( $new_instance, $old_instance ) {
		$instance = $old_instance;
		$instance['title'] = sanitize_text_field( $new_instance['title'] );
        $instance['hooks'] = sanitize_text_field( $new_instance['hooks'] );

		return $instance;
	}


	public function form( $instance ) {
		$instance = wp_parse_args( (array) $instance, array( 'title' => '', 'hooks' => 'the_content,wp_enqueue_scripts,wp_head,wp_footer' ) );
		$title = sanitize_text_field( $instance['title'] );
        $hooks = sanitize_text_field( $instance['hooks'] );
?>
			<p><label for="<?php echo $this->get_field_id('title'); ?>"><?php _e('Title:'); ?></label> <input class="widefat" id="<?php echo $this->get_field_id('title'); ?>" name="<?php echo $this->get_field_name('title'); ?>" type="text" value="<?php echo esc_attr($title); ?>" /></p>
            <p><label for="<?php echo $this->get_field_id('hooks'); ?>"><?php echo '要查看的hook,半角逗号分隔:'; ?></label> <input class="widefat" id="<?php echo $this->get_field_id('hooks'); ?>" name="<?php echo $this->get_field_name('hooks'); ?>" type="text" value="<?php echo esc_attr($hooks); ?>" /></p>
<?php
	}
}

add_action( 'widgets_init', create_function( '', 'return register_widget( "APIP_Widget_Hook_List" );' ) ); 

==== UPDATE ====
补效果图。twenty seventeen暗色风格,底部sidebar。其实我一句css都没加了啦!
2017-01-18_16.07.05

已有7条评论

路过的人
  1. 对于喜欢DIY主题或者做主题的人来说还是大有帮助的

  2. 不知道输出来是什么样子,也不抓个图看看。

    1. 图已补。
      其实我已经在为半年后的换服务器未雨绸缪了,在尽量减少传图。一旦新空间硬盘有限咋整?

        1. 不愿假手于人。早年被各种各样的图床伤过。

  3. 这应该就是WP的强大之处了。技术玩家才用得到~

  4. 准备换主机?当年整图床伤了,现在已经跨过那个大坑。图片压缩一番之后放在自己主机上比较好。加速就交给七牛这样的服务商去弄了。不怕图片多

    话说我帮朋友维护的那个站,不到三百篇左右文章,图片已经超过两千张了……

    1. 我现在的服务器买的时候很优惠,3.95刀一个月,但有陷阱,新手期过后要9.95刀一个月,太不划算了,所以到秋天之前一定要换。我之前也是吃过图床的亏,就再也不把图放别人服务器上了。
      话说你问这俩问题我以前都解释过啊,说明你看我文真够不认真了。

  5. 之前抱过一条大腿,趁着人家还着迷我的时候,让人家甘之如饴地给我写了一堆码用来移除我不要的功能,基本上都是靠add_filter和remove_action。

    1. 这么玩的一个缺点是每次升级得盯着WP的文档看,说不好就有什么东西改名了或者参数变了。
      听口气,人家现在为啥不迷你了?

你好,新朋友。留言前请先填写昵称邮箱