Статьи

Учебник по Ajax в панели управления WordPress — запросы и ответы

В этой серии из двух частей мы рассмотрим, как правильно представить Ajax-специфическую функциональность в панели управления WordPress.

В первой статье этой серии мы начали работу над плагином, который отображает уведомление, как только он активируется … но это все. В этой статье мы добавим функциональность с поддержкой Ajax, которая позволит пользователям отклонить сообщение, и мы закончим с рабочей версией плагина.

В частности, мы собираемся охватить все вещи, необходимые как на стороне сервера, так и на стороне клиента, которые необходимы для обработки запроса Ajax и соответствующего ответа.

Наконец, мы рассмотрим контрольный список элементов, которые должны иметь все функциональные возможности WordPress на основе Ajax, чтобы убедиться, что вы правильно используете API в будущих проектах.


Прежде чем мы начнем, важно убедиться, что у вас есть значение nonce в функции, которая отображает ваш метод уведомления. Для обзора вот функция, которую мы включили в первую статью:

01
02
03
04
05
06
07
08
09
10
11
12
public function display_admin_notice() {
 
    $html = ‘<div id=»ajax-notification» class=»updated»>’;
        $html .= ‘<p>’;
            $html .= __( ‘The Ajax Notification example plugin is active. This message will appear until you choose to <a href=»javascript:;» id=»dismiss-ajax-notification»>dismiss it</a>.’, ‘ajax-notification’ );
        $html .= ‘</p>’;
        $html .= ‘<span id=»ajax-notification-nonce» class=»hidden»>’ .
    $html .= ‘</div><!— /.updated —>’;
 
    echo $html;
 
}

Обратите внимание, что мы отображаем значение nonce, используя wp_create_nonce в элементе span, имеющем идентификатор ajax-notification-nonce wp_create_nonce ajax-notification-nonce . Я поднимаю это по трем причинам:

  1. Одноразовые значения обеспечивают меры безопасности и важны, когда вы делаете любой тип запроса от внешнего интерфейса до внутреннего.
  2. По моему опыту, это одна из вещей, которую разработчики чаще всего упускают из своей работы, — это делается для того, чтобы убедиться, что мы рассмотрели это до написания любого дополнительного кода.
  3. Элемент, содержащий значение nonce, требует определенного идентификатора, чтобы мы могли легко получить к нему доступ с помощью JavaScript при запуске нашего Ajax-запроса.

С этим, давайте приступим к написанию функциональности Ajax.


Создание функциональности на основе Ajax в панели управления WordPress обычно включает четыре ключевых момента:

  • Некоторые функции JavaScript, которые будут реагировать на события пользователя и отправлять его на сервер
  • Функция обратного вызова на стороне сервера, которая отвечает за управление запросом, поступающим из браузера.
  • Функциональность на стороне сервера, которая отправит данные обратно в браузер
  • Функциональность JavaScript, отвечающая за обработку ответа

Хотя нет конкретного порядка, в котором нам нужно писать этот код, мы просто пойдем по списку, как указано выше, и проработаем его.

Код JavaScript для отправки запроса является относительно стандартным, но нам нужно сначала обрисовать, что именно мы собираемся делать:

  • Пользователь решает отклонить уведомление
  • Пользователь нажимает на предоставленную нами привязку отклонения
  • JavaScript реагирует на событие, когда пользователь нажимает на указанную привязку
  • JavaScript отправляет запрос на сервер

Мы будем писать код постепенно, чтобы быть уверенным, что за ним легко следовать. Во-первых, мы начнем с настройки кода после загрузки окна и убедитесь, что уведомление Ajax присутствует:

01
02
03
04
05
06
07
08
09
10
(function ($) {
    $(function () {
 
        // Check to see if the Ajax Notification is visible;
        // we won’t worry about doing any of this.
        if ($(‘#dismiss-ajax-notification’).length > 0) {
            // Stuff TODO here…
        });
    });
}(jQuery));

Далее нам нужно настроить обработчик событий, который будет срабатывать, когда пользователь нажимает на якорь, который мы поместили в уведомлении. Для этого нам нужен идентификатор элемента сообщения, то есть dismiss-ajax-notification .

Поскольку поведение по умолчанию для якоря заключается в попытке перейти к его href , мы также должны предотвратить выполнение действия по умолчанию.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
(function ($) {
    «use strict»;
    $(function () {
 
        // Check to see if the Ajax Notification is visible
        if ($(‘#dismiss-ajax-notification’).length > 0) {
 
            // If so, we need to setup an event handler to trigger it’s dismissal
            $(‘#dismiss-ajax-notification’).click(function (evt) {
 
                evt.preventDefault();
                // More TODO here…
 
            });
 
        } // end if
 
    });
}(jQuery));

На данный момент мы готовы фактически отправить запрос на сервер. Для этого мы будем использовать функцию post jQuery. Мы передадим ему три аргумента:

  • URL-адрес адреса, на который должен быть отправлен запрос. Это глобальное значение, предоставляемое WordPress. Он хранится в переменной ajaxurl
  • Хеш опций для отправки на сервер. Это включает в себя действие — или функцию — для запуска на сервере и одноразовое значение для проверки
  • Функция, используемая для обработки ответа

Давайте выпишем все это сейчас (включая заглушение функции ответа), а затем перейдем к коду на стороне сервера.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
(function ($) {
 
    $(function () {
 
        // Check to see if the Ajax Notification is visible
        if ($(‘#dismiss-ajax-notification’).length > 0) {
 
            // If so, we need to setup an event handler to trigger it’s dismissal
            $(‘#dismiss-ajax-notification’).click(function (evt) {
 
                evt.preventDefault();
 
                // Initiate a request to the server-side
                $.post(ajaxurl, {
 
                    // The name of the function to fire on the server
                    action: ‘hide_admin_notification’,
 
                    // The nonce value to send for the security check
                    nonce: $.trim($(‘#ajax-notification-nonce’).text())
 
                }, function (response) {
 
                    // TODO response handler
 
                });
 
            });
 
        } // end if
 
    });
}(jQuery));

Напомним, ранее, что я сказал, что нам нужно знать идентификатор поля, содержащего значение nonce, то есть ajax-notification-nonce . Обратите внимание, что мы собираем текстовое значение этого элемента и отправляем его на сервер в качестве значения nonce ключа.

Второе, на что следует обратить внимание, это то, что мы отправляем ключ действия со значением hide_admin_notification . Это функция, которую нам нужно написать на сервере, поскольку именно она будет отвечать за фактическое скрытие уведомления.

В нашем файле плагина нам нужно создать функцию с именем в качестве значения действия, упомянутого выше: hide_admin_notification .

Как обычно, мне нравится говорить о том, что собирается делать функция, прежде чем писать какой-либо код. В этом случае вот что нужно сделать:

  • Нам нужно убедиться, что входящий одноразовый номер правильный; в противном случае мы не хотим выполнять какой-либо код
  • Нам нужно обновить параметр, который мы создали в первой статье, чтобы установить для dismiss false
  • Нам нужно отправить значение обратно в браузер, чтобы он мог соответствующим образом реагировать на функцию

Вот код для этого:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
public function hide_admin_notification() {
 
    // First, check the nonce to make sure it matches what we created when displaying the message.
    // If not, we won’t do anything.
    if( wp_verify_nonce( $_REQUEST[‘nonce’], ‘ajax-notification-nonce’ ) ) {
 
        // If the update to the option is successful, send 1 back to the browser;
        // Otherwise, send 0.
        if( update_option( ‘hide_ajax_notification’, true ) ) {
            die( ‘1’ );
        } else {
            die( ‘0’ );
        } // end if/else
 
    } // end if
 
}

Это относительно просто, не так ли? Главное, что нужно понять, это то, что мы отправляем значение ‘1’ в контексте die если опция успешно обновлена; в противном случае мы отправляем значение «0». Это позволит нам прочитать значение в ответе в браузере, чтобы определить, как лучше всего ответить.

Очевидно, что если возвращаемое значение равно 1, то мы можем скрыть уведомление.

Прежде чем вернуться к JavaScript, мы должны убедиться, что мы подключили эту функцию, используя соответствующий хук. Итак, в конструкторе плагина добавим строку для add_action :

1
add_action( ‘wp_ajax_hide_admin_notification’, array( &$this, ‘hide_admin_notification’ ) );

Здесь следует отметить, что тег для функции помечен как wp_ajax_hide_admin_notification .

Если вы работаете с Ajax на панели инструментов WordPress, то ваш хук должен быть добавлен с префиксом wp_ajax_ и он должен заканчиваться именем функции.

Это, пожалуй, вторая по важности вещь, которую я пропускаю при разработке кода на основе Ajax.

Отсюда мы готовы вернуться к клиентскому коду.

Наконец, мы готовы обработать ответ. Это легко: если сервер ответит 1, тогда мы будем прятаться; в противном случае мы ничего не будем делать.

Конечно, лучше всего было бы отображать сообщение об ошибке или какой-либо тип обратной связи, чтобы пользователь знал, что что-то пошло не так, но основной смысл статьи — продемонстрировать Ajax в WordPress, поэтому мы просто изменим имя класса. от updated до error .

Вот что нужно добавить в источник JavaScript для обработки ответа:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
function (response) {
 
    // If the response was successful (that is, 1 was returned), hide the notification;
    // Otherwise, we’ll change the class name of the notification
    if (‘1’ === response) {
        $(‘#ajax-notification’).fadeOut(‘slow’);
    } else {
 
        $(‘#ajax-notification’)
            .removeClass(‘updated’)
            .addClass(‘error’);
 
    } // end if
 
}

И это действительно так. Полный исходный код JavaScript должен выглядеть следующим образом:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
(function ($) {
    $(function () {
 
        // Check to see if the Ajax Notification is visible
        if ($(‘#dismiss-ajax-notification’).length > 0) {
 
            // If so, we need to setup an event handler to trigger it’s dismissal
            $(‘#dismiss-ajax-notification’).click(function (evt) {
 
                evt.preventDefault();
 
                // Initiate a request to the server-side
                $.post(ajaxurl, {
 
                    // The name of the function to fire on the server
                    action: ‘hide_admin_notification’,
 
                    // The nonce value to send for the security check
                    nonce: $.trim($(‘#ajax-notification-nonce’).text())
 
                }, function (response) {
 
                    // If the response was successful (that is, 1 was returned), hide the notification;
                    // Otherwise, we’ll change the class name of the notification
                    if (‘1’ === response) {
                        $(‘#ajax-notification’).fadeOut(‘slow’);
                    } else {
 
                        $(‘#ajax-notification’)
                            .removeClass(‘updated’)
                            .addClass(‘error’);
 
                    } // end if
 
                });
 
            });
 
        } // end if
 
    });
}(jQuery));

И PHP плагина должен выглядеть так:

001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
019
020
021
022
023
024
025
026
027
028
029
030
031
032
033
034
035
036
037
038
039
040
041
042
043
044
045
046
047
048
049
050
051
052
053
054
055
056
057
058
059
060
061
062
063
064
065
066
067
068
069
070
071
072
073
074
075
076
077
078
079
080
081
082
083
084
085
086
087
088
089
090
091
092
093
094
095
096
097
098
099
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
/*
Plugin Name: Ajax Notification
Plugin URI: http://github.com/tommcfarlin/ajax-notification
Description: An example plugin used to demonstrate the WordPress Ajax API for a companion article on Envato’s WPTuts+ site.
Version: 1.0
Author: Tom McFarlin
Author URI: http://tommcfarlin.com
Author Email: tom@tommcfarlin.com
License:
 
  Copyright 2012 Tom McFarlin (tom@tommcfarlin.com)
 
  This program is free software;
  it under the terms of the GNU General Public License, version 2, as
  published by the Free Software Foundation.
 
  This program is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY;
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  GNU General Public License for more details.
 
  You should have received a copy of the GNU General Public License
  along with this program;
  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
 
*/
 
class Ajax_Notification {
 
    /*———————————————*
     * Constructor
     *———————————————*/
 
    /**
     * Initializes the plugin by setting localization, filters, and administration functions.
     */
    function __construct() {
 
        load_plugin_textdomain( ‘ajax-notification’, false, dirname( plugin_basename( __FILE__ ) ) . ‘/lang’ );
 
        register_activation_hook( __FILE__, array( &$this, ‘activate’ ) );
        register_deactivation_hook( __FILE__, array( &$this, ‘deactivate’ ) );
 
        add_action( ‘admin_enqueue_scripts’, array( &$this, ‘register_admin_scripts’ ) );
 
        // Display the admin notice only if it hasn’t been hidden
        if( false == get_option( ‘hide_ajax_notification’ ) ) {
            add_action( ‘admin_notices’, array( &$this, ‘display_admin_notice’ ) );
        } // end if
 
        add_action( ‘wp_ajax_hide_admin_notification’, array( &$this, ‘hide_admin_notification’ ) );
 
    } // end constructor
 
    /*———————————————*
     * Core Functions
     *———————————————*/
 
    /**
     * Upon activation, add a new option used to track whether or not to display the notification.
     */
    public function activate() {
        add_option( ‘hide_ajax_notification’, false );
    } // end activate
 
    /**
     * Upon deactivation, removes the option that was created when the plugin was activated.
     */
    public function deactivate() {
        delete_option( ‘hide_ajax_notification’ );
    } // end deactivate
 
    /**
     * Registers and enqueues admin-specific minified JavaScript.
     */
    public function register_admin_scripts() {
 
        wp_register_script( ‘ajax-notification-admin’, plugins_url( ‘ajax-notification/js/admin.min.js’ ) );
        wp_enqueue_script( ‘ajax-notification-admin’ );
 
    } // end register_admin_scripts
 
    /**
     * Renders the administration notice.
     */
    public function display_admin_notice() {
 
        $html = ‘<div id=»ajax-notification» class=»updated»>’;
            $html .= ‘<p>’;
                $html .= __( ‘The Ajax Notification example plugin is active. This message will appear until you choose to <a href=»javascript:;» id=»dismiss-ajax-notification»>dismiss it</a>.’, ‘ajax-notification’ );
            $html .= ‘</p>’;
            $html .= ‘<span id=»ajax-notification-nonce» class=»hidden»>’ .
        $html .= ‘</div><!— /.updated —>’;
 
        echo $html;
 
    } // end display_admin_notice
 
    /**
     * JavaScript callback used to hide the administration notice when the ‘Dismiss’ anchor is clicked on the front end.
     */
    public function hide_admin_notification() {
 
        // First, check the nonce to make sure it matches what we created when displaying the message.
        // If not, we won’t do anything.
        if( wp_verify_nonce( $_REQUEST[‘nonce’], ‘ajax-notification-nonce’ ) ) {
 
            // If the update to the option is successful, send 1 back to the browser;
            // Otherwise, send 0.
            if( update_option( ‘hide_ajax_notification’, true ) ) {
                die( ‘1’ );
            } else {
                die( ‘0’ );
            } // end if/else
 
        } // end if
 
    } // end hide_admin_notification
 
} // end class
 
new Ajax_Notification();

Вы можете получить плагин на GitHub . Для справки обязательно ознакомьтесь со следующими ресурсами: