admin_print_scripts是用来向WordPress后台引入js脚本文件的,这个action会在所有页面引入脚本,除非你在action调用的函数的内部做判断。要想实现只在某个页面引入特定脚本,可以借助它的另一种形式admin_print_scripts-(page_hook)。这在写主题的Theme Options或者插件的Options页面非常有用,我们希望脚本只在使用的时候加载,这样还可以避免插件冲突。

什么是page_hook

举个例子,比如我们用add_menu_page()函数在后台添加一个菜单项。

add_action( 'admin_menu', 'add_my_menu' );
function add_my_menu() {
	$page_hook = add_menu_page(__('我的地盘'), __('我的地盘'), 'manage_options', 'my-territory', 'menu_page_output_callback');
}

这是在后台会产生一个菜单叫做“我的地盘”,如下图所示

添加自定义菜单

菜单的地址是/wp-admin/admin.php?page=my-territory

add_menu_page()添加菜单成功后,会将page_hook作为返回值返回,例如我添加的这个菜单page_hook是“toplevel_page_my-territory”

每注册一个菜单,不管是顶级菜单还是次级菜单,都有自己唯一的page_hook,这就是我们区分不同页面的法宝之一。

admin_print_scripts-(page_hook)登场

现在,我们要在新注册的菜单页面引入一些自定义的脚本,要把第一段代码稍微修改一下,变成下面这样

add_action( 'admin_menu', 'add_my_menu' );
function add_my_menu() {
	$page_hook = add_menu_page(__('我的地盘'), __('我的地盘'), 'manage_options', 'my-territory', 'menu_page_output_callback'); 
	add_action( 'admin_print_scripts-' . $page_hook, 'load_my_script' );
}

function load_my_script() {
	wp_enqueue_script( 'jquery-ui-core' );
	wp_enqueue_script( 'jquery-ui-datepicker' );
}

向admin_print_scripts-(page_hook) action添加了一个函数叫做load_my_script,在这个函数中,用wp_enqueue_script()添加了WordPress内置的jquery ui datepicker脚本,这样我可以给需要输入日期的input添加一个日期选择器。

那么如何写出这个input输入框呢,要靠我们的回调函数menu_page_output_callback(),这个函数是在add_menu_page中指定的,注意一下第五个参数,这里可以指定一个php文件作为菜单页面的输出,也可以指定用函数输出,Sola选择用函数输出结构。

function menu_page_output_callback() {
?>
	<script type="text/javascript">
		jQuery(document).ready( function($){
			$('#datepicker').datepicker();
		});
	</script>
	<input type="text" id="datepicker" name="date" value="" />
<?php
}

为了省事,直接将初始化脚本写在这里了,datepicker的初始化相当简单,一句话搞定。

效果就是这样

datepicker-raw

你会惊呼这不是坑爹么,长的这么难看。没错,咱还没加样式表呢。既然脚本可以根据页面载入,那你一定能联想到样式表也可以,没错,我们下一个action即将登场。

admin_print_styles-(page_hook)

admin_print_styles-(page_hook)用法与admin_print_scripts-(page_hook)完全相同,同样要借助我们添加菜单时返回的$page_hook,所以要把这句代码插入到之前的代码中,这样我们最终的代码如下(插件形式)

<?php
/*
Plugin Name: test script
*/
add_action( 'admin_menu', 'add_my_menu' );
function add_my_menu() {
	$page_hook = add_menu_page(__('我的地盘'), __('我的地盘'), 'manage_options', 'my-territory', 'menu_page_output_callback'); 
	add_action( 'admin_print_scripts-' . $page_hook, 'load_my_script' );
	add_action( 'admin_print_scripts-' . $page_hook, 'load_my_style' );
}

//加载脚本
function load_my_script() {
	wp_enqueue_script( 'jquery-ui-core' );
	wp_enqueue_script( 'jquery-ui-datepicker' );
}

//加载样式表,直接用了在线的jquery-ui样式表
function load_my_style() {
	wp_enqueue_style( 'jquery-datepicker-css', 'http://code.jquery.com/ui/1.8.21/themes/ui-lightness/jquery-ui.css');
}

//输出页面的内容
function menu_page_output_callback() {
?>
	<script type="text/javascript">
		jQuery(document).ready( function($){
			$('#datepicker').datepicker();
		});
	</script>
	<input type="text" id="datepicker" name="date" value="" />
<?php
}
?>

最终效果如下图所示

datepicker-final

结束语

只在使用时引入脚本和样式表,既可以节省流量,也能防止不必要的冲突,特别主要应当使用wp_enqueue_scriot()加载脚本,使用wp_enqueue_style加载样式表,这样可以避免重复加载,也方便其它插件在必要的时候可以将他们移除。

最后一点,要知道WordPress默认带有哪些js脚本,WordPress 3.3以后就带有jquery ui库了,很多插件会使用这些内置的脚本,却不一定规规矩矩的只在自己的页面添加,如果你引入了其它位置的jquery ui库,可能导致冲突。