Ajax в WordPress — пособие по фоновой обработке данных

Использование Ajax в WordPress может показаться сложным, но оно того стоит. Чтобы узнать, как лучше всего использовать Ajax на своем сайте, ознакомьтесь с нашим руководством.
Быстрая навигация по записе

Использование «Ajax» является одним из самых распространенных методов создания и работы с пользовательскими интерфейсами.

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

В качестве примера, работу Ajax в WordPress можно наблюдать в панели администратора если открыть консоль браузера и перейти во вкладку «Network», но, как и везде, в WordPress есть свои особенности работы с асинхронным JavaScript и в этой статье мы на их рассмотрим.

Что будем делать?

Осваивать работу Ajax в WordPress мы будем на реальном примере, а именно будем создавать «форму регистрации и авторизации пользователей», для вашего WordPress сайта.

Только реальная практика, только хардкор ?
WordPress лаборатория

Благодаря рубрикам осуществляется группировка связанных записей. Рубрика, к которой по умолчанию привязываются все новые записи — «Без рубрики» (Uncategorized), но ее можно легко изменить в настройках.

Формы, которые вы видите ниже, будут результатом нашей совместной работы. Они полностью рабочие, пробуйте.

Внимание

Так как это обучающие пособие, то все пользователи, которые зарегистрировались через эту форму, периодически удаляются!

Ajax в WordPress - пособие по фоновой обработке данных
Это не смогу сверстать
Внимание

Предполагается, что читатель уже обладает базовыми навыками работы с HTML, CSS, PHP и jQuery, так как мы не будем посимвольно разжёвывать каждый кусок кода.

Начать погружение в работу Ajax на WordPress сайтах следует с изучения теории, этим и займёмся.

Теория использования Ajax в WordPress

Начиная с бородатой версии ядра 2.8, WordPress позволяем создавать собственные события, используя встроенный Ajax, но стоит понимать, что есть ряд правил, которым нужно следовать:

  • Все запросы должны передаваться с использованием файла admin-ajax.php, не нужно писать собственные обработчики.
  • Права на использования событий обработки асинхронных запросов должны быть правильно разграничены.
  • Использование nonce (Hash, с определенным жизненным циклом), значительно уменьшает вероятность неправомерного использования события.
  • Событие должно заканчиваться функцией wp_die(), а не die() или exit(). Сторонние разработчики часто используют фильтрацию функции wp_die(), не лишайте их этой возможности. К тому же эта функция полезна при отладке кода.

Как видно, свод правил достаточно коротки и никаких критичных ограничений не несет.

Давайте уже переходить к практике.

Практика работы с Ajax в WordPress

Первое, что нам предстоит сделать – это создать HTML разметку форм для регистрации/авторизации и стилизовать их. Процесс этот описывать не будем, а сам код можно взять здесь.

Стоит учесть, что таблица стилей вашей темы может частично перекрыть стили форм, с которыми мы работаем, но в целом должно получиться примерно так:

Ajax в WordPress – HTML разметка для формы авторизации и регистрации
Ajax в WordPress – HTML разметка для формы авторизации и регистрации

Для начала, советуем не менять HTML разметку, которая используется в этом уроке, а просто скопировать и вставить в тело страницы, используя элемент HTML в редакторе блоков.

Скрипты в этом уроке будет опираться именно на эту разметку.

Событие инициализации JS скрипта

Вставляем этот код в functions.php вашей темы (желательно дочерней):

				
					// Добавляем событие в процесс инициализации JS скриптов
add_action( 'wp_enqueue_scripts', 'wplb_ajax_enqueue' );

//Описываем событие
function wplb_ajax_enqueue() {

    // Подключаем файл js скрипта.
    wp_enqueue_script(
        'wplb-ajax', // Имя
        get_stylesheet_directory_uri() . '/scripts/wplb-ajax.js', // Путь до JS файла.
        array('jquery') // В массив jquery.
    );

    // Используем функцию wp_localize_script для передачи переменных в JS скрипт.
    wp_localize_script(
        'wplb-ajax', // Куда будем передавать
        'wplb_ajax_obj', // Название массива, который будет содержать передаваемые данные
        array(
            'ajaxurl' => admin_url( 'admin-ajax.php' ), // Элемент массива, содержащий путь к admin-ajax.php
            'nonce' => wp_create_nonce('wplb-nonce') // Создаем nonce
        )
    );

}
				
			

Давайте подробнее рассмотрим это кусок кода:

Первое, что мы делаем, хукаем событие инициализации скриптов для регистрации собственного *.js.

Обратите внимание, что мы используем функцию get_stylesheet_directory_uri(), для того, чтобы указать путь к новому JS файлу так как работаем в дочерней теме. Если вы работаете в родительской теме, то используйте функцию get_template_directory_uri().

Благодаря функции wp_localize_script(), а в файле /scripts/wplb-ajax.js, будет доступен объект с данными которые мы отправляем из PHP. Имейте ввиду, что таким методом можно передавать любые, как статичные данные из БД, так и результаты отработки циклов ☝️

Изначальное тело подключённого скрипта

Для начала, содержимое файла wplb-ajax.js, который должен находится в папке wp-content/моя_тема/scripts будет таким:

				
					jQuery(document).ready(function ($) {
    'use strict';
    'esversion: 6';

    // Функция отправки форм.
    $('.wplb_holder').on('submit', 'form', function (ev) {
        // Определяем какую форму пользователь заполнил.
        let this_is = $(this);
        
        // Определяем кнопку.
        let button = $(this).find('input[type="submit"]');
        
        // Определяем тип формы.
        let type = $(this).attr('data-type');
        
        // Отправляем запрос Ajax в WordPress.
        $.ajax({

            // Путь к файлу admin-ajax.php.
            url: wplb_ajax_obj.ajaxurl,

            // Создаем объект, содержащий параметры отправки.
            data: {

                // Событие к которому будем обращаться.
                'action': 'wplb_ajax_request',

                // Передаём тип формы.
                'type': type,
                
                // Передаём значения формы.
                'content': $(this).serialize(),

                // Используем nonce для защиты.
                'security': wplb_ajax_obj.nonce,

                // Перед отправкой Ajax в WordPress.
                beforeSend: function () {}
            }
        })
        .always(function() {
            // Выполнять после каждого Ajax запроса.
            
        })
        .done(function(data) {
            // Функция для работы с обработанными данными.
            
        })
        .fail(function(errorThrown) {
            // Читать ошибки будем в консоли если что-то пойдет не по плану.
            
            console.log(errorThrown);
            
        });

        // Предотвращаем действие, заложенное в форму по умолчанию.
        ev.preventDefault();
    });

});
				
			

Давайте проясним некоторые моменты:

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

  • use strict – это так называемый «строгом режиме», который заметно ограничивает синтаксис котором можно пользоваться. Благодаря этому можно на 100% быть уверенным, что скрипт будет правильно работать во всех браузерах. Защита от тираннозавров с кривыми ручками.?
  • esversion: 6 означает, что мы используем синтаксис ECMAScript версии 6, а так версия вышла аж в 2015 году, то за совместимость с браузерами сомневаться не приходится. Можно использовать и более новые версии вплоть до 11-ой (Дата релиза: Июнь 2020), но на свой страх и риск. Понижать версию не рекомендуется.

Вы наверное заметили, что используется функция .on(), вот так:

				
					$('.wplb_holder').on('submit', 'form', function (event) {});
				
			

Вместо простой и привычной:

				
					$( "form" ).submit(function( event ) {});
				
			

Дело в том, что функция .on() позволяет обращаться к динамически добавленным в DOM (объектная модель документа) элементам.

Если представить, что в результате какого-то события на странице появился новый блочный элемент с ссылкой:

				
					<div id="wplb_new_element">
    <a href="#" id="wplb_read_more">Читать дальше..</a>
</div>
				
			

Если по ссылке нужно будет кликнуть, то:

				
					// Так работать не будет:
$('#wplb_read_more').click(function(event){});

// Так будет:
$('#wplb_new_element').on('click', '#wplb_read_more', function (event) {});
				
			

Конструкция самой $.ajax({}) функции достаточно проста, а для каждой строки мы добавили комментарии. Но стоит обратить внимание, что мы используем объект <wplb_ajax_obj, который создали при инициализации самого скрипта.

Событие, которое будет обрабатывать Ajax в WordPress ядре, в нашем случае называется wplb_ajax_request.

Давайте его создадим.

Событие обработки Ajax в WordPress

Возвращаемся в functions.php добавляем следующий код:

				
					// Создаём событие обработки Ajax в WordPress теме.
add_action( 'wp_ajax_nopriv_wplb_ajax_request', 'wplb_ajax_request' );
//add_action( 'wp_ajax_wplb_ajax_request', 'wplb_ajax_request' );

// Описываем саму функцию.
function wplb_ajax_request() {

    // Перемененная $_REQUEST содержит все данные заполненных форм.
    if ( isset( $_REQUEST ) ) {

        // Проверяем nonce, а в случае если что-то пошло не так, то прерываем выполнение функции.
        if ( !wp_verify_nonce( $_REQUEST[ 'security' ], 'wplb-nonce' ) ) {
            wp_die( 'Базовая защита не пройдена' );
        }

        // Введём переменную, которая будет содержать массив с результатом отработки события.
        $result = array( 'status' => false, 'content' => false );
        
        // Создаём массив который содержит значения полей заполненной формы.
        parse_str( $_REQUEST[ 'content' ], $creds );
        
        switch ( $_REQUEST[ 'type' ] ) {
            case 'registration':
                /**
                 * Заполнена форма регистрации.
                 */
                break;
            case 'authorization':
                /**
                 * Заполнена форма авторизации.
                 */
                break;
        }

        // Конвертируем массив с результатами обработки и передаем его обратно как строку в JSON формате.
        echo json_encode( $result );

    }

    // Заканчиваем работу Ajax.
    wp_die();
}
				
			

Для создания самого события используется хук «wp_ajax_action_name», где action_name это название события, в нашем случае wplb_ajax_request, а вот префикса может быть два:

  • WP_AJAX_NOPRIV_ WPLB_AJAX_REQUEST, событие будет доступно только для НЕ авторизированных пользователей (гости).
  • WP_AJAX_ WPLB_AJAX_REQUEST – только для авторизированных пользователей.

Получается, что если нам нужен Ajax который будет работать как для гостей, так и для авторизированных пользователей WordPress сайта, то нужно создать оба события одновременно!?

Мы так же ввели переменную $result, которая будет содержать массив с результатами обработки, а сам массив конвертируем в строку JSON формата и отправляем обратно в браузер.

Пора начинать работать с пользователями.

Регистрация пользователей

При отправки формы, благодаря функции serialize(), в глобальную переменную $_REQUEST и как элемент массива, запишутся все данные заполненной формы.

Начнем с формы регистрации, а значит там где мы используем оператор switch нас интересует случай «registration».

Вставляем следующий код:

				
					case 'registration':
    /**
     * Заполнена форма регистрации.
     */

    // Пробуем создать объект с пользователем.
    $user = username_exists( $creds[ 'wplb_login' ] );

    // Проверяем, а может быть уже есть такой пользователь
    if ( !$user && false == email_exists( $creds[ 'wplb_email' ] ) ) {
        // Пользователя не существует.

        // Создаём массив с данными для регистрации нового пользователя.
        $user_data = array(
            'user_login' => $creds[ 'wplb_login' ], // Логин.
            'user_email' => $creds[ 'wplb_email' ], // Email.
            'user_pass' => $creds[ 'wplb_password' ], // Пароль.
            'display_name' => $creds[ 'wplb_login' ], // Отображаемое имя.
            'role' => 'subscriber' // Роль.
        );

        // Добавляем пользователя в базу данных.
        $user = wp_insert_user( $user_data );

        // Проверка на ошибки.
        if ( is_wp_error( $user ) ) {

            // Невозможно создать пользователя, записываем результат в массив.
            $result[ 'status' ] = false;
            $result[ 'content' ] = $user->get_error_message();

        } else {

            // Создаём массив для авторизации.
            $creds = array(
                'user_login' => $creds[ 'wplb_login' ], // Логин пользователя.
                'user_password' => $creds[ 'wplb_password' ], // Пароль пользователя.
                'remember' => true // Запоминаем.
            );

            // Пробуем авторизовать пользователя.
            $signon = wp_signon( $creds, false );

            if ( is_wp_error( $signon ) ) {

                // Авторизовать не получилось.
                $result[ 'status' ] = false;
                $result[ 'content' ] = $signon->get_error_message();

            } else {

                // Авторизация успешна, устанавливаем необходимые куки.
                wp_clear_auth_cookie();
                clean_user_cache( $signon->ID );
                wp_set_current_user( $signon->ID );
                wp_set_auth_cookie( $signon->ID );
                update_user_caches( $signon );

                // Записываем результаты в массив.
                $result[ 'status' ] = true;
            }

        }
    } else {
        
        // Такой пользователь уже существует, регистрация не возможна, записываем данные в массив.
        $result[ 'status' ] = false;
        $result[ 'content' ] = esc_html__( 'Пользователь уже существует', 'wplb_ajax_lesson' );
    }
    break;
				
			

Всё достаточно просто. При благоприятном стечении обстоятельств пользователь будет зарегистрирован и авторизован, а в противном случае, благодаря встроенному в WordPress обработчику ошибок, мы будем знать, что именно пошло не так.

Проще говоря, результат обработки вернется в файл wplb-ajax.js в 100% случаях.

Давайте посмотрим, что можно сделать с полученным назад данными.

Авторизация пользователя

Мы еж описали процесс авторизации в блоке относящемся к регистрации, а так плодить запросы Ajax в WordPress мы не собираемся, то просто скопируем кусочек кода и вставим его в нужное место:

				
					case 'authorization':
    /**
     * Заполнена форма авторизации.
     */

    // Создаём массив для авторизации
    $creds = array(
        'user_login' => $creds[ 'wplb_login' ], // Логин пользователя
        'user_password' => $creds[ 'wplb_password' ], // Пароль пользователя
        'remember' => true // Запоминаем
    );

    // Пробуем авторизовать пользователя.
    $signon = wp_signon( $creds, false );

    if ( is_wp_error( $signon ) ) {

        // Авторизовать не получилось
        $result[ 'status' ] = false;
        $result[ 'content' ] = $signon->get_error_message();

    } else {

        // Авторизация успешна, устанавливаем необходимые куки.
        wp_clear_auth_cookie();
        clean_user_cache( $signon->ID );
        wp_set_current_user( $signon->ID );
        wp_set_auth_cookie( $signon->ID );
        update_user_caches( $signon );

        // Записываем результаты в массив.
        $result[ 'status' ] = true;
    }

    break;
				
			
Внимание

Дублирование процедур в коде – это очень плохое решение и вам стоит создать отдельную функцию, описывающую процесс авторизации и вызывать её в нужных местах.

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

Визуализация вернувшихся данных

Ajax в WordPress – пример работы
Ajax в WordPress – пример работы

Прежде чем, что-то сделать с данными которые мы обработали и вернули обратно, давайте посмотрим что можно сделать перед изначальной их отправкой.

Описываем функцию beforeSend: function () {}):

				
					// Перед отправкой запроса Ajax в WordPress ядро.
beforeSend: function () {

    // Спрячем кнопку и покажем пользователю, что скрипт работает.
    button.hide();
    this_is.find('.wplb_alert').hide();
    this_is.find('.wplb_loading').show();
}
				
			

Всё просто, мы спрятали кнопку отправки формы и показали всевдоспинер, для визуализации процесса.

Теперь опишем процесс визуализации вернувшихся данных:

				
					.done(function(data) {
    // Функция для работы с обработанными данными.

    // Переменная $reslut будет хранить результат обработки.
    let $result = JSON.parse(data);

    // Проверяем какой статус пришел
    if($result.status == false){

        //Пришла ошибка, скрываем не нужные элементы и возвращаем кнопку.
        this_is.find('.wplb_alert').addClass('wplb_alert_error').html($result.content).show();

        button.show();

    }else{

        // Пользователь авторизован, покажем ему сообщение.
        $('.wplb_holder').addClass('wplb_alert wplb_signon').html('<p style="margin-bottom:3px;"><strong>Добро пожаловать!</strong></p>Ajax выполнил свою работу, вы в системе! Перезагрузите страницу и убедитесь.');
    }

})
				
			

Так как код очень простой и содержит комментарии, то описывать его смысла нет.

Послесловие и исходный код

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

К этому уроку мы подготовили все исходники, а форму обернули в шорткод для более удобного использования. Скачать можно тут.

Инструкция:

  • Содержимое файла functions.php из архива добавьте в конец одноименного файла (functions.php) вашей темы.
  • Скопируйте файл wplb_ajax_template.php в коревую папку вашей WordPress темы.
  • В корневой папке вашей темы создайте папку scripts и положите туда файл wplb-ajax.js

Вставьте этот шорткод в тело страницы, любым удобным методом, удалив лишние пробелы:

				
					[ wplb_ajax_example ]
				
			

Если у вас есть вопросы спрашивайте в комментариях.

Спасибо.

Оставить комментарий

Нужна помощь с WordPress WooCommerce плагинами темой оптимизацией ?

Упрощаем сложное, создаем впечатляющее!
100% без риска
Нет обязательств по найму
Бесплатная оценка
Давайте составим техническое задание!100% без рискаНет обязательств по наймуБесплатная оценка стоимости
Здравствуйте! Я асистент на основе искусственного интеллекта. Вы можете общаться со мной, как с человеком — задавайте вопросы, описывайте свои идеи и требования.

С удовольствием помогу вам составить техническое задание для вашего WordPress проекта.

Выберите подходящий вариант или опишите свою задачу в свободной форме, и я помогу вам составить четкий план действий, для оценки стоимости нашими разработчиками! 😊

Поможем вывести Ваш бизнес на новый уровень!

Проснувшись однажды утром после беспокойного сна, Грегор Замза обнаружил

Добро пожаловать!

Авторизуйтесь, чтобы продолжить

или

* Если аккунта у Вас еще нет, то он будет создан автоматически