AJAX комментарии

Урок 6

Зарегистрируйтесь или войдите и получите бесплатный доступ к первому уроку курса.

Урок 6

AJAX комментарии в WordPress

Итак, комментарии на AJAX. Перед написанием этого поста я потратил добрую половину дня на их разработку — хорошо, что я уже был с ними знаком. В самый первый раз, когда я ещё начинал изучать jQuery, на создание асинхронных комментариев с нуля у меня ушли первые две недели января.

Чтобы скачать готовый код из этого урока, вам нужно купить курс.

Кстати, я долго думал, имеет ли смысл поставить комментарии со стороннего сервиса, например disqus — но в итоге решил что свои комментарии на AJAX будут покруче.

Вот как примерно выглядит отправка комментария:

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

  • самое главное — возможность работы со стандартными древовидными комментариями comment-reply.js,
  • вывод ошибок, в том числе вордпрессовских, особо с этим заморачиваться не буду, сделаю через alert() пока что,
  • проверка комментария на наличие запрещенных HTML-тегов. Читайте о том, как изменить список разрешенных тегов,
  • модерация комментария при необходимости,
  • запоминание в кукисах значений полей «Имя» и «Email»,
  • исключить возможность двойного нажатия на кнопку «Отправить»,
  • не используем никакие плагины WordPress;

Шаг 1. Структура HTML

В этом уроке я использовал стандартную тему WordPress Twenty Twenty One. Обратите внимание на скриншот из этой темы, как расположены элементы списка и формы комментариев, чтобы сориентироваться по атрибутам class и id.

расположение элементов формы комментариев темы WordPress

Если у вас что-то добавляется не туда, посмотрите, как я проверял это всё на видео.

Шаг 2. CSS

Если у вас со структурой всё окей, то стили по сути и не понадобятся, за исключением оформления ошибок, возникающих в результате валидации полей. То есть, если кто-то ввёл неверный адрес email, поле должно стать красного цвета (например).

input.error, textarea.error{
	background: #fe0000; /* или background:red или любой другой цвет, который больше вписывается в дизайн вашего блога */
}

Добавляем этот код в основной файл стилей вашей темы, обычно это — style.css.

Шаг 3. Подключение скриптов

Во-первых, давайте в папке с темой создадим какой-нибудь файл JavaScript, в который мы потом добавим весь наш код. У меня это будет файл comments.js.

Теперь наша задача — правильно подключить библиотеку jQuery и файл comments.js. Для этого воспользуемся функцией wp_enqueue_script().

Кроме того, нам нужно динамически передать в скрипт URL обработчика AJAX в WordPress, это admin_url( 'admin-ajax.php' ), а передать его можно при помощи функции wp_localize_script().

add_action( 'wp_enqueue_scripts', 'true_include_my_comment_script' );
 
function true_include_my_comment_script() {
 
	wp_enqueue_script( 'jquery' );
 	wp_register_script( 'commentjs', get_stylesheet_directory_uri() . '/comments.js', array('jquery'), null );
	wp_localize_script( 'commentjs', 'misha', array( 'ajaxurl' => admin_url( 'admin-ajax.php' ) ) );
	wp_enqueue_script( 'commentjs' );
 
}

Зайдите в исходный код страницы и посмотрите, появился ли там comments.js, если да — переходим к следующему шагу, если нет — открываем файлы header.php и footer.php и убеждаемся, что там присутствуют функции wp_head() и wp_footer() соответственно.

Шаг 4. Скрипты jQuery

Открываем наш файл comments.js и вписываем туда:

jQuery( function( $ ){
	// действие при отправки формы комментария
	$( '#commentform' ).submit( function() {
 
		var commentForm = $(this),
				respond = $( '#respond' ),
				commentList = $( '.comment-list' ); // .comment-list иногда имеет другой класс
 
		// отправляем запрос
		$.ajax({
			type : 'POST',
			url : misha.ajax_url,
			data : commentForm.serialize() + '&action=sendcomment',
			beforeSend : function( xhr ) {
 
				// изменяем текст кнопки перед отправкой комментария
				$( '#submit' ).val( 'Отправляем' );
 
			},
			error: function (request, status, error) {
 
				// обрабатываем ошибки
				if( status == 500 ){
					alert( 'Ошибка при добавлении комментария' );
				} else if( status=='timeout' ){
					alert( 'Ошибка: Сервер не отвечает, попробуй ещё.' );
				} else {
					// ворпдрессовские ошибочки, не уверен, что это самый оптимальный вариант
					// если знаете способ получше - поделитесь
					var errormsg = request.responseText;
					var string1 = errormsg.split("<p>");
					var string2 = string1[1].split("</p>");
					alert(string2[0]);
				}
 
			},
			success : function( newComment ) {
 
				// console.log( newComment );
 
				if( $( '.comment-list li' ).length > 0 ) { // если есть комментарии
 
					if( respond.parent().hasClass( 'comment' ) ) { // если дочерний комментарий
 
						if( respond.parent().children( '.children' ).length > 0 ) { // если дочерние уже есть
							respond.parent().children( '.children' ).append( newComment );
						} else { // если первый дочерний
							respond.after( '<ol class="children">' + newComment + '</ol>' );
						}
 
					} else { // если обычный комментарий
						commentList.append( newComment );
					}
 
				} else { // если нет комментариев
					respond.before( '<ol class="comment-list">' + newComment + '</ol>' );
				}
 
				$( '#cancel-comment-reply-link' ).trigger( "click" );
				$( '#submit' ).val( 'Отправить комментарий' );
				$( '#comment' ).val(''); // очищаем поле комментария
 
			}
 
		} );
 
		return false;
 
	});
});

Последний шаг. PHP-обработчик

Читайте подробнее о том, как обрабатываются асинхронные запросы в WordPress. Код обработчика:

add_action( 'wp_ajax_sendcomment', 'true_comment' );
add_action( 'wp_ajax_nopriv_sendcomment', 'true_comment' );
 
function true_comment() {
 
	// код из файла wp-comments-post.php
	$comment = wp_handle_comment_submission( wp_unslash( $_POST ) );
	if ( is_wp_error( $comment ) ) {
		$data = (int) $comment->get_error_data();
		if ( ! empty( $data ) ) {
			wp_die(
				'<p>' . $comment->get_error_message() . '</p>',
				__( 'Comment Submission Failure' ),
				array(
					'response'  => $data,
					'back_link' => true,
				)
			);
		} else {
			exit;
		}
	}
 
	$user            = wp_get_current_user();
	$cookies_consent = ( isset( $_POST['wp-comment-cookies-consent'] ) );
 
	do_action( 'set_comment_cookies', $comment, $user, $cookies_consent );
 
	// код из файла comments.php вашей текущей темы
	wp_list_comments(
		array(
			'avatar_size' => 60,
			'style'       => 'ol',
			'short_ping'  => true,
		),
		array( $comment )
	);
 
	die;
 
}

Также есть доработки, которые я не буду добавлять, дабы не усложнять пост, но вам стоит попробовать сделать их самим:

  • При добавлении нового комментария неплохо также обновлять цифру с количеством комментариев, которую обычно можно найти рядом с датой публикацией поста и в заголовке непосредственно перед самими комментами,
  • Вы можете оформить ошибки в виде красивых всплывающих окон или в виде подсказок,
  • Очень здорово, если при нажатии на кнопку отправки, на ней будет появляться анимация-прелоадер.
Купить курс
  • 7 видеоуроков
  • Доступ к теме курса с готовым кодом после каждого урока
  • Доступ навсегда
4000 р2800 р
Скидка 30% до 1 октября