當(dāng)前位置:首頁(yè)>WordPress建站>WordPress開發(fā)>使用WordPress REST API創(chuàng)建WordPress設(shè)置頁(yè)面

使用WordPress REST API創(chuàng)建WordPress設(shè)置頁(yè)面

WordPress REST API的許多重要用途之一就是改善您的插件或主題設(shè)置屏幕。添加自定義REST API端點(diǎn)后,通過(guò)AJAX獲取保存的設(shè)置并通過(guò)AJAX(即無(wú)額外頁(yè)面刷新)保存設(shè)置將變得更加簡(jiǎn)單。

使用WordPress REST API代替admin-ajax不僅性能更高,而且還可以使WordPress核心在清理和驗(yàn)證方面完成大部分繁重的工作。

在本文中,我們將逐步完成創(chuàng)建設(shè)置表單頁(yè)面的每個(gè)步驟,并使用WordPress REST API處理該表單。

添加設(shè)置頁(yè)面

在開始設(shè)計(jì)設(shè)置頁(yè)面之前,我們需要向WordPress儀表板添加菜單或子菜單項(xiàng),您可以在其中放置設(shè)置表單。在此頁(yè)面上,您將需要加載CSS和JavaScript文件。

這是一個(gè)入門類:

<?php
class Apex_Menu {
	/**
	 * Menu slug
	 *
	 * @var string
	 */
	protected $slug = 'apex-menu';
	/**
	 * URL for assets
	 *
	 * @var string
	 */
	protected $assets_url;
	/**
	 * Apex_Menu constructor.
	 *
	 * @param string $assets_url URL for assets
	 */
	public function __construct( $assets_url ) {
		$this->assets_url = $assets_url;
		add_action( 'admin_menu', array( $this, 'add_page' ) );
		add_action( 'admin_enqueue_scripts', array( $this, 'register_assets' ) );
	}
	/**
	 * Add CF Popup submenu page
	 *
	 * @since 0.0.3
	 *
	 * @uses "admin_menu"
	 */
	public function add_page(){
		add_menu_page(
			__( 'Apex Page', 'text-domain' ),
			__( 'Apex Page', 'text-domain' ),
			'manage_options',
			$this->slug,
			array( $this, 'render_admin' ) );
	}
	/**
	 * Register CSS and JS for page
	 *
	 * @uses "admin_enqueue_scripts" action
	 */
	public function register_assets()
	{
		wp_register_script( $this->slug, $this->assets_url . '/js/admin.js', array( 'jquery' ) );
		wp_register_style( $this->slug, $this->assets_url . '/css/admin.css' );
		wp_localize_script( $this->slug, 'APEX', array(
			'strings' => array(
				'saved' => __( 'Settings Saved', 'text-domain' ),
				'error' => __( 'Error', 'text-domain' )
			),
			'api'     => array(
				'url'   => esc_url_raw( rest_url( 'apex-api/v1/settings' ) ),
				'nonce' => wp_create_nonce( 'wp_rest' )
			)
		) );
	}
	/**
	 * Enqueue CSS and JS for page
	 */
	public function enqueue_assets(){
		if( ! wp_script_is( $this->slug, 'registered' ) ){
			$this->register_assets();
		}
		wp_enqueue_script( $this->slug );
		wp_enqueue_style( $this->slug );
	}
	/**
	 * Render plugin admin page
	 */
	public function render_admin(){
		$this->enqueue_assets();
		echo 'Put your form here!';
	}
}

在此類中,我使用add_menu_page創(chuàng)建一個(gè)頂層菜單,但是您可能希望根據(jù)需要使用add_sub_menu創(chuàng)建子菜單。

這里有兩件事要注意。

首先是我們?nèi)绾问褂?code>wp_localize_script()。每當(dāng)加載第一個(gè)參數(shù)中指定的腳本時(shí),此函數(shù)都可以為您提供一種使用PHP創(chuàng)建全局作用域JavaScript變量的方法。最初是為了向?yàn)g覽器提供翻譯后的本地化字符串而設(shè)計(jì)的。這就是我們使用它的一部分-提供可翻譯的成功和錯(cuò)誤消息。但是,它也可以用于傳遞動(dòng)態(tài)值,例如當(dāng)前站點(diǎn)的URL,在這種情況下為REST API終結(jié)點(diǎn)和隨機(jī)數(shù)。我們將在JavaScript中需要所有這些功能,但是對(duì)于每個(gè)站點(diǎn),它都是不同的,因此我們必須使用PHP即時(shí)生成它。

另外,請(qǐng)注意,腳本的根URL作為對(duì)類的依賴關(guān)系而傳入。我喜歡這樣做,因?yàn)樵揢RL可能會(huì)在插件或主題的其他地方使用,并且我希望在一個(gè)地方更改或過(guò)濾整個(gè)插件。

實(shí)例化類時(shí),需要指定該URL。這樣做的一個(gè)好地方是在根插件文件中,使用plugin_dir_url()將生成正確的URL。讓我們看一下設(shè)置它的主要插件文件:

<?php
/**
 * Plugin Name: Apex Plugin
 */
add_action( 'init', function(){
	$assets_url = plugin_dir_url( __FILE__ );
	//Setup menu
	if( is_admin() ){
		new Apex_Menu( $assets_url );
	}
	//Setup REST API
});

在此,我們使用“init”操作加載此類。我為REST API端點(diǎn)保留了一個(gè)占位符,一旦插件屏幕準(zhǔn)備就緒,我們將使用它來(lái)保存數(shù)據(jù)。

設(shè)置表單

我不會(huì)對(duì)設(shè)置表單本身太深入,我可以為此寫一整個(gè)系列。取而代之的是,我們僅添加兩個(gè)字段來(lái)查看一些重要的內(nèi)容。然后,我們可以編寫JavaScript將表單值發(fā)送回服務(wù)器。

這是“render_admin”方法,使用具有兩個(gè)字段的字段進(jìn)行了更新:

/**
 * Render plugin admin page
 */
public function render_admin(){
    $this->enqueue_assets();
    ?>
    <form id="apex-form">
        <div id="feedback">
        </div>
        <div>
            <label for="industry">
                <?php esc_html_e( 'Industry', 'text-domain' ); ?>
            </label>
            <input id="industry" type="text" />
        </div>
        <div>
            <label for="amount">
                <?php esc_html_e( 'Amount', 'text-domain' ); ?>
            </label>
            <input id="amount" type="number" min="0" max="100" />
        </div>
        <?php submit_button( __( 'Save', 'text-domain' ) ); ?>
    </form>

    <?php
}

我確保每個(gè)字段都有一個(gè)ID。這將允許我使用jQuery.val()定位每個(gè)對(duì)象以獲取其值。這對(duì)于保持我們的HTML語(yǔ)義也很重要,因?yàn)樽侄螛?biāo)簽的屬性必須與字段ID相對(duì)應(yīng)。我還給了表單一個(gè)ID,并添加了一個(gè)ID為“feedback”的空元素,我們可以在其中動(dòng)態(tài)放置保存或錯(cuò)誤消息。

同樣,您的表單可能會(huì)更復(fù)雜,但讓我們開始吧。

添加REST API路由

在編寫任何JavaScript通過(guò)AJAX將數(shù)據(jù)發(fā)送到服務(wù)器之前,我們需要為其提供REST API路由。我為此寫了很多,但是值得通過(guò)一個(gè)非常簡(jiǎn)單的帶有GETPOST端點(diǎn)的自定義路由。

分離業(yè)務(wù)邏輯

我堅(jiān)信REST API路由的類應(yīng)僅與處理請(qǐng)求有關(guān),而與這些請(qǐng)求所需的業(yè)務(wù)邏輯無(wú)關(guān)。在這種情況下,“業(yè)務(wù)邏輯”是指讀寫實(shí)際設(shè)置。首先,讓我們創(chuàng)建一個(gè)可以處理此問(wèn)題的類。

此類將是帶有一些基本驗(yàn)證的get_option()update_option()的簡(jiǎn)單包裝。此類具有get_settings()方法,該方法獲取保存的值,然后使用wp_parse_args()填充我們希望它具有的已保存數(shù)組的所有缺失索引。它還具有一個(gè)save_settings()方法,該方法確保只有要保存的數(shù)組的白名單鍵才在要保存的最終數(shù)組中。

<?php
class Apex_Settings {
	/**
	 * Option key to save settings
	 *
	 * @var string
	 */
	protected static $option_key = '_apex_settings';
	/**
	 * Default settings
	 *
	 * @var array
	 */
	protected static $defaults = array(
		'industry' => 'lumber',
		'amount' => 42
	);
	/**
	 * Get saved settings
	 *
	 * @return array
	 */
	public static function get_settings(){
		$saved = get_option( self::$option_key, array() );
		if( ! is_array( $saved ) || ! empty( $saved )){
			return self::$defaults;
		}
		return wp_parse_args( $saved, self::$defaults );
	}
	/**
	 * Save settings
	 *
	 * Array keys must be whitelisted (IE must be keys of self::$defaults
	 *
	 * @param array $settings
	 */
	public static function save_settings( array  $settings ){
		//remove any non-allowed indexes before save
		foreach ( $settings as $i => $setting ){
			if( ! array_key_exists( $setting, self::$defaults ) ){
				unset( $settings[ $i ] );
			}
		}
		update_option( self::$option_key, $settings );
	}
}

REST API路由

現(xiàn)在,我們有了一種讀寫方法,可以通過(guò)任何方式尋址,讓我們創(chuàng)建一個(gè)REST API路由,以充當(dāng)其RESTful接口。該路由將具有GET和POST端點(diǎn)。

如果您從未創(chuàng)建過(guò)自定義的REST API終結(jié)點(diǎn),建議您閱讀文檔。我還介紹過(guò)與該主題相關(guān)的Torque文章和WordPress TV talks: 精選的鏈接列表 ?。

這是REST API路由類:

<?php
class Apex_API {
	/**
	 * Add routes
	 */
	public function add_routes( ) {
		register_rest_route( 'apex-api/v1', '/settings',
			array(
				'methods'         => 'POST',
				'callback'        => array( $this, 'update_settings' ),
				'args' => array(
					'industry' => array(
						'type' => 'string',
						'required' => false,
						'sanitize_callback' => 'sanitize_text_field'
					),
					'amount' => array(
						'type' => 'integer',
						'required' => false,
						'sanitize_callback' => 'absint'
					)
				),
				'permissions_callback' => array( $this, 'permissions' )
			)
		);
		register_rest_route( 'apex-api/v1', '/settings',
			array(
				'methods'         => 'GET',
				'callback'        => array( $this, 'get_settings' ),
				'args'            => array(
				),
				'permissions_callback' => array( $this, 'permissions' )
			)
		);
	}
	/**
	 * Check request permissions
	 *
	 * @return bool
	 */
	public function permissions(){
		return current_user_can( 'manage_options' );
	}
	/**
	 * Update settings
	 *
	 * @param WP_REST_Request $request
	 */
	public function update_settings( WP_REST_Request $request ){
		$settings = array(
			'industry' => $request->get_param( 'industry' ),
			'amount' => $request->get_param( 'amount' )
		);
		Apex_Settings::save_settings( $settings );
		return rest_ensure_response( Apex_Settings::get_settings())->set_status( 201 );
	}
	/**
	 * Get settings via API
	 *
	 * @param WP_REST_Request $request
	 */
	public function get_settings( WP_REST_Request $request ){
		return rest_ensure_response( Apex_Settings::get_settings());
	}
}

看一下,回調(diào)函數(shù)非常簡(jiǎn)單,因?yàn)樗鼈冎话b了我在上一節(jié)中創(chuàng)建的設(shè)置類。重要的是要了解,根據(jù)設(shè)計(jì),設(shè)置類沒(méi)有權(quán)限檢查或清理操作。但是權(quán)限檢查和清理非常重要。

這些REST API端點(diǎn)提供了這一點(diǎn)。POST方法為每個(gè)字段指定一個(gè)“ sanitize_callback”參數(shù)。這樣,我可以相信數(shù)據(jù)在傳入之前是安全的。而且,這兩個(gè)路由都使用“permissions_callback”,因此只能通過(guò)具有“ manage_options”功能的路由來(lái)訪問(wèn)這些路由。跳過(guò)這些步驟中的任何一個(gè)都是危險(xiǎn)的。

現(xiàn)在我們只需要在“rest_api_init”操作上實(shí)例化此類,以便存在端點(diǎn)。這又是主要的插件文件,對(duì)其進(jìn)行了修改以實(shí)現(xiàn)此目的:

<?php
/**
 * Plugin Name: Apex Plugin
 */
add_action( 'init', function(){
	$assets_url = plugin_dir_url( __FILE__ );
	//Setup menu
	if( is_admin() ){
		new Apex_Menu( $assets_url );
	}
	//Setup REST API
});

在“設(shè)置”頁(yè)面中使用REST API

現(xiàn)在我們有了端點(diǎn),讓我們?cè)谠O(shè)置頁(yè)面上使用它們。我們將編寫兩個(gè)AJAX調(diào)用。第一個(gè)將獲取保存的設(shè)置,并使用這些設(shè)置更新表單。這將由頁(yè)面加載觸發(fā)。第二個(gè)將由表單保存按鈕觸發(fā),并將用于更新設(shè)置。

在本教程的前面,我們告訴WordPress在此管理頁(yè)面上加載JavaScript文件。現(xiàn)在該使用該文件了。

這是第一個(gè)AJAX調(diào)用的樣子。它的工作是獲取保存的設(shè)置并使用以下內(nèi)容更新表單:

jQuery(function($) {
	
	$.ajax({
		method: 'GET',
		url: APEX.api.url
		beforeSend: function ( xhr ) {
			xhr.setRequestHeader( 'X-WP-Nonce', APEX.api.nonce );
		}
	}).then( function ( r ) {
		if( r.hasOwnProperty( 'industry' ) ){
			$( '#industry' ).val( r.industry );
		}

		if( r.hasOwnProperty( 'amount' ) ){
			$( '#amount' ).val( r.amount );
		}
	})

});

請(qǐng)注意此處的兩個(gè)重要事項(xiàng)。首先,我使用之前通過(guò)wp_localize_script()設(shè)置的APEX全局對(duì)象來(lái)告訴jQuery請(qǐng)求什么URL。另外,我正在使用beforeSend()方法添加包含該對(duì)象中隨機(jī)數(shù)的標(biāo)頭。否則,在API請(qǐng)求處理期間將不會(huì)認(rèn)為用戶已登錄,因此我們的權(quán)限檢查將失敗。

API請(qǐng)求完成后,使用jQuery.val()將設(shè)置添加到表單字段。為了安全起見(jiàn),我使用Object.hasOwnProperty()確保它們?cè)陧憫?yīng)中。這是很重要的驗(yàn)證,但是隨著設(shè)置數(shù)量的增長(zhǎng)而無(wú)法很好地?cái)U(kuò)展-這是我使用VueJS進(jìn)行這種事情的眾多原因之一。

現(xiàn)在,當(dāng)您加載頁(yè)面時(shí),它應(yīng)該獲取已保存的設(shè)置(此時(shí)可能是默認(rèn)值)并更新表單。很好,但是所有這些的真正意義在于能夠更新設(shè)置。因此,我們將需要第二個(gè)AJAX調(diào)用,該調(diào)用將在提交表單時(shí)運(yùn)行POST請(qǐng)求。

這是帶有保存AJAX調(diào)用的更新后的JavaScript:

jQuery(function($) {

	$.ajax({
		method: 'GET',
		url: APEX.api.url,
		beforeSend: function ( xhr ) {
			xhr.setRequestHeader( 'X-WP-Nonce', APEX.api.nonce );
		}
	}).then( function ( r ) {
		if( r.hasOwnProperty( 'industry' ) ){
			$( '#industry' ).val( r.industry );
		}

		if( r.hasOwnProperty( 'amount' ) ){
			$( '#amount' ).val( r.amount );
		}
	});

	$( '#apex-form' ).on( 'submit', function (e) {
		e.preventDefault();
		var data = {
			amount: $( '#amount' ).val(),
			industry: $( '#industry' ).val()
		};

		$.ajax({
			method: 'POST',
			url: APEX.api.url,
			beforeSend: function ( xhr ) {
				xhr.setRequestHeader('X-WP-Nonce', APEX.api.nonce);
			},
			data:data
		}).then( function (r) {
			$( '#feedback' ).html( '<p>' + APEX.strings.saved + '</p>' );
		}).error( function (r) {
			var message = APEX.strings.error;
			if( r.hasOwnProperty( 'message' ) ){
				message = r.message;
			}
			$( '#feedback' ).html( '<p>' + message + '</p>' );

		})
	})
});

第二個(gè)調(diào)用非常相似,除了它使用POST并包裝在與表單的commit事件綁定的閉包中。這樣,它在表單提交時(shí)運(yùn)行,我們可以防止該事件的默認(rèn)操作發(fā)生。

您應(yīng)該在這里查看成功和錯(cuò)誤方法。它們用于將文本(位于APEX.string對(duì)象中)本地化的消息添加到#feedback元素中。該對(duì)象中的“錯(cuò)誤”消息非常籠統(tǒng)。但是大多數(shù)失敗的請(qǐng)求都會(huì)生成一條帶有消息的響應(yīng)。因此,如果已設(shè)置,我們將改用它。

自己去實(shí)踐吧

一旦有了一個(gè)良好的起點(diǎn),就可以更新表單中的字段以符合您的需求。另外,您可能應(yīng)該使用JavaScript框架來(lái)簡(jiǎn)化此過(guò)程,因?yàn)殡S著表單的復(fù)雜性增加,您將越來(lái)越難以使用jQuery進(jìn)行管理并且會(huì)變得更加簡(jiǎn)單,并且如果您使用VueJS或React ,會(huì)提供更好的用戶體驗(yàn)。

本文向您展示了使用WordPress REST API 添加 WordPress設(shè)置頁(yè)面的所有部分。我們添加了一個(gè)菜單頁(yè)面,將我們的JavaScript和CSS入隊(duì),添加了一個(gè)用于讀取和寫入設(shè)置的類,添加了兩個(gè)REST API端點(diǎn)作為這些設(shè)置的RESTful和安全接口,并使用jQuery AJAX根據(jù)我們的設(shè)置表單更新了設(shè)置。代碼量很多,但我希望您已經(jīng)了解了如何使用這些基礎(chǔ)知識(shí)來(lái)改進(jìn)自己的設(shè)置頁(yè)面,或者從頭開始構(gòu)建自己的設(shè)置頁(yè)面并從那里發(fā)展。

原文出自: https://torquemag.io/2017/06/creating-wordpress-settings-page-using-wordpress-rest-api/ ,由WordPress大學(xué)翻譯整理。

拓展閱讀:創(chuàng)建WordPress插件設(shè)置頁(yè)面的5種方法

聲明:本站所有文章,如無(wú)特殊說(shuō)明或標(biāo)注,均為本站原創(chuàng)發(fā)布。任何個(gè)人或組織,在未征得本站同意時(shí),禁止復(fù)制、盜用、采集、發(fā)布本站內(nèi)容到任何網(wǎng)站、書籍等各類媒體平臺(tái)。如若本站內(nèi)容侵犯了原著者的合法權(quán)益,可聯(lián)系我們進(jìn)行處理。

給TA打賞
共{{data.count}}人
人已打賞
歡迎關(guān)注WordPress大學(xué)公眾號(hào) WPDAXUE
WordPress開發(fā)

8個(gè)專為開發(fā)者準(zhǔn)備的WordPress初始化主題

2020-2-22 9:30:54

WordPress開發(fā)

創(chuàng)建WordPress插件設(shè)置頁(yè)面的5種方法

2020-2-23 11:30:51

0 條回復(fù) A文章作者 M管理員
    暫無(wú)討論,說(shuō)說(shuō)你的看法吧
?
個(gè)人中心
購(gòu)物車
優(yōu)惠劵
今日簽到
有新私信 私信列表
搜索

常山县| 伽师县| 广灵县| 军事| 阜南县| 平舆县| 黑河市| 永定县| 樟树市| 阜宁县| 锦州市| 锡林郭勒盟| 临澧县| 鄢陵县| 武平县| 报价| 沅陵县| 崇州市| 青川县| 莒南县| 邵武市| 广平县| 西安市| 客服| 新野县| 苍溪县| 孙吴县| 鹿泉市| 漯河市| 崇文区| 新竹市| 建水县| 万源市| 襄城县| 中西区| 大城县| 格尔木市| 伊宁市| 沁阳市| 襄汾县| 饶平县|