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

Опубликовано: 01.09.2018

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

5.Вывод комментариев и форма отправки комментариях

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


Создание комментариев на сайте

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

Требования к AJAX-комментам

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


Изучаем jQuery | Урок №21 - Форма комментариев

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

Шаг 1. Подготовка. Структура HTML.

Будем отталкиваться от стандартных тем WordPress, это Twenty Ten и Twenty Eleven. Разумеется, то, что представлено в следующем куске кода — всего лишь HTML-шаблон, который должен сориентировать вас по атрибутам class и id, а также по расположению элементов, а вообще все эти штуки делаются через php!

<!-- можно <ul> или <ol> --> < ol class= "commentlist" > <!-- класс depth-1 показывает уровень вложенности --> < li class= "comment depth-1" id= "li-comment-4" > < div id= "comment-4" > <!-- тут содержимое комментария --> < div class= "reply" > < a class= "comment-reply-link" >Ответить</ a> </ div > </ div > <!-- дальше идут ответы к предыдущему комментарию --> < ul class= "children" > <!-- depth-2 - значит вложенность второго уровня --> < li class= "comment depth-2" id= "li-comment-5" > < div id= "comment-5" > <!-- тут содержимое комментария --> < div class= "reply" > < a class= "comment-reply-link" >Ответить</ a> </ div > </ div > </ li > </ ul > </ li > </ ol > < div id= "respond" > <!-- тут нужно обратить внимание также на атрибуты name --> < a id= "cancel-comment-reply-link" style= "display:none;" >Отменить ответ</ a> < form id= "commentform" > < input name= "author" id= "author" type= "text" /> < input name= "email" id= "email" type= "text" /> <!-- или type="email", как хотите --> < input name= "url" id= "url" type= "text" /> < textarea name= "comment" id= "comment" ></ textarea > < input name= "submit" type= "submit" id= "submit" value= "Отправить" /> <!-- если у вас нет hidden-полей попробуйте вставить их через php-функцию comment_id_fields() --> < input type= "hidden" name= "comment_post_ID" /> < input type= "hidden" name= "comment_parent" /> </ form > </ div >

Так что, если у вас что-то добавляется не туда, куда надо, сверяйтесь по этому листингу.

Примерно так это будет выглядеть:

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

Шаг 2. CSS

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

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

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

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

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

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

Следующий код вставляем в файл functions.php вашей текущей темы:

function true_include_my_comment_script ( ) { wp_enqueue_script ( 'jquery' ) ; wp_enqueue_script ( 'commentjs' , get_stylesheet_directory_uri ( ) . '/comments.js' , array ( 'jquery' ) , null ) ; } add_action ( 'wp_enqueue_scripts' , 'true_include_my_comment_script' ) ;

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

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

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

jQuery. extend ( jQuery. fn , { /* * функция проверки, что длина поля не меньше 3х символов */ checka : function ( ) { if ( jQuery ( this ) .val ( ) .length < 3 ) { jQuery ( this ) .addClass ( 'error' ) ; return false } else { jQuery ( this ) .removeClass ( 'error' ) ; return true } } , /* * функция проверки правильности введенного email */ checke : function ( ) { var emailReg = /^([\w-\.][email protected]([\w-]+\.)+[\w-]{2,4})?$/ ; var emailaddressVal = jQuery ( this ) .val ( ) ; if ( ! emailReg. test ( emailaddressVal ) || emailaddressVal == "" ) { jQuery ( this ) .addClass ( 'error' ) ; return false } else { jQuery ( this ) .removeClass ( 'error' ) ; return true } } , } ) ; jQuery ( function ( $) { $ ( '#commentform' ) .submit ( function ( ) { // может такое случиться, что пользователь залогинен - нужно это проверить, иначе валидация не пройдет if ( $( "#author" ) .length ) var author = $ ( "#author" ) .checka ( ) ; if ( $( "#email" ) .length ) var email = $ ( "#email" ) .checke ( ) ; var comment = $ ( "#comment" ) .checka ( ) ; // небольшое условие для того, чтобы исключить двойные нажатия на кнопку отправки // в это условие также входит валидация полей if ( ! $( '#submit' ) .hasClass ( 'loadingform' ) && ! $( "#author" ) .hasClass ( 'error' ) && ! $( "#email" ) .hasClass ( 'error' ) && ! $( "#comment" ) .hasClass ( 'error' ) ) { $. ajax ( { type : 'POST' , url : 'http://' + location. host + '/wp-admin/admin-ajax.php' , data : $ ( this ) .serialize ( ) + '&action=ajaxcomments' , beforeSend : function ( xhr ) { // действие при отправке формы, сразу после нажатия на кнопку #submit $ ( '#submit' ) .addClass ( 'loadingform' ) .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 ) { // Если уже есть какие-то комментарии if ( $( '.commentlist' ) .length > 0 ) { // Если текущий комментарий является ответом if ( $( '#respond' ) .parent ( ) .hasClass ( 'comment' ) ) { // Если уже есть какие-то ответы if ( $( '#respond' ) .parent ( ) .children ( '.children' ) .length ) { $ ( '#respond' ) .parent ( ) .children ( '.children' ) .append ( newComment ) ; } else { // Если нет, то добавляем <ul class="children"> newComment = '<ul class="children">' + newComment + '</ul>' ; $ ( '#respond' ) .parent ( ) .append ( newComment ) ; } // закрываем форму ответа $ ( "#cancel-comment-reply-link" ) .trigger ( "click" ) ; } else { // обычный коммент $ ( '.commentlist' ) .append ( newComment ) ; } } else { // если комментов пока ещё нет, тогда newComment = '<ul class="commentlist">' + newComment + '</ol>' ; $ ( '#respond' ) .before ( $( newComment ) ) ; } // очищаем поле textarea $ ( '#comment' ) .val ( '' ) ; } , complete : function ( ) { // действие, после того, как комментарий был добавлен $ ( '#submit' ) .removeClass ( 'loadingform' ) .val ( 'Отправить' ) ; } } ) ; } return false ; } ) ; } ) ;

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

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

<?php // если вы вставляете код не в новый файл, то <?php нужно удалить function true_add_ajax_comment ( ) { global $wpdb ; $comment_post_ID = isset ( $_POST [ 'comment_post_ID' ] ) ? ( int ) $_POST [ 'comment_post_ID' ] : 0 ; $post = get_post ( $comment_post_ID ) ; if ( empty ( $post -> comment_status ) ) { do_action ( 'comment_id_not_found' , $comment_post_ID ) ; exit ; } $status = get_post_status ( $post ) ; $status_obj = get_post_status_object ( $status ) ; /* * различные проверки комментария */ if ( !comments_open ( $comment_post_ID ) ) { do_action ( 'comment_closed' , $comment_post_ID ) ; wp_die ( __ ( 'Sorry, comments are closed for this item.' ) ) ; } elseif ( 'trash' == $status ) { do_action ( 'comment_on_trash' , $comment_post_ID ) ; exit ; } elseif ( ! $status_obj -> public && ! $status_obj -> private ) { do_action ( 'comment_on_draft' , $comment_post_ID ) ; exit ; } elseif ( post_password_required ( $comment_post_ID ) ) { do_action ( 'comment_on_password_protected' , $comment_post_ID ) ; exit ; } else { do_action ( 'pre_comment_on_post' , $comment_post_ID ) ; } $comment_author = ( isset ( $_POST [ 'author' ] ) ) ? trim ( strip_tags ( $_POST [ 'author' ] ) ) : null ; $comment_author_email = ( isset ( $_POST [ 'email' ] ) ) ? trim ( $_POST [ 'email' ] ) : null ; $comment_author_url = ( isset ( $_POST [ 'url' ] ) ) ? trim ( $_POST [ 'url' ] ) : null ; $comment_content = ( isset ( $_POST [ 'comment' ] ) ) ? trim ( $_POST [ 'comment' ] ) : null ; /* * проверяем, залогинен ли пользователь */ $user = wp_get_current_user ( ); if ( $user -> exists ( ) ) { if ( empty ( $user -> display_name ) ) $user -> display_name =$user -> user_login ; $comment_author = $wpdb -> escape ( $user -> display_name ) ; $comment_author_email = $wpdb -> escape ( $user -> user_email ) ; $comment_author_url = $wpdb -> escape ( $user -> user_url ) ; $user_ID = get_current_user_id ( ); if ( current_user_can ( 'unfiltered_html' ) ) { if ( wp_create_nonce ( 'unfiltered-html-comment_' . $comment_post_ID ) != $_POST [ '_wp_unfiltered_html_comment' ] ) { kses_remove_filters ( ); // start with a clean slate kses_init_filters ( ); // set up the filters } } } else { if ( get_option ( 'comment_registration' ) || 'private' == $status ) wp_die ( 'Вы должны зарегистрироваться или войти, чтобы оставлять комментарии.' ) ; } $comment_type = '' ; /* * проверяем, заполнил ли пользователь все необходимые поля */ if ( get_option ( 'require_name_email' ) && ! $user -> exists ( ) ) { if ( 6 > strlen ( $comment_author_email ) || '' == $comment_author ) wp_die ( 'Ошибка: заполните необходимые поля (Имя, Email).' ) ; elseif ( !is_email ( $comment_author_email ) ) wp_die ( 'Ошибка: введенный вами email некорректный.' ) ; } if ( '' == trim ( $comment_content ) || '<p><br></p>' == $comment_content ) wp_die ( 'Вы забыли про комментарий.' ) ; /* * добавляем новый коммент и сразу же обращаемся к нему */ $comment_parent = isset ( $_POST [ 'comment_parent' ] ) ? absint ( $_POST [ 'comment_parent' ] ) : 0 ; $commentdata = compact ( 'comment_post_ID' , 'comment_author' , 'comment_author_email' , 'comment_author_url' , 'comment_content' , 'comment_type' , 'comment_parent' , 'user_ID' ) ; $comment_id = wp_new_comment ( $commentdata ) ; $comment = get_comment ( $comment_id ) ; /* * выставляем кукисы */ do_action ( 'set_comment_cookies' , $comment , $user ) ; /* * вложенность комментариев */ $comment_depth = 1 ; while ( $comment_parent ) { $comment_depth ++; $parent_comment = get_comment ( $comment_parent ) ; $comment_parent = $parent_comment -> comment_parent ; } $GLOBALS [ 'comment' ] = $comment ; $GLOBALS [ 'comment_depth' ] = $comment_depth ; /* * ниже идет шаблон нового комментария, вы можете настроить его для себя, * а можете воспользоваться функцией(которая скорее всего уже есть в теме) для его вывода */ ?> <li <?php comment_class ( ); ?> id="li-comment- <?php comment_ID ( ); ?> "> <div id="comment- <?php comment_ID ( ); ?> "> <div class="comment-author vcard"> <?php echo get_avatar ( $comment , 40 ) ; ?> <cite class="fn"> <?php echo get_comment_author_link ( ); ?> </cite> </div> <?php if ( $comment -> comment_approved == '0' ) : ?> <em class="comment-awaiting-moderation">Комментарий отправлен на проверку</em> <br /> <?php endif ; ?> <div class="comment-meta commentmetadata"><a href=" <?php echo esc_url ( get_comment_link ( $comment -> comment_ID ) ) ; ?> "> <?php printf ( '%1$s в %2$s' , get_comment_date ( ), get_comment_time ( ) ) ; ?> </a> <?php edit_comment_link ( 'ред.' , ' ' ) ; ?> </div> <div class="comment-body"> <?php comment_text ( ); ?> </div> </div> </li> <?php die ( ) ; } add_action ( 'wp_ajax_ajaxcomments' , 'true_add_ajax_comment' ) ; // wp_ajax_{значение параметра action} add_action ( 'wp_ajax_nopriv_ajaxcomments' , 'true_add_ajax_comment' ) ; // wp_ajax_nopriv_{значение параметра action}

Комменты можете протестировать прямо на моем блоге, там совсем незначительные изменения в коде, также я протестировал весь код из статьи ничего не меняя, как есть, на теме Twenty Ten.

Со временем пост будет обновляться по мере совершенствования кода в нем, после появления каких-либо доработок.

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

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

Смотрите также

rss