最近在開發一個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