AJAX комментарии
Урок 6
Итак, комментарии на AJAX. Перед написанием этого поста я потратил добрую половину дня на их разработку — хорошо, что я уже был с ними знаком. В самый первый раз, когда я ещё начинал изучать jQuery, на создание асинхронных комментариев с нуля у меня ушли первые две недели января.
Чтобы скачать готовый код из этого урока, вам нужно купить курс.
Кстати, я долго думал, имеет ли смысл поставить комментарии со стороннего сервиса, например disqus — но в итоге решил что свои комментарии на AJAX будут покруче.
Вот как примерно выглядит отправка комментария:
Итак, допустим, мы только что решили поставить асинхронные комментарии у себя на сайте. Какую функциональность, на наш взгляд, они должны иметь?
comment-reply.js
,alert()
пока что,В этом уроке я использовал стандартную тему WordPress Twenty Twenty One. Обратите внимание на скриншот из этой темы, как расположены элементы списка и формы комментариев, чтобы сориентироваться по атрибутам class
и id
.
Если у вас что-то добавляется не туда, посмотрите, как я проверял это всё на видео.
Если у вас со структурой всё окей, то стили по сути и не понадобятся, за исключением оформления ошибок, возникающих в результате валидации полей. То есть, если кто-то ввёл неверный адрес email, поле должно стать красного цвета (например).
input.error, textarea.error{ background: #fe0000; /* или background:red или любой другой цвет, который больше вписывается в дизайн вашего блога */ }
Добавляем этот код в основной файл стилей вашей темы, обычно это — style.css
.
Во-первых, давайте в папке с темой создадим какой-нибудь файл 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() соответственно.
Открываем наш файл 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; }); });
Читайте подробнее о том, как обрабатываются асинхронные запросы в 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; }
Также есть доработки, которые я не буду добавлять, дабы не усложнять пост, но вам стоит попробовать сделать их самим: