12 марта 2012

Комментарии WordPress - руководство разработчика

Приветствую вас, уважаемый читатель. Сегодня я предлагаю расставить все точки над «ё» в вопросе работы с комментариями WordPress.

На мой взгляд, блок комментариев — это самая сложная и запутанная часть движка WordPress. Я постараюсь осветить все вопросы установки и настройки древовидных комментариев. Мне очень нравится именно древовидный формат, т. к. он дает четкое понимание дискуссии и не нужно прыгать с одного комментария на другой для поиска ответа.

Итак, приступим.

В предыдущей публикации мы начали верстать тему для WordPress. Внешний вид всех страниц блога формировался одним файлом — index.php в папке с нашей темой. Движок WordPress устроен таким образом, что если в папке с темой создать файл single.php, то уже именно он будет отвечать за отображение страницы отдельного поста (если файла single.php в папке с темой нет, то за отображение страницы поста отвечает файл index.php).

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

В месте, где мы хотим увидеть блок комментариев, необходимо указать код вызова функции comments_template().

Я полностью скопировал содержимое файла index.php в файл single.php и в петлю, отображающую содержимое поста, включил функцию, выводящую блок комментариев WordPress — comments_template в 7-й строке листинга 1. Таким образом, в конце каждой страницы отдельного поста будет выводится блок комментариев.

Листинг 1. Стандартная петля WordPress и вывод комментариев. Файл single.php

<?php if(have_posts()): ?>
<?php while(have_posts()): the_post(); ?>
<article>
	<h1><?php the_title();?></h1>
	<?php the_content();?>
</article>
<?php comments_template('', true); ?>
<?php endwhile; ?>
<?php else: ?> <p>Ничего не найдено</p>
<?php endif; ?>

В скобках, при вызове функции comments_template, можно указать два аргумента:

  1. Имя файла, обрабатывающего вывод комментариев. Если мы указываем пустое значение, то обрабатывать комментарии WordPress по умолчанию будет файл comments.php в папке с нашей темой. Мы можем передать строку с любым другим названием файла и тогда WordPress обратиться к файлу с переданным именем за кодом отображения комментариев.
  2. Нужно ли разделять комментарии по типу (обычные комментарии, pingback и trackback). Значение, передаваемое данным параметром, должно быть либо TRUE, либо FALSE. Видимо, данный механизм фильтрации применим только для работы со стандартной внутренней функцией вывода списка комментариев движка WordPress. Но, поскольку мы будем использовать свою собственную функцию отображения комментариев, данный параметр никакого значения для нас не имеет.

Я вызываю комментарии следующей директивой (строка 7 листинга 1)

<?php comments_template('', true); ?>

Как видите, мне потребуется создать в папке с темой файл comments.php, в котором я буду описывать код работы с комментариями WordPress (ведь я передал пустое значение первым аргументом функции). Кроме того, на всякий случай, я включил разделение комментариев (обычные комментарии, pingback и trackback) значением TRUE второго аргумента функции.

Хочу заметить, что именно дроблением кода на сущности, выполняющие независимые друг от друга операции можно добиться гибкости решения. В случае движка WordPress мы видим, что код, выполняющий обособленную функцию (вывод комментариев) помещается в отдельный файл. И нам будет достаточно внести правки в одном месте, для изменения вида комментариев на всем сайте. Это очень удобный и правильный подход.

Отображение комментариев WordPress файлом comments.php

Итак, в папке с нашей темой необходимо создать файл comments.php, в котором мы будем описывать код отображения комментариев.

В начале файла, для целей дополнительной SEO-оптимизации, предлагаю разместить следующий HTML-код:

<h3>Комментарии к посту «<?php the_title();?>»</h3>

Заголовок третьего уровня, содержащий название поста — думаю, это не плохо с точки зрения SEO.

После заголовка приступим непосредственно к отображению списка комментариев к загруженному посту. Для этого достаточно добавить функцию wp_list_comments() в файл comments.php.

Если в посте есть комментарии, то уже сейчас вы увидите их список. Посмотрите HTML-код отображения комментариев — каждый комментарий заключен в теги <li></li> по умолчанию (именно так работает стандартная функция отображения комментариев движка WordPress).

Естественное желание, добавить теги <ul></ul> перед списком. В результате нормальный код, отображающий комментарии WordPress, будет выглядеть следующим образом:

Листинг 2. Отображение комментариев в WordPress. Файл comments.php

<h3>Комментарии к посту «<?php the_title();?>»</h3>
<div class="main-list-comments">
	<ul>
		<?php wp_list_comments($args); ?>
	</ul>
</div>

Как видно из листинга 2, в качестве аргумента функции wp_list_comments передан массив $args. Именно его содержимое меняет настройки отображения комментариев по умолчанию.

Перед кодом, показанным в листинге 2, я укажу инструкции, заполняющие необходимыми мне значениями строки массива $args для изменения способа отображения комментариев WordPress по умолчанию (см. листинг 3).

Листинг 3. Изменение настроек отображения комментариев по умолчанию

<?php $args = array(
	 'avatar_size'       => 45,
	 'reply_text'       => 'Ответить на комментарий',
	 'callback'          => 'mytheme_comment',
    ); ?>
  • Строка 2 — изменяет размер аватара комментатора до 45 пикселов в ширину (против 32 пикселов по умолчанию).
  • Строка 3 — задает текст ссылки для ответа на комментарий.
  • Строка 4 — указывает название функции, которая будет обрабатывать отображение комментариев. В нашем случае WordPress обратиться к файлу functions.php в папке с активной темой и воспользуется кодом функции mytheme_comment, описанной там. Если параметр callback в массиве $args не указан, то WordPress использует стандартный способ отображения комментариев, описанный в ядре движка. Поскольку я хочу изменить стандартный способ отображения комментариев (убрать дату добавления комментария WordPress) и сделать это гибко — я использую свою собственную функцию отображения комментариев (mytheme_comment), отличную от стандартного представления WordPress ровно на столько, на сколько моей душеньке будет угодно.

Название и значения всех возможных полей массива $args можно посмотреть на странице официального руководства к функции wp_list_comments().

В чем же заключается гибкость подхода к изменению отображения комментариев. Способ «ковыряния ядра» (внесение изменений в файлы /wp-includes/comment-template.php, /wp-includes/comment.php, отвечающие за стандартный вывод комментариев WordPress с целью, например, удаления все той же даты комментирования) явно таки не гибкий. Ведь внесенные изменения исчезнут после обновления WordPress, поскольку обновление сводится к замене файлов ядра новыми, обновленными версиями (а разработчики WordPress, к сожалению, не уведомлены о внесенных вами негибких изменениях).

Негибкое решение приведет к невозможность просто надеть новую тему оформления на движок WordPress копированием папки с файлами темы в директорию wp-content/themes — необходимо еще и «поковырять ядро» в соответствии с вашими инструкциями.

Мы пойдем другим путем и все наши действия не выйдут за пределы папки с темой. Это будет гибкое решение. Подход внесения изменений только в файлы темы единственно правильный.

Прежде чем перейти к написанию функции mytheme_comment давайте закончим с файлом comments.php.

Мы уже знаем, что в случае, если у поста есть комментарии, их можно отобразить функцией wp_list_comments(). А как же быть, когда комментариев у записи нет или они отключены в админке?

— Для этого нам пригодиться следующий код, который мы вставим под листинг 2 (см листинг 4).

Листинг 4. Проверка на разрешение комментирования данной записи. В случае, если комментарии разрешены, выполняется проверка наличия комментариев. Файл comments.php

<?php if (!comments_open())
{
	echo "<p class='nocomments'>Комментарии запрещены</p>";
}
else
{
	if (!get_comments_number())
	{	
			echo "<p class='nocomments'>Комментариев пока нет, будьте первым.</p>";
	}	
}
?>
  • Функция comments_open() проверяет разрешены ли комментарии. Если комментарии запрещены функция вернет значение FALSE, которое будет инвертировано в TRUE оператором «!» и WordPress отобразит текст «Комментарии запрещены».
  • Иначе (оператор «else»), если комментарии разрешены, функция get_comments_number() посчитает их количество. Если количество комментариев равно нулю (что, по сути, идентично значению FALSE в понимании оператора «if») инверсия восклицательным знаком позволит отобразить текст «Комментариев пока нет, будьте первым».

Таким образом, когда комментарии в админке WordPress запрещены, будет отображаться надпись «Комментарии запрещены» и скрываться форма добавления нового комментария (о форме добавления комментария поговорим чуть позже).

Если комментарии разрешены, но пока никто не прокомментировал пост, будет выводиться надпись «Комментариев пока нет, будьте первым».

Я думаю у вас, уважаемый читатель, к данному моменту должно быть достаточно знаний, чтобы самостоятельно придумать код, скрывающий заголовок <h3>Комментарии к посту «<?php the_title();?>»</h3>, в случае, если комментарии запрещены. А сделать это было бы вполне логично.

Функция mytheme_comment, отображающая комментарии

Благодаря 4-й строке листинга 3, для отображения комментариев WordPress воспользуется функцией mytheme_comment, которую необходимо описать в файле functions.php нашей темы.

Листинг 5. Код функции mytheme_comment. Файл functions.php

<?php
function mytheme_comment($comment, $args, $depth)
{
	$GLOBALS&#91;'comment'&#93; = $comment;
	switch ( $comment->comment_type ) :
		case '' :
?>
	   <li <?php comment_class(); ?> id="li-comment-<?php comment_ID() ?>">
			<div id="comment-<?php comment_ID(); ?>">
				<div class="comment-author vcard">
					<?php edit_comment_link( __( 'Редактировать' ), ' ' ); ?>
					<?php echo get_avatar( $comment->comment_author_email, $args['avatar_size']); ?>
					<?php printf(__('<cite class="fn">%s</cite> <span class="says">says:</span>'), get_comment_author_link()) ?>
				</div>

				<div class="comment-meta commentmetadata">
					<a href="<?php echo esc_url( get_comment_link( $comment->comment_ID ) ) ?>"><?php printf(__('%1$s at %2$s'), get_comment_date(),  get_comment_time()) ?></a>
				</div>

<?php if ($comment->comment_approved == '0') : ?>
				<div class="comment-awaiting-verification"><?php _e('Your comment is awaiting moderation.') ?></div>
			 <br />
<?php endif; ?>
				<?php comment_text() ?>
				<div class="reply">
					<?php comment_reply_link(array_merge( $args, array('depth' => $depth, 'max_depth' => $args['max_depth']))) ?>
				</div>
			</div>

<?php
		break;
		case 'pingback'  :
		case 'trackback' :
?>
			<li class="post pingback">
				<?php comment_author_link(); ?>
				<?php edit_comment_link( __( 'Редактировать' ), ' ' ); ?>
<?php
		break;
	endswitch;
}
&#91;/sourcecode&#93;

Функция полностью реализует <strong>стандартные комментарии WordPress</strong>. Но теперь мы сможем <strong>гибко</strong> изменять функционал комментариев. Например, для удаления ненавистной даты добавления комментария, достаточно убрать строки 16 — 18 листинга 5.

Дам пояснение к листингу 5.

4-я строка листинга получает из массива с комментариями один конкретный комментарий и дальше программа работает именно с ним.

5-я строка проверяет тип комментария. Если комментарий обычный, то выполняется код строк 7 — 30. Если тип комментария pingback или trackback будут выполнены инструкции в строках 34 — 39.
<blockquote>По поводу комментариев типа pingback trackback мнение неоднозначное. Считается, что данные типы комментариев используются, в основном, для спама. Кроме того, если обратить внимание на понижение ценности ссылки при взаимном обмене таковыми, trackback становится вредным с точки зрения SEO. А, стало быть, не нужные trackback и pingback комментарии можно запросто отключить удалением строк 32 — 39.</blockquote>
Теперь обратим внимание на строки 7 — 30, выводящие содержимое обычного комментария. В них присутствует множество интересных функций WordPress:

строка 8, <a href="http://codex.wordpress.org/Function_Reference/comment_class">comment_class()</a> — функция, возвращающая классы, присваиваемые конкретному комментарию (благодаря данной функции можно различить четные и нечетные комментарии, комментарии автора поста и т. д.);

строка 8, 9 <a href="http://codex.wordpress.org/Function_Reference/comment_ID">comment_ID()</a> — возвращает идентификатор обрабатываемого в данный момент комментария (в верстке присутствует обязательно, для реализации древовидных комментариев и прокрутки страницы к комментарию с заданным идентификатором);

строка 11, <a href="http://codex.wordpress.org/Function_Reference/edit_comment_link">edit_comment_link</a><a href="http://codex.wordpress.org/Function_Reference/edit_comment_link">()</a> — функция, выводящая ссылку «Редактировать», в случае, если авторизованный пользователь обладает правами редактирования комментариев;

строка 12, <a href="http://codex.wordpress.org/Function_Reference/get_avatar">get_avatar()</a> — функция, возвращающая код для отображения аватара комментатора (1-й аргумент передает e-mail для получения аватара, 2-й забирает из массива $args значение поля avatar_size, указывающее размер аватара — размер мы передавали в листинге 3);

строка 13 — выводит имя комментатора и ссылку на его сайт;

строки 20 — 23 выполняют проверку одобрения комментария, если одобрения не было — выводится стандартный текст, сообщающий об ожидании модерации;

строка 24, <a href="http://codex.wordpress.org/Function_Reference/comment_text">comment_text()</a> — выводит текст комментария;

строка 26, <a href="http://codex.wordpress.org/Function_Reference/comment_reply_link">comment_reply_link()</a> — отображает ссылку ответа на комментарий.

На этом с файлом functions.php и функцией mytheme_comment покончено. Комментарии выводить мы научились, остается позаботиться об их внешнем виде.
<h2>Верстка комментариев WordPress</h2>
Как упоминалось ранее, в 8-й строке mytheme_comment (листинг 5) используется функция comment_class, которая наделит комментарии всеми необходимыми классами для последующего закрепления за ними стилей отображения.

Если комментарий верхнего уровня нечетный, то в атрибуте <em>class</em> тега &lt;li&gt;, обрамляющего данный комментарий, будет содержаться значение thread-even.

Для четного — thread-alt.

Вложенные нечетные комментарии имеют класс even. Четные — alt.

Вложенные комментарии (имеется ввиду древовидная структура комментариев WordPress) охватываются тегом &lt;ul class='children'&gt;. В результате, задав отступ (padding-left) для класса children, можно визуально обозначить вложения.

Если комментарий оставил автор поста, то к тегу &lt;li&gt; добавиться класс bypostauthor. Тем самым, добавив желаемые стили отображения классу bypostauthor, можно добиться особого внешнего вида для комментария автора.

При этом класс bypostauthor будет назначен комментарию только в том случае, если комментатор был залогинен в WordPress и его учетная запись совпадает с учетной записью автора поста.

Если комментатор окажется автором поста, но при этом не будет авторизован при добавлении комментария — его комментарий не получит класс bypostauthor. Данная проблема решается установкой плагина <a href="http://wordpress.org/extend/plugins/highlight-author-comments/">Highlight Author Comments</a>, заданным образом выделяющего комментарий автора поста. Работает плагин по следующему принципу — он сравнивает эл. почту автора поста с эл. почтой комментатора и, в случае их совпадения, выделяет комментарий. Использование данного плагина наиболее удобный вариант выделения авторского комментария.
<h2>Форма добавления комментария WordPress</h2>
Теперь познакомимся со способом отображения формы ввода нового комментария.

Для решения данной задачи существует стандартная функция WordPress <a href="http://codex.wordpress.org/Function_Reference/comment_form">comment_form()</a>.

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

Вызов функции comment_form() имеет смысл разместить в конце файла comments.php нашей темы. Таким образом, после отображения списка комментариев будет показана форма добавления нового комментария.

<img src="http://www.sdelaysite.com/img/commentswp/1.png" alt="Стандартная форма добавления комментариев в WordPress" />

Рис. 1. Стандартная форма добавления нового комментария в WordPress.

Разберемся с вопросом <strong>изменения стандартного вида формы добавления нового комментария</strong>.

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

Предположим, я хочу отключить подпись под формой («<em>Можно использовать следующие </em><em>HTML</em><em>-теги и атрибуты</em><code><em>…</em></code><code>»</code>). Для этого мне нужно сформировать массив, с соответствующим значением и передать его в функцию comment_form аргументом.

<strong>Листинг 6. Отключение подписи под формой добавления нового комментария. Файл comments.php</strong>


$comments_args = array(
        'comment_notes_after' => '',
);

comment_form($comments_args);

Я передал пустое значение полю comment_notes_after массива $comments_args и подпись в форме исчезла.

С другими полями массива аргументов данной функции можно познакомиться в официальном руководстве comment_form().

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

Листинг 7. Код вызова JavaScript для «подъема» формы комментирования при ответе. Размещается в разделе <head>

<?php
if ( is_singular() && get_option( 'thread_comments' ) )
wp_enqueue_script( 'comment-reply' );

wp_head();
?>

Подробнее о коде раздела <head> в WordPress.

Подключение плагина «Привет, Комментатор!»

Димокс написал замечательный плагин «Привет, Комментатор!», позволяющий, в случае повторного добавления комментария, не отображать поля ввода имени, адреса эл. почты и сайта комментатора — вместо этого выводится очень приятно приветствие, например, «С возвращением, Андрей Морковин!».

Результат работы плагина Привет, Комментатор!

Рис. 2. Плагин «Привет, Комментатор!» в действии.

Подробнее о плагине «Привет, Комментатор!»

Мне нравится этот плагин. Я думаю, что он отлично стимулирует к комментированию постов, да и просто приятно получается.

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

Как Димокс написал в официальном мануале, необходимо обхватить поля ввода имени, e-mail и сайта комментатора блоком <div id=”author-data”></div>. Сделать это можно при помощи все того же вышеописанного массива аргументов $comments_args.

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

1. Сначала необходимо сформировать дополнительный массив, содержащий строки: author, email, url. В данные строки внести HTML-код верстки трех наших полей ввода и подписей к ним.

Листинг 8. Изменение верстки полей ввода имени, e-mail и сайта комментатора. Файл comments.php

$fields =  array(
	'author' => '<div id="author-data"><p class="comment-form-author">' . '<label for="author">' . __( 'Name' ) . '</label> ' . ( $req ? '<span class="required">*</span>' : '' ) .
	            '<input id="author" name="author" type="text" value="' . esc_attr( $commenter&#91;'comment_author'&#93; ) . '" size="30"' . $aria_req . ' /></p>',
	'email'  => '<p class="comment-form-email"><label for="email">' . __( 'Email' ) . '</label> ' . ( $req ? '<span class="required">*</span>' : '' ) .
	            '<input id="email" name="email" type="text" value="' . esc_attr(  $commenter&#91;'comment_author_email'&#93; ) . '" size="30"' . $aria_req . ' /></p>',
	'url'    => '<p class="comment-form-url"><label for="url">' . __( 'Website' ) . '</label>' .
	            '<input id="url" name="url" type="text" value="' . esc_attr( $commenter&#91;'comment_author_url'&#93; ) . '" size="30" /></p></div>',
);

Обратите внимание, для подключения плагина «Привет, Комментатор!» я добавил <div id="author-data"> перед полем ввода имени комментатора, как того и требовал Димокс (строка 3 листинга 8).

В конце строки 8 я закрываю открытый блок — </div>.

2. Сформированный массив $fields необходимо передать нашему старому знакомому — массиву аргументов $comments_args.

Листинг 9. Передача содержимого массива $fields в массив $comments_args. Ниже листинга 8 в файле comments.php

$comments_args = array(
	'fields' => $fields,
        'comment_notes_after' => '',
);

Все, теперь верстка трех полей ввода в форме комментирования будет изменена на переданное значение.

Тем самым, необходимые изменения для подключения плагина «Привет, Комментатор!» выполнены.

Пользуясь случаем передаю привет Диме и благодарность за такой замечательный плагин.

Подключение предпросмотра комментариев WordPress

Еще один замечательный плагин от Димокса — плагин реализующий предпросмотр комментариев в WordPress.

Для его нормальной работы нам потребуется растянуть область ввода тела комментария <textarea>.

Несоответствие ширины поля ввода и шапки плагина

Рис. 3. Несоответствие длины «крышки» плагина и области ввода текста.

Сделать это можно просто указав стиль width: 99.1% для идентификатора comment (по умолчанию <textarea> для ввода тела комментария имеет именно такой идетификатор).

Именно 99.1%, я не шучу. При длине в 100% справа получается ступенька.

Проблема с версткой поля ввода комментария WordPress

Рис. 4. Ступенька.

Мало того, как видно из рис. 4, в Google Chrome получается зазор между «шапкой» плагина и областью ввода (причины сей фигни мне не известны).

По умолчанию в атрибутах <textarea> указана длина в 45 символов (cols="45"). Для чистоты верстки неплохо бы сменить данный параметр на пустое значение. А мы, заодно, посмотрим, каким же образом изменить стандартную верстку области ввода комментария.

Оказывается, достаточно внести строку comment_field в массив $comments_args. Значением данной строки передаст HTML-код области ввода комментария и подписи к нему (4-я строка листинга 10).

Листинг 10. Изменение области ввода тела комментария

$comments_args = array(
		'fields' => $fields,
        'comment_notes_after' => '',
		'comment_field' => '<p class="comment-form-comment"><label for="comment">' . _x( 'Comment', 'noun' ) . '</label><textarea id="comment" name="comment" cols="" rows="8" aria-required="true"></textarea></p>'
);

Еще раз передаю привет и благодарность Диме за отличный плагин.

Борьба со спамом в комментариях

Серьезная проблема — это спам в комментариях WordPress. Для эффективной борьбы с ним есть отличный плагин Antispam Bee.

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

Подписка на комментарии

Установка плагина Subscribe To Comments позволит реализовать возможность подписки на комментарии к записи блога. В случае появления нового комментария WordPress отправит сообщение на эл. почту подписчика.

В моем блоге вы можете наблюдать галочку подписки рядом с формой добавления комментария — это результат работы плагина.

Кроме того, в конце файла comments.php можно указать код <?php show_manual_subscription_form(); ?>, который вызовет форму подписки на комментарии без необходимости комментировать самому.

HTML код в комментариях WordPress

По умолчанию WordPress обрезает HTML-теги в комментариях. Решить эту проблему можно установкой плагина PixoPoint Code Comments Plugin. После установки данного плагина, HTML код, охваченный тегами <code></code> будет отображаться без изменений (еще и с подсветкой).

Благо плагин предпросмотра комментариев от Димокса имеет кнопку «code» в визуальном редакторе.

Спасибо за внимание.

Желающие могу скачать исходники темы (15.5 кБ, *.zip).

← Предыдущая публикация курса

С уважением, Андрей Морковин.

Плюсануть
Поделиться
Отправить
Класснуть
Линкануть
Запинить