WordPress как на ладони
WordPress темы и плагины за 250 рублей wordpress jino

wp_list_comments() WP 2.7.0

Выводит комментарии записей (постов, страниц). Функция может принимать ряд параметров и используется в шаблоне для вывода списка комментариев к посту/странице. Некоторые из параметров можно настроить в админ-панели.

Перед этой функцией должна быть вызвана функция comments_template(), которая получает комментарии для вывода из базы данных. Если этого не сделать, то нужно указать второй параметр $comments иначе функция не выведет ничего.

Хуки из функции:

Использование

<?php wp_list_comments( $args, $comments ); ?>

Шаблон использования

<ul class="commentlist">
	<?php
	$args = array(
		'walker'            => null,
		'max_depth'         => '',
		'style'             => 'ul',
		'callback'          => null,
		'end-callback'      => null,
		'type'              => 'all',
		'reply_text'        => 'Reply',
		'page'              => '',
		'per_page'          => '',
		'avatar_size'       => 32,
		'reverse_top_level' => null,
		'reverse_children'  => '',
		'format'            => 'html5', // или xhtml, если HTML5 не поддерживается темой
		'short_ping'        => false,    // С версии 3.6,
		'echo'              => true,     // true или false
	);

	wp_list_comments( $args ); 
	?>
</ul>
$args(строка/массив)
Массив аргументов, определяющий вывод комментариев.
По умолчанию: параметры по умолчанию
$comments(массив)
Массив полученный функцией get_comments().
По умолчанию: $wp_query->comments

Аргументы параметра $args

walker(объект)
Экземпляр класса, на основе которого собирается список комментариев.
По умолчанию: null (new Walker_Comment)
max_depth(число)
Глубина вложенности дочерних комментариев. Работает если включена поддержка древовидных комментариев. Параметр устанавливается в админ-панели.
По умолчанию: 5
style(строка)

В каком виде выводить список комментариев. Может быть div, ol или ul. Имейте ввиду, что сам список нужно оборачивать вручную:

<div class="commentlist">
 <?php wp_list_comments(array('style' => 'div')); ?>
</div>

или

<ol class="commentlist">
  <?php wp_list_comments(array('style' => 'ol')); ?>
</ol>

По умолчанию: 'ol'

callback(строка)
Название произвольной функции, которая будет использоваться для формирования вывода каждого комментария.
Указанная тут функция будет вызываться при выводе каждого комментария. Имейте ввиду, что ваша функция обратного вызова (callback) должна содержать открывающий тег <div> или <li> (в зависимости от параметра style), но этот тег не должен закрываться. WordPress впишет закрывающий тег автоматически. Можно использовать параметр end-callback, чтобы изменить его. Такое разделение нужно для древовидных комментариев, когда один коммент вложен в другой.
По умолчанию: нет
end-callback(строка)
Название произвольной функции, которая будет закрывать каждый комментарий. Указанная тут функция будет вызываться при закрытии каждого комментария. Она должна выводить закрывающий тег </div> или </li> в зависимости от параметра style. Callbackи end-callback разделены, для того чтобы правильно выводить древовидные комментарии.
По умолчанию: нет
type(строка)
Какой тип комментариев показывать. Может быть all, comment, trackback, pingback или pings. pings включает в себя 'trackback' и 'pingback'.
По умолчанию: all
per_page(число)

Количество комментариев на странице. Параметр устанавливается в админ-панели. Пишем 0, если нужно вывести все комментарии без разбивки на страницы.

Если нужно вывести все комментарии записи, то нужно указать число, а не 0 и желательно указать параметр page, чтобы он переписался: например: &per_page=9999&page=1.

Если page или per_page переданы и они не совпадают с тем что находится в $wp_query, то будет создан отдельный запрос на получение комментариев и результат будет разделен на страницы пагинации...

По умолчанию: 50

page(число)
Страница пагинации, комментарии которой нужно вывести.
avatar_size(число)
Размер аватара в пикселях.
По умолчанию: 32
reverse_top_level(логический)
Если поставить true (1), то самые последние комментарии будут наверху (обратная сортировка по дате). Влияет только на комментарии верхнего уровня (родительские, те у которых есть или могут быть дочерние комменты).
По умолчанию: false
reverse_children(логический)
Если поставить true, то самые последние комментарии будут наверху (обратная сортировка по дате). Влияет только на дочерние комментарии.
По умолчанию: false
reply_text(строка)
Текст, который нужно показать в ссылке "ответить". Текст используется в функции: get_comment_reply_link().
По умолчанию: 'reply'
login_text(строка)
Текст, который будет показан для не зарегистрированных пользователей, если комменты могут оставлять только зарегистрированные юзеры.
По умолчанию: 'Log in to Reply'
echo(логический)
Выводить код на экран или возвращать для обработки.
По умолчанию: 'true'

Примеры

#1 Использование по умолчанию

Выводит список комментариев. Используется в файле шаблона comments.php. Наличие древовидности и пагинации у комментариев контролируется через админ-панель Опции->Обсуждение.

<ol class="commentlist">
<?php wp_list_comments(); ?>
</ol>

#2 Вывод комментариев с использованием пользовательской функции

Для настройки внешнего вида каждого комментария, можно использовать параметр callback в который указать название функции, а затем создать эту функцию с нужным кодом (выводом):

<ul class="commentlist">
	  <?php wp_list_comments('type=comment&callback=mytheme_comment'); ?>
</ul>

Мы выводим список комментариев (type=comment), т.е. это не пинги, а так же используем свою функцию формирующую внешний вид комментария (callback=mytheme_comment). Функцию mytheme_comment нужно описывать отдельно, можно в файл functions.php или прям в том же файле, где находится этот код (обычно это comments.php).

<?php
function mytheme_comment($comment, $args, $depth) {
	if ( 'div' === $args['style'] ) {
		$tag       = 'div';
		$add_below = 'comment';
	} else {
		$tag       = 'li';
		$add_below = 'div-comment';
	}
	?>
	<<?php echo $tag; comment_class( empty( $args['has_children'] ) ? '' : 'parent' ); ?> id="comment-<?php comment_ID() ?>"><?php 
	if ( 'div' != $args['style'] ) { ?>
		<div id="div-comment-<?php comment_ID() ?>" class="comment-body"><?php
	} ?>
		<div class="comment-author vcard"><?php 
			if ( $args['avatar_size'] != 0 ) {
				echo get_avatar( $comment, $args['avatar_size'] ); 
			} 
			printf( __( '<cite class="fn">%s</cite> <span class="says">says:</span>' ), get_comment_author_link() ); ?>
		</div><?php 
		if ( $comment->comment_approved == '0' ) { ?>
			<em class="comment-awaiting-moderation"><?php _e( 'Your comment is awaiting moderation.' ); ?></em><br/><?php 
		} ?>
		<div class="comment-meta commentmetadata">
			<a href="<?php echo htmlspecialchars( get_comment_link( $comment->comment_ID ) ); ?>"><?php
				/* translators: 1: date, 2: time */
				printf( 
					__('%1$s at %2$s'), 
					get_comment_date(),  
					get_comment_time() 
				); ?>
			</a><?php 
			edit_comment_link( __( '(Edit)' ), '  ', '' ); ?>
		</div>

		<?php comment_text(); ?>

		<div class="reply"><?php 
				comment_reply_link( 
					array_merge( 
						$args, 
						array( 
							'add_below' => $add_below, 
							'depth'     => $depth, 
							'max_depth' => $args['max_depth'] 
						) 
					) 
				); ?>
		</div><?php 
	if ( 'div' != $args['style'] ) : ?>
		</div><?php 
	}
}

callback функция содержит только открывающий тег <li> и он не должен закрываться. Подробнее см. в описании параметра.

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

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

<ol class="commentlist">
	<?php
		// Получаем комментарии поста с ID XXX из базы данных 
		$comments = get_comments(array(
			'post_id' => XXX,
			'status' => 'approve' // комментарии прошедшие модерацию
		));

		// Формируем вывод списка полученных комментариев
		wp_list_comments(array(
			'per_page' => 10, // Пагинация комментариев - по 10 на страницу
			'reverse_top_level' => false // Показываем последние комментарии в начале
		), $comments);
	?>
</ol>

Код wp list comments: wp-includes/comment-template.php VER 4.9.6

<?php
function wp_list_comments( $args = array(), $comments = null ) {
	global $wp_query, $comment_alt, $comment_depth, $comment_thread_alt, $overridden_cpage, $in_comment_loop;

	$in_comment_loop = true;

	$comment_alt = $comment_thread_alt = 0;
	$comment_depth = 1;

	$defaults = array(
		'walker'            => null,
		'max_depth'         => '',
		'style'             => 'ul',
		'callback'          => null,
		'end-callback'      => null,
		'type'              => 'all',
		'page'              => '',
		'per_page'          => '',
		'avatar_size'       => 32,
		'reverse_top_level' => null,
		'reverse_children'  => '',
		'format'            => current_theme_supports( 'html5', 'comment-list' ) ? 'html5' : 'xhtml',
		'short_ping'        => false,
		'echo'              => true,
	);

	$r = wp_parse_args( $args, $defaults );

	/**
	 * Filters the arguments used in retrieving the comment list.
	 *
	 * @since 4.0.0
	 *
	 * @see wp_list_comments()
	 *
	 * @param array $r An array of arguments for displaying comments.
	 */
	$r = apply_filters( 'wp_list_comments_args', $r );

	// Figure out what comments we'll be looping through ($_comments)
	if ( null !== $comments ) {
		$comments = (array) $comments;
		if ( empty($comments) )
			return;
		if ( 'all' != $r['type'] ) {
			$comments_by_type = separate_comments($comments);
			if ( empty($comments_by_type[$r['type']]) )
				return;
			$_comments = $comments_by_type[$r['type']];
		} else {
			$_comments = $comments;
		}
	} else {
		/*
		 * If 'page' or 'per_page' has been passed, and does not match what's in $wp_query,
		 * perform a separate comment query and allow Walker_Comment to paginate.
		 */
		if ( $r['page'] || $r['per_page'] ) {
			$current_cpage = get_query_var( 'cpage' );
			if ( ! $current_cpage ) {
				$current_cpage = 'newest' === get_option( 'default_comments_page' ) ? 1 : $wp_query->max_num_comment_pages;
			}

			$current_per_page = get_query_var( 'comments_per_page' );
			if ( $r['page'] != $current_cpage || $r['per_page'] != $current_per_page ) {
				$comment_args = array(
					'post_id' => get_the_ID(),
					'orderby' => 'comment_date_gmt',
					'order' => 'ASC',
					'status' => 'approve',
				);

				if ( is_user_logged_in() ) {
					$comment_args['include_unapproved'] = get_current_user_id();
				} else {
					$commenter = wp_get_current_commenter();
					if ( $commenter['comment_author_email'] ) {
						$comment_args['include_unapproved'] = $commenter['comment_author_email'];
					}
				}

				$comments = get_comments( $comment_args );

				if ( 'all' != $r['type'] ) {
					$comments_by_type = separate_comments( $comments );
					if ( empty( $comments_by_type[ $r['type'] ] ) ) {
						return;
					}

					$_comments = $comments_by_type[ $r['type'] ];
				} else {
					$_comments = $comments;
				}
			}

		// Otherwise, fall back on the comments from `$wp_query->comments`.
		} else {
			if ( empty($wp_query->comments) )
				return;
			if ( 'all' != $r['type'] ) {
				if ( empty($wp_query->comments_by_type) )
					$wp_query->comments_by_type = separate_comments($wp_query->comments);
				if ( empty($wp_query->comments_by_type[$r['type']]) )
					return;
				$_comments = $wp_query->comments_by_type[$r['type']];
			} else {
				$_comments = $wp_query->comments;
			}

			if ( $wp_query->max_num_comment_pages ) {
				$default_comments_page = get_option( 'default_comments_page' );
				$cpage = get_query_var( 'cpage' );
				if ( 'newest' === $default_comments_page ) {
					$r['cpage'] = $cpage;

				/*
				 * When first page shows oldest comments, post permalink is the same as
				 * the comment permalink.
				 */
				} elseif ( $cpage == 1 ) {
					$r['cpage'] = '';
				} else {
					$r['cpage'] = $cpage;
				}

				$r['page'] = 0;
				$r['per_page'] = 0;
			}
		}
	}

	if ( '' === $r['per_page'] && get_option( 'page_comments' ) ) {
		$r['per_page'] = get_query_var('comments_per_page');
	}

	if ( empty($r['per_page']) ) {
		$r['per_page'] = 0;
		$r['page'] = 0;
	}

	if ( '' === $r['max_depth'] ) {
		if ( get_option('thread_comments') )
			$r['max_depth'] = get_option('thread_comments_depth');
		else
			$r['max_depth'] = -1;
	}

	if ( '' === $r['page'] ) {
		if ( empty($overridden_cpage) ) {
			$r['page'] = get_query_var('cpage');
		} else {
			$threaded = ( -1 != $r['max_depth'] );
			$r['page'] = ( 'newest' == get_option('default_comments_page') ) ? get_comment_pages_count($_comments, $r['per_page'], $threaded) : 1;
			set_query_var( 'cpage', $r['page'] );
		}
	}
	// Validation check
	$r['page'] = intval($r['page']);
	if ( 0 == $r['page'] && 0 != $r['per_page'] )
		$r['page'] = 1;

	if ( null === $r['reverse_top_level'] )
		$r['reverse_top_level'] = ( 'desc' == get_option('comment_order') );

	wp_queue_comments_for_comment_meta_lazyload( $_comments );

	if ( empty( $r['walker'] ) ) {
		$walker = new Walker_Comment;
	} else {
		$walker = $r['walker'];
	}

	$output = $walker->paged_walk( $_comments, $r['max_depth'], $r['page'], $r['per_page'], $r );

	$in_comment_loop = false;

	if ( $r['echo'] ) {
		echo $output;
	} else {
		return $output;
	}
}

Cвязанные функции

Из метки: Список (wp_list списки)

Еще из раздела: Комментарии

Еще из тегов шаблона: Комментарии

45 комментов
Полезные 5 Все
  • Nata

    Подскажите, пожалуйста, в каком файле править, чтобы в комментах отображалось вместо Reply - "Ответить", вместо says - "пишет" и т.п. Я совсем новичок, просмотрела comments.php и functions.php, но, наверное, не там ищу... unknw
    Спасибо.

    Ответить4.2 года назад #
    • Nata

      Упс, нашла )) Надо было смотреть comments-template.php.

      Ответить4.2 года назад #
  • Alex

    Пытался разобраться сам, но ничего не выходит sorry Суть такова, чтобы убрать из комментариев says, русифицировать "Reply" и во времени комментария заменить "at" на "в".

    В файлах шаблона этого нет, надо править файлы самого движка, что повлечет за собой правку этих файлах каждый раз после обновления sad

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

    Как я понял, за вывод комментариев отвечает код

    <?php wp_list_comments('type=comment'); ?>

    и нужно использовать пареметр callback, примерно так

    <?php wp_list_comments('type=comment&callback=custom_comments'); ?>

    С вызовом функции разобрался, а вот как ее правильно описать в файле functions.php никак понять не могу wacko Понял только то, что подмену можно произвести следующим образом:

    // убрать says
    <?php printf(__('<cite class="fn">%s</cite> <span class="says"></span>','custom_comments'), get_comment_author_link()); ?>
     // заменить at на в
    <?php printf(__('%1$s в %2$s', 'custom_comments'), get_comment_date(),  get_comment_time()) ?>
     //заменить reply на Ответить
    <?php $args=array( 'reply_text' => __('Ответить','custom_comments')); comment_reply_link( $args ); ?>

    Очень прошу помощи в решении этого не простого вопроса.

    Заранее большое спасибо

    Ответить4 года назад #
    • Kama5393

      Обновил описание. Перевел функцию в примере, там где был перевод, сделал все на русском. Попробуйте использовать её.

      А вообще, у вас локализация русская работает? Почему не переводится?

      1
      Ответить4 года назад #
      • Alex

        Пытался поставить облегченную версию перевода на сайт, но почему-то именно эти 3 параметра в комментариях не перевелись. И с датой публикации поста тоже проблема. Решил начать с комментариев.

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

        Так же хотел спросить, если указать формат даты и времени в комментариях в ручную, это снизит количество обращений в БД ?

        P.S. Отдельное спасибо за возможность указать аватарку комментатора по умолчанию good Раньше за это у меня отвечала отдельная функция.

        Ответить4 года назад #
        • Kama5393

          C reply решается так, в строке

          <?php comment_reply_link(array_merge( $args, array('depth' => $depth, 'max_depth' => $args['max_depth']))) ?>

          добавьте параметр "reply_text":

          <?php comment_reply_link( array_merge( $args, array('depth' => $depth, 'max_depth' => $args['max_depth'], 'reply_text' => 'Ответить')) ) ?>

          Описание смотрите: comment_reply_link()

          Насчет формата в ручную. Там он получается из настроек get_option('date_format'), они в память загружаются. Примерно с такой же скоростью получаются как переменные массива в PHP (я так понимаю). Нет смысла вручную указывать, прироста не будет совсем, не стоит возиться!

          Ответить4 года назад #
          • Alex

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

            Если задать формат времени вручную, то мы убираем 2 запроса в БД, которые запрашивают формат вывода даты и времени. Для небольших проектов это не принципиально, но когда трафик возрастает - может быть полезно.

            Ответить4 года назад #
            • Kama5393

              Это не так. Я раньше тоже так думал: http://wp-kama.ru/id_20/izbavlyaemsya-ot-lishnih-obrascheniy-k-dannyim.html

              Все это справедливо если выключить встроенных кэш WordPress. Но этого никогда не происходит. В данном случае никаких дополнительных запросов в БД не происходит. Данные берутся из памяти PHP (кэша) и даже не из файлового, равносильно обработке массива данных в PHP.

              В общем, выбросите эти мысли из головы.

              Ответить4 года назад #
              • Alex

                Спасибо, понял. Проверил по тестам, эффекта ноль. Буду оптимизировать другими методами.

                Еще раз большое спасибо за блог и помощь good

                Ответить4 года назад #
          • Alex

            Заметил такой нюанс, при клике на кнопку ответить, обновляется форма (ответ пользователю), но экран не спускается к полю ввода сообщения. Подскажите пожалуйста, как это правильно реализовать ? sorry

            И не могу понять, как перевести надпись "Click here to cancel reply".

            Заранее огромнейшее спасибо и низкий поклон.

            Ответить4 года назад #
  • Равиль

    Кама, помоги пжлста, что за плагин для комментариев на http://app4smart.com

    Ответить4 года назад #
  • Что-то в фукцнии обработки не нашел закрывающего li - это так предусмотрено?

    1
    Ответить3.7 года назад #
    • Kama5393

      В описании параметра есть этот момент:

      Имейте ввиду, что ваша функция обратного вызова (callback) должна содержать открывающий тег <div> или <li> (в зависимости от параметра style), но этот тег не должен закрываться. WordPress впишет закрывающий тег автоматически. Вы можете использовать параметр end-callback, чтобы изменить его. Такое разделение нужно для древовидных комментариев, когда один коммент вложен в другой.

      Ответить3.7 года назад #
  • Евгений cайт: blogozapis.ru

    Привет. Я редактирую в comment-template.php код в html5, а при изменении и сохранении она вообще не меняется и ничто не происходит. Что может быть, не подскажешь? Спасибо.

    Ответить3.4 года назад #
    • campusboy2796 cайт: www.youtube.com/c/wpplus

      Тут вариантов не много:
      1) Не тот файл отвечает за вывод комментариев
      2) Вы видите кеш страницы

      1
      Ответить3.4 года назад #
      • Евгений cайт: blogozapis.ru

        Спасибо, проблему решил good

        Ответить3.4 года назад #
  • Алексей

    Здравствуйте! Нужна помощь... Когда отправляешь комментарий с WordPress сайта, то появляется белое окно. Просто белое. Приходится идти назад, обновить страницу и только тогда появляется комментарий. Хотя должно быть: нажал отправить, страница перезагрузилась а не встала на месте... Когда из админки удаляешь комментарии, то же самое. Выделил, нажал удалить и сново белое окно. Снова нажимаешь стрелку назад, обновляешь вручную, тогда исчезают.

    Не подскажете в чем может быть проблема? Спасибо)

    Ответить2.5 года назад #
    • Kama5393

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

      Если это не из-за ошибки, нужно искать... Отключайте плагины, меняйте темы. Найдите из за чего так. Когда найдете, тогда нужно уже в коде смотреть все что связано с комментариями, где-то баг...

      1
      Ответить2.5 года назад #
  • Face2005

    Добрый день! а как в функции mytheme_comment($comment, $args, $depth) получить название статьи, к которой привязан комментарий?

    Ответить2 года назад #
    • stepan1187 cайт: www.weblancer.net/users/stepanko/?affili...

      В переменной

      $comment->comment_post_ID

      содержится ID статьи, к которой был оставлен коммент.
      Ну а дальше уже не составит труда получить Заголовок поста, зная его ID

      Ответить1.6 год назад #
  • @ Вячаслав

    2 Вывод комментариев с использованием пользовательской функции

    Привет!!! Возможно я уже плохо соображаю, который день "пилю" себе комментарии. У меня этот пример работает так: Если комментарий на модерации, он все ровно виден всем, и автору комментария и другим посетителям.
    Придумал вот так:

    <?php if ($comment->comment_approved == '0') {
    	   echo 'На модерации';
    	 } else {
    		comment_text();
    	 }
    	 ?>

    Это конечно прикольно =mosking) Но все же, чего не хватает, что бы пока комментарий на модерации был виден только его автору.? Это я у себя где-то намудрил?mosking

    • @ Вячаслав

      нашел проблему) Как правильно "Скрестить" get_comments и wp_list_comments? Мне get_comments нужен что бы вывести комменты с нужной меткой.

               $get_comments_arg = array(
      		   //'status' => 'approve', // тогда вообще никому ничего не видно
      		   'post_id' => 123,
      		   'meta_query' => array(
      				'relation' => 'OR',
      				array(
      					'key' => 'keykey',
      					'value' => 'valuevalue',
      				),
      				array(
      					'key' => 'key',
      					'value' => 'value'
      				 )
      			)
      		 );
      
      		 $wp_list_arg = array(
      		   'type' => 'comment',
      		   'callback' => 'mytheme_comment',
      		   'reverse_top_level' => false,
      		   'reverse_children'  => true
      		 );
      
      $get_comments_comm = get_comments($get_comments_arg);
      wp_list_comments($wp_list_arg, $get_comments_comm);

      Как это все записать, но только правильно? Так-то все работает как мне нужно, но комментарии на проверки видны всемmosking) laugh

  • Александр

    Спасибо

Здравствуйте, !     Войти . Зарегистрироваться