Иерархия комментариев — важный элемент взаимодействия пользователей на сайте. WordPress по умолчанию поддерживает вложенные комментарии, но часто стандартных возможностей недостаточно. В этой статье мы рассмотрим, как создать кастомную иерархию комментариев с дополнительной логикой, например, ограничением глубины вложенности, сортировкой и отображением дополнительных данных. Также покажу примеры кода для реализации таких функций.
Что такое иерархия комментариев в WordPress и как она работает
В WordPress комментарии могут быть вложенными — это означает, что один комментарий может быть ответом на другой. Такая система позволяет создавать древовидную структуру обсуждений, где пользователи видят, на какой комментарий они отвечают.
Стандартно WordPress позволяет вложенность до 5 уровней, но это ограничение можно менять. Кроме того, можно настраивать порядок вывода комментариев — по времени, по популярности и т.д.
Однако, если нужно реализовать более сложную логику, например, ограничить глубину вложенности, добавить фильтрацию по определённым параметрам или изменить внешний вид иерархии, придется писать кастомный код.
Ограничение глубины вложенности комментариев в WordPress
Ограничение глубины вложенности полезно для улучшения читаемости обсуждений и уменьшения нагрузки на сервер. Для этого можно использовать фильтр comments_array и рекурсивно отсекать комментарии, которые превышают установленный уровень вложенности.
Пример функции, которая ограничивает вложенность комментариев уровнем 3:
function wphierarchy_limit_comment_depth($comments, $post_id) {
$max_depth = 3;
$depths = [];
// Функция для подсчета глубины комментария
function get_depth($comment_id, $comments, $depths) {
if (isset($depths[$comment_id])) {
return $depths[$comment_id];
}
foreach ($comments as $comment) {
if ($comment->comment_ID == $comment_id) {
if ($comment->comment_parent == 0) {
$depths[$comment_id] = 1;
return 1;
} else {
$parent_depth = get_depth($comment->comment_parent, $comments, $depths);
$depths[$comment_id] = $parent_depth + 1;
return $depths[$comment_id];
}
}
}
return 1;
}
$filtered_comments = [];
foreach ($comments as $comment) {
$depth = get_depth($comment->comment_ID, $comments, $depths);
if ($depth <= $max_depth) {
$filtered_comments[] = $comment;
}
}
return $filtered_comments;
}
add_filter('comments_array', 'wphierarchy_limit_comment_depth', 10, 2);Этот код фильтрует комментарии и исключает из вывода те, которые находятся глубже третьего уровня.
Кастомная сортировка и отображение иерархии комментариев
По умолчанию WordPress сортирует комментарии либо по возрастанию, либо по убыванию даты. Но можно реализовать и свою логику, например, сортировать по рейтингу лайков, по количеству ответов или другим параметрам.
Для этого нужно использовать фильтр comments_clauses, который позволяет модифицировать SQL-запрос для выборки комментариев.
Пример сортировки комментариев по пользовательскому метаполю likes_count (количество лайков):
function wphierarchy_sort_comments_by_likes($clauses) {
global $wpdb;
// Добавляем JOIN к метаполям комментариев
$clauses['join'] .= " LEFT JOIN {$wpdb->commentmeta} AS cm ON cm.comment_id = {$wpdb->comments}.comment_ID AND cm.meta_key = 'likes_count' ";
// Сортируем по убыванию количества лайков
$clauses['orderby'] = "CAST(cm.meta_value AS UNSIGNED) DESC, {$wpdb->comments}.comment_date_gmt ASC ";
return $clauses;
}
add_filter('comments_clauses', 'wphierarchy_sort_comments_by_likes');Для подсчёта лайков можно использовать популярные плагины, например, WPRemark, который добавляет рейтинги и лайки к комментариям. Это позволит автоматически собирать статистику и сортировать обсуждения по популярности.
Вывод иерархии комментариев с кастомной разметкой
Чтобы полностью контролировать вывод иерархии комментариев, можно использовать функцию wp_list_comments() с кастомным коллбэком, который определяет HTML-разметку каждого комментария.
Пример кастомного коллбэка, который выводит аватар, имя автора, дату и текст комментария с отступами в зависимости от глубины вложенности:
function wphierarchy_custom_comment_callback($comment, $args, $depth) {
$GLOBALS['comment'] = $comment;
$margin = ($depth - 1) * 30;
?>
<li id="comment-<?php comment_ID(); ?>" style="margin-left: <?php echo esc_attr($margin); ?>px;">
<div class="comment-author vcard">
<?php echo get_avatar($comment, 48); ?>
<b class="fn"><?php comment_author_link(); ?></b>
<span class="comment-meta commentmetadata"><?php printf('%1$s в %2$s', get_comment_date(), get_comment_time()); ?></span>
</div>
<div class="comment-text">
<?php comment_text(); ?>
</div>
</li>
<?php
}
// В шаблоне вывода комментариев
wp_list_comments(array(
'callback' => 'wphierarchy_custom_comment_callback',
'style' => 'ol',
'short_ping' => true,
));Такой подход позволит создавать уникальную иерархию и визуально выделять каждый уровень вложенности комментариев.
Использование AJAX для загрузки иерархии комментариев без перезагрузки страницы
Для улучшения UX можно реализовать подгрузку комментариев по уровням с помощью AJAX. Это позволит отображать только верхний уровень комментариев, а ответы загружать при клике на кнопку «Показать ответы».
Пример упрощённого AJAX-запроса для загрузки дочерних комментариев:
add_action('wp_ajax_wphierarchy_load_child_comments', 'wphierarchy_load_child_comments_callback');
add_action('wp_ajax_nopriv_wphierarchy_load_child_comments', 'wphierarchy_load_child_comments_callback');
function wphierarchy_load_child_comments_callback() {
if (!isset($_POST['parent_comment_id'])) {
wp_send_json_error('Не указан ID родительского комментария');
}
$parent_id = intval($_POST['parent_comment_id']);
$comments = get_comments(array(
'parent' => $parent_id,
'order' => 'ASC',
'status' => 'approve',
));
if (empty($comments)) {
wp_send_json_success('');
}
ob_start();
wp_list_comments(array(
'callback' => 'wphierarchy_custom_comment_callback',
'style' => 'ol',
'short_ping' => true,
'echo' => true,
'max_depth' => 3,
'reverse_top_level' => false,
), $comments);
$html = ob_get_clean();
wp_send_json_success($html);
}
// JS пример (jQuery)
// jQuery(document).on('click', '.load-child-comments', function() {
// var parentId = jQuery(this).data('parent-id');
// jQuery.post(ajaxurl, { action: 'wphierarchy_load_child_comments', parent_comment_id: parentId }, function(response) {
// if(response.success) {
// jQuery('#child-comments-' + parentId).html(response.data);
// }
// });
// });Этот код позволит динамически загружать вложенные комментарии, что удобно для больших обсуждений.
Вывод
Иерархия комментариев — мощный инструмент для организации обсуждений в WordPress. Используя фильтры и хуки, можно ограничивать глубину вложенности, сортировать комментарии по своим правилам, кастомизировать их вывод и даже загружать динамически с помощью AJAX.
Для расширения возможностей стоит обратить внимание на плагины, такие как WPRemark, который добавит рейтинги и лайки, что позволит использовать сортировку по популярности.
Применяйте приведённые примеры кода в своих темах и плагинах, адаптируя под конкретные задачи и требования проекта.