不明白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> %1$s</li>', $function['function'] ); } else { $cname = is_string($function['function'][0]) ? $function['function'][0] : get_class($function['function'][0]); $line = sprintf('<li> %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都没加了啦!
对于喜欢DIY主题或者做主题的人来说还是大有帮助的
不知道输出来是什么样子,也不抓个图看看。
图已补。
其实我已经在为半年后的换服务器未雨绸缪了,在尽量减少传图。一旦新空间硬盘有限咋整?
外链?
不愿假手于人。早年被各种各样的图床伤过。
这应该就是WP的强大之处了。技术玩家才用得到~
准备换主机?当年整图床伤了,现在已经跨过那个大坑。图片压缩一番之后放在自己主机上比较好。加速就交给七牛这样的服务商去弄了。不怕图片多
话说我帮朋友维护的那个站,不到三百篇左右文章,图片已经超过两千张了……
我现在的服务器买的时候很优惠,3.95刀一个月,但有陷阱,新手期过后要9.95刀一个月,太不划算了,所以到秋天之前一定要换。我之前也是吃过图床的亏,就再也不把图放别人服务器上了。
话说你问这俩问题我以前都解释过啊,说明你看我文真够不认真了。
之前抱过一条大腿,趁着人家还着迷我的时候,让人家甘之如饴地给我写了一堆码用来移除我不要的功能,基本上都是靠add_filter和remove_action。
这么玩的一个缺点是每次升级得盯着WP的文档看,说不好就有什么东西改名了或者参数变了。
听口气,人家现在为啥不迷你了?
这个好玩,斗胆收下了。