wordpress——在插件后台管理页面中添加javascript和ajax
最近在开发一个wordpress插件,需要在插件的后台管理页面上,添加自己写的javascript文件,以达到一些功能。
查了好几天的文档和资料,终于实现了。
这里先介绍下wordpress后台页面添加javascript的过程,再介绍添加ajax的过程。
添加javascript
首先我们需要知道wordpress插件开发的框架,然后再介绍javascript添加的步骤。
添加插件设置页面
开发插件,总需要在管理后台添加自己的插件设置页面、插件设置子页面,在这些页面中,可以设置和保存插件的一些运行参数。
可以将插件设置页面添加到管理后台的多个位置中。wordpress默认的管理后台面板,提供了page、post、comment和setting等默认主页面菜单。
如下图所示,也就是中文的“文章”、“页面”、“评论”和“设置”这些主页面菜单。wordpress提供了对应的API,在这些位置的底下,来添加页面。
例如我们可以在“设置”下,添加我们自己的插件设置页面,利用的是API:
add_options_page( $page_title, $menu_title, $capability, $menu_slug, $function);
我们也可以在“评论”下,添加我们自己的插件设置页面,利用的是API:
add_comments_page( $page_title, $menu_title, $capability, $menu_slug, $function);
但是呢,我们也可以在和“页面”、“文章”、“评论”这些同一级别上添加我们的插件设置页面。例如,在上图中,我的插件“cartbiner server”的设置页面,就是和“文章”等同级别的。然后再这个插件设置页面下,我们在自己添加相关的子页面。
我们要用到的API是,具体参数和含义可以查阅wordpress codex:
add_menu_page();
add_submenu_page();
最后我的实现结果是,1个插件的主设置页面,3个插件的子设置页面:
具体请参考:
添加javascript文件
这里我们想讲的是,如何在插件设置页面上添加javascript文件。
我们作为开发者,可以自己直接在输出的html页面里面利用script标签,加入javascript代码。
但是wordpress不推荐这么做,一是不好管理,而是难以避免多个代码的重复导致错误。
所以我们这里要说的,其实是利用wordpress提供的接口,在对应的页面头部中添加javascript文件。
例如,我们在上面添加了3个子设置页面,但是我们想开发一个javascript文件,只添加到“Add Cartbinet”和“Add Door”页面,其他页面都不会包含这个javascript文件,怎么实现?
wordpress提供了2种添加javascript的方法,但是我只试成功了一种,接下来我会详细介绍我的实现方法。
有哪些页面类型可以添加javascript文件?
在wordpress里面,共有以下几个页面位置,可以添加用户自定义的javascript文件。
分别是:
- 后台管理页面;
- 管理者的登录页面;
- 前台页面(也就是一般访问者看到的页面)。
以下是从wordpress插件官方开发教程里面摘录的话:
For administration pages, use admin_enqueue_scripts
.
For front-end pages use wp_enqueue_scripts
, except for the login page, in which case use login_enqueue_scripts
.
可以看到共有3种API,可以在以上三种页面类型中添加javascript文件。
显然,我们这里要用到的是API:
admin_enqueue_scripts();
添加javascript文件的过程
首先,在插件的init_hooks函数里面,在wordpress载入后台管理菜单和页面的时候,添加我们自己的插件设置页面:
add_action('admin_menu', array( 'CartbinetServer', 'cartbinet_add_pages') );
add_action('admin_enqueue_scripts', array( 'CartbinetServer', 'cartbinet_load_add_cartbinet_scripts') );
第一个add_action,是用来添加我们自己的插件设置页面的。
“admin_menu”,表示wordpress载入后台管理菜单和页面的钩子;
“cartbinet_add_pages”,添加插件设置页面的函数;
第二个add_action,是用来载入我们的javascript文件的。
“admin_enqueue_scripts”,表示wordpress插入管理页面的javascript文件的钩子;
“cartbinet_load_add_cartbinet_scripts”,载入javascript文件的函数。
我们按步骤介绍这两个函数:“cartbinet_add_pages”和“cartbinet_load_add_cartbinet_scripts”。
其次,在添加插件设置页面的函数里面,也就是cartbinet_add_pages,获取我们需要添加javascript文件的页面的hook。也就是说,我们想在哪个页面,添加javascript文件,我们就需要获得这个页面的一个标识——hook。
这个hook,是下面API的返回值。我们把页面hook,保存在一个全局的数组变量里面,这样其他函数也可以访问到:
$addCartBinetsPageHook = add_submenu_page; $addDoorPageHook = add_submenu_page
上面的代码只是是表示一下,并没有写完整。读者可以查阅API: add_submenu_page。
接下来,我们在后台管理页面载入javascript文件的函数里面,也就是函数“cartbinet_load_add_cartbinet_scripts”里面,写入如下代码。
在这个函数的最开始,我们先判断当前管理页面,是不是我们需要添加javascript文件的那两个插件子设置页面。
public static function cartbinet_load_add_cartbinet_scripts($hook) {
if ( ! in_array( $hook, self::$addPages ) )
return;
/* put jquery scriptr in the queue*/
wp_enqueue_script( 'setting-ajax-script', plugins_url( 'accerts/js/setting.js', __FILE__ ) );
$title_nonce = wp_create_nonce( 'title_example' );
wp_localize_script( 'setting-ajax-script',
'my_ajax_obj',
array(
'ajax_url' => admin_url( 'admin-ajax.php' ),
'nonce' => $title_nonce,
) );
}
wp_enqueue_script就是注册javascript文件的函数。
至于wp_localize_script则是注册ajax的函数。
wp_create_nonce是产生ajax交互密钥的函数,也就是说服务器产生一个密钥,前端javascript通过ajax向服务器请求服务数据时,需要发送这个密钥供核对。
添加ajax
添加ajax的步骤,其实和添加javascript文件的步骤是一样的。
首先,在init_hooks函数里面,注册服务器ajax响应函数:
add_action('wp_ajax_cartbinet_name_list', array( 'CartbinetServer', 'cartbinet_name_list_ajax_handler') );
我们的ajax响应函数为:
public static function cartbinet_name_list_ajax_handler () { //check nonce check_ajax_referer('title_example'); error_log('cartbinet_name_list_ajax_handler'); //get cartbinet name list from xml file, json format $names = self::cartbinet_get_name_list(); error_log(implode(" ", $names)); //return data to front end jquery script wp_send_json($names); wp_die(); // all ajax handlers should die when finished }
其次,在载入javascript文件的函数里面,注册ajax交互中要使用的全局变量,以及ajax请求所发送的url位置。
为什么要这么做,
因为ajax请求放在javascript文件里面的啊,所以先载入javascript文件,其次呢,在服务器端生成ajax密钥。最后在服务器端注册一个ajax请求和这个交互请求会使用的变量以及url位置。
public static function cartbinet_load_add_cartbinet_scripts($hook) {
if ( ! in_array( $hook, self::$addPages ) )
return;
/* put jquery scriptr in the queue*/
wp_enqueue_script( 'setting-ajax-script', plugins_url( 'accerts/js/setting.js', __FILE__ ) );
$title_nonce = wp_create_nonce( 'title_example' );
wp_localize_script( 'setting-ajax-script',
'my_ajax_obj',
array(
'ajax_url' => admin_url( 'admin-ajax.php' ),
'nonce' => $title_nonce,
) );
}
最后,我们再实现前端页面中的javascript文件,
jQuery(document).ready(function($) { //wrapper var this2 = $("#filter-by-name"); $.post(my_ajax_obj.ajax_url, { //POST request _ajax_nonce: my_ajax_obj.nonce, //nonce action: "cartbinet_name_list", //action title: 'cartbinets_names' //data }, function(data) { //callback $(this2).empty(); $.each(data, function(key, value){ var $op = new String("<option>" + value + "</option>"); $(this2).append($op); }); }); });
“my_ajax_obj”就是服务器端php所生成的ajax变量:
“my_ajax_obj.ajax_url”,保存了向服务器发送ajax请求的url地址;
“my_ajax_obj.nonce”,保存了ajax交互的密钥。
“cartbinet_name_list”,对应到服务器PHP端所注册的ajax请求标识,也就是对应在init_hook函数里面注册ajax响应函数时,设置的ajax请求标识。
也就是说前端发送的这个ajax请求,会被wordpress parse一遍,然后服务器端php根据ajax请求标识,知道要调用函数"cartbinet_name_list_ajax_handler",来响应这个ajax请求。
add_action('wp_ajax_cartbinet_name_list', array( 'CartbinetServer', 'cartbinet_name_list_ajax_handler') );
“data”,里面保存的是服务器端通过函数wp_send_json($names)返回的数据。
参考资料:
https://developer.wordpress.org/plugins/javascript/enqueuing/
http://www.solagirl.net/wordpress-ways-to-load-js-css.html
https://www.zfanw.com/blog/wordpress-add-jquery.html