Использование « Ajax» является одним из самых распространенных методов создания и работы с пользовательскими интерфейсами.
Начиная с бородатой версии ядра 2.8, WordPress позволяем создавать собственные события, используя встроенный Ajax, но стоит понимать, что есть ряд правил, которым нужно следовать:
- Все запросы должны передаваться с использованием файла , не нужно писать собственные обработчики.
- Права на использования событий обработки асинхронных запросов должны быть правильно .
- Использование (Hash, с определенным жизненным циклом), значительно уменьшает вероятность неправомерного использования события.
- Событие должно заканчиваться функцией , а не или . Сторонние разработчики часто используют фильтрацию функции , не лишайте их этой возможности. К тому же эта функция полезна при отладке кода.
- Практика работы с Ajax в WordPress
- Событие инициализации JS скрипта
- Изначальное тело подключённого скрипта
- Событие обработки Ajax в WordPress
- Регистрация пользователей
- Авторизация пользователя
- Визуализация вернувшихся данных
- Послесловие и исходный код
- Шаг 1. Добавление кнопки «Загрузить ещё»
- Шаг 2. Подключение скриптов
- Шаг 3. Скрипт асинхронной загрузки
- Шаг 4. Обработчик PHP, вывод постов
- Бесконечная загрузка постов при прокрутке страницы
- Шаг 1. Структура HTML
- Шаг 2. C SS
- Шаг 3. Подключение скриптов
- Шаг 4. Скрипты jQuery
- Последний шаг. P HP-обработчик
- AJAX в клиентской части WordPress
- Переменная ajaxurl
- Параметр nonce
- Создание запроса
- Работа над ошибками
- Показ ошибок в консоли DevTools
- Шаг 1. Подготовка
- Шаг 2. Познакомимся с $. ajax
- Шаг 3. Познакомимся со стандартным обработчиком асинронных запросов в WordPress – admin-ajax. php
- Распространённые ошибки
- Что можно сделать с самим событием?
- Примеры работы с событием
- Обратите внимание!
Практика работы с Ajax в WordPress
Первое, что нам предстоит сделать – это создать 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.
Обратите внимание, что мы используем функцию , для того, чтобы указать путь к новому JS файлу так как работаем в дочерней теме. Если вы работаете в родительской теме, то используйте функцию .
Благодаря функции , а в файле , будет доступен объект с данными которые мы отправляем из . Имейте ввиду, что таким методом можно передавать любые, как статичные данные из БД, так и результаты отработки циклов ☝️
Изначальное тело подключённого скрипта
Для начала, содержимое файла , который должен находится в папке будет таким:
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(); }); });
Давайте проясним некоторые моменты:
Обратите внимание, что используются две директивы:
- – это так называемый « строгом режиме», который заметно ограничивает синтаксис котором можно пользоваться. Благодаря этому можно на 100% быть уверенным, что скрипт будет правильно работать во всех браузерах. Защита от тираннозавров с кривыми ручками?
- означает, что мы используем синтаксис ECMAScript версии 6, а так версия вышла аж в 2015 году, то за совместимость с браузерами сомневаться не приходится. Можно использовать и более новые версии вплоть до 11-ой
Вы наверное заметили, что используется функция , вот так:
$('.wplb_holder').on('submit', 'form', function (event) {});
Вместо простой и привычной:
$( "form" ).submit(function( event ) {});
Дело в том, что функция позволяет обращаться к динамически
добавленным в 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 в WordPress ядре, в нашем случае называется .
Давайте его создадим.
Событие обработки Ajax в WordPress
Возвращаемся в добавляем следующий код:
// Создаём событие обработки 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_nopriv_ wplb_ajax_request, событие будет доступно только для не авторизированных пользователей (гости).
- wp_ajax_ wplb_ajax_request– только для авторизированных пользователей.
Получается, что если нам нужен Ajax который будет работать как для гостей, так и для авторизированных пользователей WordPress сайта, то нужно создать оба события одновременно! ?
Мы так же ввели переменную , которая будет содержать массив с результатами обработки, а сам массив конвертируем в строку формата и отправляем обратно в браузер.
Регистрация пользователей
При отправки формы, благодаря функции , в глобальную переменную и как элемент массива, запишутся все данные заполненной формы.
Начнем с формы регистрации, а значит там где мы используем оператор нас интересует случай « 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 обработчику ошибок, мы будем знать, что именно пошло не так.
Авторизация пользователя
Мы еж описали процесс авторизации в блоке относящемся к регистрации, а так плодить запросы 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 ядро. 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)
вашей темы. - Скопируйте файл в коревую папку вашей WordPress темы.
- В корневой папке вашей темы создайте папку и положите туда файл
Вставьте этот шорткод в тело страницы, любым удобным методом, удалив лишние пробелы:
[ wplb_ajax_example ]
Если у вас есть вопросы спрашивайте в комментариях.
Работать будем со стандартной темой TwentyTwentyOne, во-первых, эта тема довольно простая и будет нетрудно разобраться в коде, во-вторых, вы всегда можете установить её прямо из админки из репозитория тем WordPress.
- Загрузку постов при нажатии на кнопку «Загрузить ещё».
- Бесконечную загрузку, т е посты будут подгружаться автоматически при прокрутке страницы.
- Сделаем так, чтобы подгрузка постов работала для рубрик, меток и любых архивов таксономий
(только на видео). - Сделаем динамическую пагинацию, показывающую текущую страницу после подгрузки постов (только на видео).
Шаг 1. Добавление кнопки «Загрузить ещё»
Для начала нам надо найти файл, в котором добавляется постраничная навигация. В TwentyTwentyOne это два файла – index.php
для главной страницы сайта, где выводятся посты блога и archive.php
– для меток и рубрик. Если вы не понимаете, в каком файле надо искать в вашей теме, рекомендую взглянуть на этот туториал.
Найдите соответствующее место в шаблоне за пределами цикла while
, то есть после того, как заканчивается вывод постов (в TwentyTwentyOne это место практически сразу после endwhile
) и вставляем туда код:
div id="loadmore" style="text-align:center;">a href="#" class="button">Загрузить ещё/a>/div>
Понятно, нам нужно учесть некоторые моменты, чтобы кнопка отображалась корректно, а именно:
- Если это последняя страница с постами, то кнопку выводить не нужно.
- Если количество постов в данной рубрике меньше, чем количество, установленное в
Настройки > Чтение,
то кнопку не отображаем также.
Это решается следующими условиями:
; // текущая страница = ? : ; // максимум страниц = ->; // если текущая страница меньше, чем максимум страниц, то выводим кнопку < // тут выводим кнопку
Кроме того, я предлагаю добавить на кнопку data-атрибут, чтобы передавать в обработчик информацию о том, на какой странице мы находимся в данный момент и какую страницу нужно загрузить.
; // текущая страница = ? : ; // максимум страниц = ->; // если текущая страница меньше, чем максимум страниц, то выводим кнопку < '<div id="loadmore" style="text-align:center;"> <a href="#" data-max_pages="' . . . . '" class="button">Загрузить ещё</a> </div>' ;
Также на кнопку я добавил класс .button
, который стилизует её для темы TwentyTwentyOne.
Успешным выполнением первого шага будет считаться вот такая кнопка, которая должна будет появиться на странице всех ваших записей, но имейте ввиду, что если записей недостаточно для двух страниц, то кнопки не будет, для этого либо создайте больше записей, либо перейдите в
Настройки > Чтение
и измените количество отображаемых на странице записей там.
Самый легкий шаг позади.
Шаг 2. Подключение скриптов
Документация функций wp_enqueue_script() и get_stylesheet_directory_uri() в помощь. Про подключение скриптов я писал часто и подробно, поэтому сейчас на этом останавливаться не будем, если есть проблемы — смотрите документацию. А этот код — в functions.php
дочерней темы.
, ; true_loadmore_scripts ; // в TwentyTwentyOne он не подключен по умолчанию , . , , // не кэшируем файл, убираем эту строчку после завершение разработки ;
Также нам понадобится передать в loadmore.js
динамический адрес обработчика AJAX в WordPress, поэтому мы немного модифицируем наш код, добавив в него функцию wp_localize_script()
.
, ; true_loadmore_scripts ; // в TwentyTwentyOne он не подключен по умолчанию , . , , // не кэшируем файл, убираем эту строчку после завершение разработки ; , , => ; ;
Шаг 3. Скрипт асинхронной загрузки
Вы ещё не создали файл loadmore.js
в папке с темой? Давайте создадим его и добавим туда следующий код:
jQuery$ // определяем в переменные кнопку, текущую страницу и максимальное кол-во страниц button = $ , paged = button. , maxPages = button. ; button. event event.; // предотвращаем клик по ссылке $. type : , url : misha., // получаем из wp_localize_script() data : paged : paged, // номер текущей страниц action : // экшен для wp_ajax_ и wp_ajax_nopriv_ , beforeSend : xhr button. ; , success : data paged++; // инкремент номера страницы button. data ; button. ; // если последняя страница, то удаляем кнопку paged == maxPages button.; ; ; ;
Я постарался сделать этот код максимально простым, дополнительными переменными усложнять его не стал. Если вы хотя бы немного разбираетесь в jQuery, то у вас не возникнет с ним никаких проблем. Даже если не разбираетесь, но сделаете всё по инструкции, то всё тоже будет ок.
Шаг 4. Обработчик PHP, вывод постов
, ; , ; true_loadmore = ! ? : ; ++; = => , => ; ; : ; , get_theme_mod , ; ; ;
Бесконечная загрузка постов при прокрутке страницы
Суть в том, что вы просто скроллите страницу вниз, а новые посты подгружаются по мере её прокрутки. Насколько я помню, впервые такая штука появилась у твиттера (могу ошибаться, поправьте, если я не прав), а потом уже все стянули её оттуда.
Скажу честно — заразная вещь. Те, кто сидят на сайте вконтакте, понимают это прекрасно. Так что, если у вас новостной сайт, тогда этот способ загрузки постов просто «must have».
Если вы сделали все предыдущие шаги из поста и дошли до этого момента — тогда отлично, добавим некоторые изменения для шагов 1 и 3.
Содержимое файла loadmore.js
изменится и будет следующим:
jQuery$ $window. bottomOffset = , // отступ от нижней границы сайта, до которого должен доскроллить пользователь, чтобы подгрузились новые посты button = $ , paged = button. , maxPages = button. ; $document. > $document. - bottomOffset && !$. $. type : , url : misha., data : paged : paged, action : , beforeSend: xhr $.; , success:data data paged++; button. data ; $.; ; ; ;
Надеюсь, что не запутал вас. Если возникнут трудности то не забывайте про видео.
Очень многие из моих учеников сталкиваются с тем, что им надо сохранить пагинацию. То есть, чтобы были и кнопка «Загрузить ещё» и пагинация ссылками. Причём сама пагинация должна динамически изменяться в зависимости от того, какие посты подгружены
и на какой странице мы находимся после этого.
Пагинация подробно рассмотрена на видеоуроке 🙂
- 7 видеоуроков
- Доступ к теме курса с готовым кодом после каждого урока
- Единоразовый платёж
- Доступ навсегда
- Уроки актуальны в 2023-м году
Не знаете как создать сайт на WordPress? Следуйте нашему бесплатному руководству и узнайте как сделать сайт и запустить его без привлечения разработчиков.
Хотите улучшить свою безопасность WordPress? Вот наши рекомендации, советы и плагины безопасности WordPress, о которых вам точно нужно знать.
Не знаете как создать блог на WordPress? Мы решили создать наиболее полное руководство по созданию блога на WordPress без каких-либо технических знаний.
Как правильно сбросить постоянные ссылки на всех сайтах в сети WordPress (Multisite) если у Вас есть пользовательские типы записей (Custom Post Type)
Рассмотрим работу WordPress Cron (WP-Cron). Запланированные события в WordPress и всё, что с ними связанно. Примеры работы Wp-Cron!
Использование Ajax в WordPress может показаться сложным, но оно того стоит. Чтобы узнать, как лучше всего использовать Ajax на своем сайте, ознакомьтесь с нашим руководством.
Рубрики в WordPress – это один из основных способ фильтрации различных типов записей и являются неотъемлемой частью любого WordPress сайта.
Вот как примерно выглядит отправка комментария:
- самое главное — возможность работы со стандартными древовидными комментариями
comment-reply.js
, - вывод ошибок, в том числе вордпрессовских, особо с этим заморачиваться не буду, сделаю через
alert()
пока что, - проверка комментария на наличие запрещенных HTML-тегов. Читайте о том, как изменить список разрешенных тегов,
- модерация комментария при необходимости,
- запоминание в кукисах значений полей «Имя» и «Email»,
- исключить возможность двойного нажатия на кнопку «Отправить»,
- не используем никакие плагины WordPress;
Шаг 1. Структура HTML
В этом уроке я использовал стандартную тему WordPress Twenty Twenty One. Обратите внимание на скриншот из этой темы, как расположены элементы списка и формы комментариев, чтобы сориентироваться по атрибутам class
и id
.
Если у вас что-то добавляется не туда, посмотрите, как я проверял это всё на видео.
Шаг 2. C SS
Если у вас со структурой всё окей, то стили по сути и не понадобятся, за исключением оформления ошибок, возникающих в результате валидации полей. То есть, если кто-то ввёл неверный адрес email, поле должно стать красного цвета (например).
input textarea /* или background:red или любой другой цвет, который больше вписывается в дизайн вашего блога */
Добавляем этот код в основной файл стилей вашей темы, обычно это — style.css
.
Шаг 3. Подключение скриптов
Во-первых, давайте в папке с темой создадим какой-нибудь файл JavaScript, в который мы потом добавим весь наш код. У меня это будет файл comments.js
.
Теперь наша задача — правильно подключить библиотеку jQuery и файл comments.js
. Для этого воспользуемся функцией wp_enqueue_script().
, ; true_include_my_comment_script ; , . , , ; , , => ; ;
Зайдите в исходный код страницы и посмотрите, появился ли там comments.js,
если да — переходим к следующему шагу, если нет — открываем файлы header.php
и footer.php
и убеждаемся, что там присутствуют функции wp_head() и wp_footer()
соответственно.
Шаг 4. Скрипты jQuery
Открываем наш файл comments.js
и вписываем туда:
jQuery $ // действие при отправки формы комментария $ . commentForm = $, respond = $ , commentList = $ ; // .comment-list иногда имеет другой класс // отправляем запрос $. type : , url : misha., data : commentForm. + , beforeSend : xhr // изменяем текст кнопки перед отправкой комментария $ . ; , error: request, status, error // обрабатываем ошибки status == 'Ошибка при добавлении комментария' ; status== 'Ошибка: Сервер не отвечает, попробуй ещё.' ; // ворпдрессовские ошибочки, не уверен, что это самый оптимальный вариант // если знаете способ получше - поделитесь errormsg = request.; string1 = errormsg.; string2 = string1.; string2; , success : newComment // console.log( newComment ); $ . > respond. respond. . > // если дочерние уже есть respond. . newComment ; // если первый дочерний respond. + newComment + ; commentList. newComment ; // если нет комментариев respond. + newComment + ; $ . ; $ . ; $ .; // очищаем поле комментария ; ; ; ;
Последний шаг. P HP-обработчик
Читайте подробнее о том, как обрабатываются асинхронные запросы в WordPress. Код обработчика:
, ; , ; true_comment // код из файла wp-comments-post.php = wp_handle_comment_submission wp_unslash ; = int ->; ! . -> . , 'Comment Submission Failure' , => , => , ; ; = ; = ; , , , ; // код из файла comments.php вашей текущей темы wp_list_comments => , => , => , , ; ;
Также есть доработки, которые я не буду добавлять, дабы не усложнять пост, но вам стоит попробовать сделать их самим:
- При добавлении нового комментария неплохо также обновлять цифру с количеством комментариев, которую обычно можно найти рядом с датой публикацией поста и в заголовке непосредственно перед самими комментами,
- Вы можете оформить ошибки в виде красивых всплывающих окон или в виде подсказок,
- Очень здорово, если при нажатии на кнопку отправки, на ней будет появляться анимация-прелоадер.
- 7 видеоуроков
- Доступ к теме курса с готовым кодом после каждого урока
- Единоразовый платёж
- Доступ навсегда
- Уроки актуальны в 2023-м году
AJAX — технология взаимодействия PHP и JS/jQuery, которая позволяет получать информацию от сервера в фоновом режиме без перезагрузки страницы.
Методика построения запросов на основе AJAX доступна во многих системах управления контентом, и WordPress здесь не является исключением.
AJAX в клиентской части WordPress
Асинхронные запросы основе AJAX применяются для динамической загрузки контента в целях повышения отзывчивости пользовательского интерфейса.
Для создания и выполнения запроса в пользовательской части WordPress потребуется три компонента:
- JS-код в клиентской части для запуска запроса с параметрами;
- PHP-код в серверной части для обработки запроса и отправки результата.
- HTML-элемент: форма, кнопка или ссылка.
Переменная ajaxurl
Самый оптимальный способ определить переменную ajaxurl
— прикрепиться к одному из основных скриптов в теме оформления с применением функции локализации строки:
add_action('wp_footer', 'app_footer_scripts');
function app_footer_scripts() {
wp_enqueue_script( 'app-core', get_template_directory_uri() . '/assets/js/app.min.js', [], THEME_VERSION );
/**
* AJAX
*/
wp_localize_script( 'app-core', 'ajax',
[
'url' => admin_url('admin-ajax.php'),
'nonce' => wp_create_nonce('ajax-nonce')
]
);
}
Для проверки корректности вывода, откройте исходный код страницы и проверьте наличие переменной. В этом примере, она будет расположена одной строкой выше от места подключения сценария:
Вы можете прикрепить переменную к любому сценарию в вашей теме вне зависимости от секции его регистрации в исходном коде.
Параметр nonce
В этом примере, кроме адреса для запросов был создан параметр nonce
. Nonce-код — это строка с набором символом, которая может быть использована один раз.
В AJAX запросах проверка с применением nonce-кода используется, когда необходимо убедиться в том, что пользователь выполняет запрос из указанного места.
Создание запроса
WordPress предлагает два хука для определения AJAX-функций:
add_action( 'wp_ajax_(action)', 'my_function_name' );
add_action( 'wp_ajax_nopriv_(action)', 'my_function_name' );
Если ваш запрос предназначен для авторизованных пользователей, используйте хук wp_ajax_
. В случае, если запрос является общедоступным используйте оба хука.
Для демонстрации принципов работы асинхронного запроса в WordPress, напишем функцию, результатом выполнения которой, будет показ текущего времени в окне браузера.
<?php
if( wp_doing_ajax() ) {
add_action( 'wp_ajax_request', 'get_current_time' );
add_action( 'wp_ajax_nopriv_request', 'get_current_time' );
}
function get_current_time() {
if( ! wp_verify_nonce( $_POST['nonce'], 'ajax-nonce' ) ) die();
echo date('h:i:s');
wp_die();
}
?>
jQuery(document).ready(function($) {
$( "#ajax-request" ).click(function() {
var data = {
action: 'request',
nonce: ajax.nonce
};
jQuery.post( ajax.url, data, function(response) {
alert(`Сейчас: ` + response);
});
});
});
Функция $.ajax()
лежит в основе всех Ajax запросов, но для простых задач она избыточна:
jQuery(document).ready(function($) {
$( "#ajax-request" ).click(function() {
$.ajax({
type: 'POST',
url: ajax.url,
data: {
action: 'request',
nonce: ajax.nonce,
},
success: function (response) {
alert(`Сейчас: ` + response);
}
});
});
});
Пример Ajax запроса без применения библиотеки jQuery с помощью объекта XMLHttpRequest:
let button = document.getElementById('ajax-request');
button.addEventListener('click', () => {
let xhr = new XMLHttpRequest();
let params = '?action=request&nonce=' + ajax.nonce;
xhr.open("GET", ajax.url + params, true);
xhr.send();
xhr.onload = function () {
alert(`Сейчас: ` + xhr.response);
}
});
let button = document.getElementById('ajax-request');
button.addEventListener('click', request);
async function request() {
const data = new FormData();
data.append('nonce', ajax.nonce);
data.append('action', 'request');
const request = await fetch(ajax.url, { method: 'POST', body: data });
const response = await request.text();
alert(`Сейчас: ` + response);
}
<button id="ajax-request">Который час?</button>
Работа над ошибками
В случае возникновения ошибки в процессе выполнения запроса, система вернет ответ с кодом ошибки:
Показ ошибок в консоли DevTools
Для показа ошибок в консоли разработчика, добавьте код в functions.php
:
<?php
if( WP_DEBUG && WP_DEBUG_DISPLAY && (defined('DOING_AJAX') && DOING_AJAX) ) {
@ ini_set( 'display_errors', 1 );
}
?>
Шаг 1. Подготовка
Как я уже говорил, я предполагаю, что вы базово знаете jQuery, поэтому подобная конструкция для вас ясна как день 🏞
jQuery $ // есть разные варианты этой строчки, но такая мне нравится больше всего, т.к. всегда работает $ . // при клике на элемент с id="misha_button" 'Если это работает, уже неплохо' ; // выводим сообщение ; ;
На всякий случай напомню, что должна быть подключена библиотека jQuery для этого в functions.php
, но не всегда именно туда
, мы добавляем строчку:
, ; truemisha_jquery ;
А непосредственно наш jQuery-код пока что временно можем разместить в футере, после функции wp_footer().
<?php wp_footer <script> jQuery $ $ .click alert 'Если это работает, уже неплохо' ; ; ; </script>
То есть библиотека jQuery теперь у нас подключена через wp_enqueue_script() либо в wp_head(), либо в wp_footer(), наша же задача закинуть наш собственный код jQuery после неё. Знаю, что мы можем сделать это через файл, мы можем сделать это через хук, а можно и просто в шаблоне вывести (у вас это возможно footer.php
будет, но не факт).
В этом уроке для простоты понимания весь мой jQuery код будет находиться в файле footer.php
темы.
Шаг 2. Познакомимся с $. ajax
В jQuery есть несколько способов отправки асинхронных запросов, сам я пользуюсь только $.ajax
, так как он более универсален, остальные – лишь частные случаи из него. В общих чертах, учитывая всё необходимое, код будет выглядеть вот так👇
jQuery $ $ . $. url: , type: , data: , // можно также передать в виде объекта beforeSend: xhr $ . ; , success: data $ . ; data ; ; // если элемент – ссылка, то не забываем: // return false; ; ;
data: param1: , param2:
7-9
– это функция, которая выполнится перед отправкой запроса, тут можно годно активировать всякие прелоадеры, я вот например изменил текст кнопки .11-14
– это функция запускается сразу после получения данных, а данные это… параметр этой функции конечно же, он может называться по-разному, у меня —data
- У функции
$.ajax
есть много прикольных параметров, я рекомендую попрактиковаться с ними, документацию можете найти на официальном сайте.
Так, теперь самая важная часть – обработка запроса в PHP. У нас с вами есть файл myajax.php
, который находится в корне сайта, пусть он сложит два параметра – param1 и param2 и возвратит нам их сумму.
Почему мы складываем числа в PHP, когда это можно сделать непосредственно в JavaScript на стороне клиента? Потому что мы учимся, Карл! Если слишком легко для тебя, отправляйся в пост посложнее или ещё сложнее.
Шаг 3. Познакомимся со стандартным обработчиком асинронных запросов в WordPress – admin-ajax. php
Сам код отправки асинхронного запроса изменится совсем чуть-чуть:
- На 4й строчке мы указываем на путь на наш собственный файл-обработчик, а на стандартный вордпрессовский, он всегда находится в одном месте —
https://misha.agency/wp-admin/admin-ajax.php
(только домен моего сайта замените на свой, очень прошу). Так как я использую мой код в файлеfooter.php
, в среде WordPress, то я могу получить путь к этому файлу динамически, например при помощи функции admin_url()
или site_url(). - На 6-й строке, там где передаются параметры, обязательно нужно указать параметр
action
с каким-нибудь произвольным значением, которое мы будем подцеплять чуть позже.
jQuery$ $. $. url: , type: , data: , // можно также передать в виде массива или объекта beforeSend: xhr $.; , success: data $.; data ; ; // если элемент – ссылка, то не забываем: // return false; ; ;
И вторым шагом нужно будет создать функцию в
functions.php
и повесить её на два хука (если используете AJAX в админке, то только на один кстати).
, ; , ; // первый хук для авторизованных, второй для не авторизованных пользователей truemisha_ajax = + ; ; ; // даём понять, что обработчик закончил выполнение
Распространённые ошибки
Ошибиться можно много где угодно, но исправление ошибок тут по большей части работа с консолью браузера и понимание некоторых основных вещей.
- 7 видеоуроков
- Доступ к теме курса с готовым кодом после каждого урока
- Единоразовый платёж
- Доступ навсегда
- Уроки актуальны в 2023-м году
Если ваша тема соответствует стандартам WooCommerce, то хлебный крошки должны отображаться на страницах архивов и на странице товара, так как событие входит в состав события woocommerce_before_main_content
с приоритетом :
// Вот так изначально должно срабатывать событие вывода хлебных крошек add_action( 'woocommerce_before_main_content', 'woocommerce_breadcrumb', 20 );
Что можно сделать с самим событием?
Как и с любым другим событием, с можно:
- Отключить, тем самым вовсе отказаться от хлебных крошек.
- Поменять приоритет отображения.
- Добавить хлебные крошки на другие страницы, например на страницу корзины и страницу оформления заказа.
- Добавить к событию новое, свое собственное, событие.
Примеры работы с событием
В качестве примера, давайте добавим отображение хлебных крошек на страницах корзины и оформления заказа:
// Корзина add_action( 'woocommerce_before_cart', 'woocommerce_breadcrumb', 10, 0 ); // Оформление заказа add_action( 'woocommerce_before_checkout_form', 'woocommerce_breadcrumb', 0, 0 );
Обратите внимание!
Хлебные крошки будут отображаться после заголовка страниц. Поднять хлебные крошки выше можно только внеся изменения непосредственно в сам шаблон страницы, обычно это page.php
А совсем отключить хлебные крошки можно так:
// Отключаем вывод хлебных крошек (страницы архивов и страница товара) remove_action( 'woocommerce_before_main_content', 'woocommerce_breadcrumb', 20 );