WordPress как на ладони
Недорогой хостинг для сайтов на WordPress: wordpress.jino.ru

Функция для вывода последних комментариев

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

# Получим последние комментарии списком

Этот код получает последние 10 комментариев в виде списка UL. Где текст комментария укорочен до 50 символов и является ссылкой на сам комментарий:

$args = array(
	'number'  => 10,
	'orderby' => 'comment_date',
	'order'   => 'DESC',
	'status'  => 'approve',
	'type'    => 'comment', // только комментарии, без пингов и т.д...
);

if( $comments = get_comments( $args ) ){
	echo '<ul>';
	foreach( $comments as $comment ){
		$comm_link = get_comment_link( $comment->comment_ID ); // может быть тяжелый запрос ...
		$comm_short_txt = mb_substr( strip_tags( $comment->comment_content ), 0, 50 ) .'...';

		echo '<li>'. $comment->comment_author .': <a rel="nofollow" href="'. $comm_link .'">'. $comm_short_txt .'</a></li>';
	}
	echo '</ul>';
}

/*
Данные в объекте $comment
stdClass Object
(
	[comment_ID] => 9727
	[comment_post_ID] => 477
	[comment_author] => Andrew
	[comment_author_email] => mail@gmail.com
	[comment_author_url] => 
	[comment_author_IP] => 178.45.177.200
	[comment_date] => 2015-22-01 00:27:04
	[comment_date_gmt] => 2015-22-28 21:27:04
	[comment_content] => текст коммента
	[comment_karma] => 0
	[comment_approved] => 1
	[comment_agent] => Mozilla/5.0 (Windows NT 6.1; WOW64; rv:36.0) Gecko/20100101 Firefox/36.0
	[comment_type] => 
	[comment_parent] => 9724
	[user_id] => 313
)
*/

Измените этот код под себя. Если по каким-то причинам такой вариант не подходит, то все что ниже как раз для вас.

Специальная функция для вывода последних комментариев

Чтобы вывести последние комментарии я пользуюсь своей функцией, которая расположена ниже. Её нужно поместить в файл functions.php вашей темы.

/**
 * Функция для вывода последних комментариев в WordPress. 
 * ver: 0.1
 */
function kama_recent_comments( $args = array() ){
	global $wpdb;

	$def = array(
		'limit'      => 10, // сколько комментов выводить.
		'ex'         => 45, // n символов. Обрезка текста комментария.
		'term'       => '', // id категорий/меток. Включить(5,12,35) или исключить(-5,-12,-35) категории. По дефолту - из всех категорий.
		'gravatar'   => '', // Размер иконки в px. Показывать иконку gravatar. '' - не показывать.
		'user'       => '', // id юзеров. Включить(5,12,35) или исключить(-5,-12,-35) комменты юзеров. По дефолту - все юзеры.
		'echo'       => 1,  // выводить на экран (1) или возвращать (0).
		'comm_type'  => '', // название типа комментария
		'meta_query' => '', // WP_Meta_Query
		'meta_key'   => '', // WP_Meta_Query
		'meta_value' => '', // WP_Meta_Query
		'url_patt'   => '', // оптимизация ссылки на коммент. Пр: '%s?comments#comment-%d' плейсхолдеры будут заменены на $post->guid и $comment->comment_ID
	);

	$args = wp_parse_args( $args, $def );
	extract( $args );

	$AND = '';

	// ЗАПИСИ
	if( $term ){
		$cats = explode(',', $term );
		$cats = array_map('intval', $cats );

		$CAT_IN = ( $cats[ key($cats) ] > 0 ); // из категорий или нет

		$cats = array_map('absint', $cats ); // уберем минусы
		$AND_term_id = 'AND term_id IN ('. implode(',', $cats) .')';

		$posts_sql = "SELECT object_id FROM $wpdb->term_relationships rel LEFT JOIN $wpdb->term_taxonomy tax ON (rel.term_taxonomy_id = tax.term_taxonomy_id) WHERE 1 $AND_term_id ";

		$AND .= ' AND comment_post_ID '. ($CAT_IN ? 'IN' : 'NOT IN') .' ('. $posts_sql .')';
	}

	// ЮЗЕРЫ
	if( $user ){
		$users = explode(',', $user );
		$users = array_map('intval', $users );

		$USER_IN = ( $users[ key($users) ] > 0 );

		$users = array_map('absint', $users );

		$AND .= ' AND user_id '. ($USER_IN ? 'IN' : 'NOT IN') .' ('. implode(',', $users) .')';
	}

	// WP_Meta_Query
	$META_JOIN = '';
	if( $meta_query || $meta_key || $meta_value ){
		$mq = new WP_Meta_Query( $args );
		$mq->parse_query_vars( $args );
		if( $mq->queries ){
			$mq_sql = $mq->get_sql('comment', $wpdb->comments, 'comment_ID' );
			$META_JOIN = $mq_sql['join'];
			$AND .= $mq_sql['where'];
		}
	}

	$sql = $wpdb->prepare("SELECT * FROM $wpdb->comments LEFT JOIN $wpdb->posts ON (ID = comment_post_ID ) $META_JOIN
	WHERE comment_approved = '1' AND comment_type = %s $AND ORDER BY comment_date_gmt DESC LIMIT %d", $comm_type, $limit );

	//die( $sql );  
	$results = $wpdb->get_results( $sql );

	if( ! $results ) return 'Комментариев нет.';

	// HTML
	$out = $grava = '';
	foreach ( $results as $comm ){
		if( $gravatar )
			$grava = get_avatar( $comm->comment_author_email, $gravatar );

		$comtext = strip_tags( $comm->comment_content );
		$com_url = $url_patt ? sprintf( $url_patt, $comm->guid, $comm->comment_ID ) : get_comment_link( $comm->comment_ID );

		$leight = (int) mb_strlen( $comtext );
		if( $leight > $ex )
			$comtext = mb_substr( $comtext, 0, $ex ) .' …';

		$out .= '
		<li>
			'. $grava .' <b>'. strip_tags( $comm->comment_author ) .':</b> 
			<a href="'. $com_url .'" title="к записи: '. esc_attr( $comm->post_title ) .'">'. $comtext .'</a>
		</li>';
	}

	if( $echo )
		return print $out;
	return $out;
}

Примеры использования

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

<ul>
	<?php kama_recent_comments("limit=10&ex=40"); ?>
</ul>

10 - это количество комментариев, которые будут показаны, а 40 - сколько символов из текста комментария будет выведено. Символы считаются после того, как из текста были вырезаны все HTML теги, чтобы сохранить равную длину текстов.

#2 Комментарии для постов из заданных рубрик/меток

Также в функции можно включать/исключать комменты к записям из указанных рубрик/меток/произвольных таксономий. ЗА это отвечает параметр term, указывать нужно id рубрик (увидеть их можно в админке в разделе "рубрики"). Для исключение перед id ставится "-":

<ul>
	<?php kama_recent_comments("limit=10&ex=40&term=5,10,34"); ?>
</ul>

Выведет 10 комментариев, с длинной текста до 40 символов, для постов из рубрик 5,10,34. Чтобы исключить эти рубрики нужно будет вызвать функцию так:

<ul>
	<?php kama_recent_comments("limit=10&ex=40&term=-5,-10,-34"); ?>
</ul>

Выведет 10 комментариев, с длинной текста до 40 символов, для всех постов, кроме постов из рубрик 5,10,34.

Одновременно включать и исключать рубрики нельзя! Впрочем, это лишено здравого смысла smile

#3 Возвращаем результат

Если нужно возвратить результат для дальнейшей обработки в php, а не выводить на экран, то параметр echo ставим в 0:

<?php kama_recent_comments('echo=0'); ?>

#4 Аватарки

Если нужно включить показ аватарок из сервиса gravatar, то указываем параметр gravatar как размер необходимой аватарки. Например, 20 - активирует показ аватарок и выведет аву шириной и высотой в 20px.

<ul>
	<?php kama_recent_comments('gravatar=20'); ?>
<ul>

1 6 2015
Полностью переписал функцию... Доп параметры и т.д.

9 ноября 2010
Добавил аватарки от сервиса gravatar.com в вывод функции.

13 июня 2010
Обновил код функции, до этого к тексту комментария добавлялось троеточие, даже если текст был короче чем выводимая длина. Теперь, если комментарий короче заданной длинны, то троеточие не добавляется.

21 августа 2010
По просьбе Анатолия v, добавил возможность выводить комментарии для постов из определенных рубрик (включать рубрики) или исключать комментарии к постам из определенных рубрик (исключать рубрики)

Функция для вывода последних комментариев из текущей категории

Эта старая функция, если работает то используйте, если не работает, то пользуйтесь функцией выше - kama_recent_comments().

/**
 * Функция для вывода последних комментариев из текущей категории.
 * 
 * Автор: Kama
 * ver: 0.1
 * 
 * Как работает:
 * в рубрике, выводит комменты из текущей и дочерних рубрик
 * в посте, выводит комменты из рубрик к которым принадлежит пост, работает если пост из нескольких рубриках
 * в постах дочерние рубрики рубрик поста не учитываются
 * Пример: echo kama_recent_comments_from_current_cat(10, 45, $gravatar='');
 */
function kama_recent_comments_from_current_cat( $limit=10, $ex=45, $gravatar=0 ){
	global $post, $cat, $wpdb;

	$limit = (int) $limit;
	$ex    = (int) $ex;

	// для дочерних рубрик
	if( $cat && $child_terms = get_categories( array('child_of' => $cat) ) )
		foreach( $child_terms as $term )
			$cat .= ','. $term->term_id;

	// для постов
	if( !$cat && is_singular() && $terms = get_the_category( $post->ID ) )
		foreach( $terms as $term )
			$cat .= $term->term_id . ',';

	$cat = rtrim($cat, ',');

	$JOIN = $AND = '';
	if( $cat ){
		$IN   = (strpos($cat,'-')===false) ? "IN ($cat)" : "NOT IN (". str_replace('-', '', $cat) .")";
		$JOIN = "LEFT JOIN $wpdb->term_relationships rel ON (p.ID = rel.object_id) LEFT JOIN $wpdb->term_taxonomy tax ON (rel.term_taxonomy_id = tax.term_taxonomy_id)";
		$AND  = "AND tax.taxonomy = 'category' AND tax.term_id $IN";
	}

	$sql = "SELECT * FROM $wpdb->comments com
	LEFT JOIN $wpdb->posts p ON (com.comment_post_ID = p.ID) $JOIN
	WHERE comment_approved = '1' AND comment_type = '' $AND
	ORDER BY comment_date_gmt DESC LIMIT $limit"; 

	$results = $wpdb->get_results( $sql );

	$out = $grava = '';
	foreach( $results as $comm ){
		if( $gravatar )
			$grava = get_avatar( $comm->comment_author_email, $gravatar );

		$comtext = strip_tags( $comm->comment_content );
		$leight = (int) mb_strlen( $comtext );
		if( $leight > $ex )
			$comtext = mb_strlen( $comtext, 0, $ex, 'UTF-8' ) .' …';

		$out .= '
		<li>
			'. $grava .'<b>'. strip_tags($comm->comment_author) .':</b> 
			<a href="'. get_comment_link($comm->comment_ID) .'" title="к записи: '. esc_attr($comm->post_title) .'">'. $comtext .'</a>
		</li>';
	}

	return $out;
}
192 коммента
Полезные 8 Вопросы 2 Все
  • Dimox dimox.name

    Я пользуюсь вот такой функцией - http://dumpz.org/19025/ - это из какого-то плагина.

    Хотел бы узнать, есть ли особая разница с твоей функцией?

    Ответить29.Апр.2010 в 22:06 #
    • Kama7644

      Нет, особой разницы нет. Тоже самое smile Разница только в том, что там обрезка комментария делается прям в MySQL, я средствами ПХП. Там вроде как логичнее, только в теории у меня вроде длинна обрезанных кусков должна быть одинаковее, потому что сперва теги вырезаются (если они есть).

      Ответить30.Апр.2010 в 10:00 #
    • Валерий strateg.org

      Kama

      Спасибо за функцию, все работает, только вот с многостраничными комментариями возникают проблемы, а точнее с формированием ссылки на комментарии, которые располагаются на 2-й и далее страницах.

      Чтобы было понятно о чем речь, загляните ко мне и попробуйте перейти по ссылке на комментарий: "Lee-s: @Валерий Чугреев Можно, а нужно ли? Думаю как таковой необх …" (не сочтите за рекламу, просто так понятнее).

      Чтобы перейти на этот комментарий нужно пролистывать страницу.

      Ответить04.Дек.2010 в 12:06 #
      • Kama7644

        34-ю строку поменяйте на:

        $out .= "\n<li>$gravatar<b>".strip_tags($comment->comment_author). ": </b>" . "<a href='". get_comment_link($comment->comment_post_ID) ." title='к записи: {$comment->post_title}'>{$comtext}</a></li>";

        У меня на этом блоге, кстати тоже такой "глюк", вроде жизнь не портит. Не нравится мне функция get_comment_link() crazy

        П.С. обновил функцию.

        Ответить04.Дек.2010 в 16:49 #
  • Error2003 error2003.org.ua

    Спасибо за решение!

    Ответить10.Май.2010 в 15:02 #
  • Никита www.victoryinvestors.com

    Огромное спасибо Kama и Dimox

    Ответить13.Май.2010 в 18:44 #
  • overbag overbag.ru

    большое спасибо за этот код!!! у меня на блоге была такая проблема, что при обрезке комментария иногда выскакивал в конце символ неправильной кодировки. заменил тот код на этот, и всё просто замечательно работает!

    Ответить09.Июл.2010 в 22:14 #
  • Дима webguruz.ru

    спасибо отлично работает, подцепилась без проблем

    Ответить10.Июл.2010 в 15:55 #
  • Анатолий blogav.ru

    У вас тут как я понял, просто вывод всех комментов, а скажите пожалуйста, как можно настроить вывод комментов из определенной рубрики? Очень надо...
    Заранее большое спасибо за ответ.

    Ответить18.Авг.2010 в 13:40 #
    • Kama7644

      Обновил функцию и пост, теперь можно исключать и включать рубрики. Вам нужно будет обновить код и вызвать функцию так:

      <ul>
      	 <?php kama_recent_comments(10, 40, '5'); ?>
      </ul>

      Здесь, 10 - количество комменнтов, 40 - длинна текста, 5 - id рубрики для постов которой будут показаны комментарии.

      Ответить21.Авг.2010 в 11:28 #
  • Василий videouroki.su

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

    kama_recent_comments2

    а в остальных местах вызывается

    kama_recent_comments

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

    Ответить08.Сен.2010 в 00:17 #
  • wlad2 wlad2.ru

    как удалить автора? то-есть что-бы на комменты автора ссылка не давалась!

    Ответить14.Окт.2010 в 20:11 #
    • Kama7644

      Если вы имели ввиду, как убрать ссылку на сам комментарий, меняйте строку 31

      ```php:firstline[31]
      $out .= "\n<li><b>".strip_tags($comment->comment_author). ": </b>" . "<a href='".get_permalink($comment->comment_post_ID)."#comment-{$comment->comment_ID}' title='к записи: {$comment->post_title}'>{$comtext}</a></li>";

      на такую:
      
      ```php:firstline[31]
      $out .= "\n<li><b>". strip_tags($comment->comment_author) . "</b>: $comtext</li>";
      Ответить14.Окт.2010 в 22:17 #
      • wlad2 wlad2.ru

        не, что-бы на комменты админа блога ссылка не давалась!
        извиняюсь не так выразился.

        Ответить15.Окт.2010 в 08:00 #
        • Kama7644

          Где? На какие комменты админа? Я не понимаю, что вам нужно! Вы как-то получше сформулируйте вопрос smile

          Ответить15.Окт.2010 в 20:58 #
          • wlad2 wlad2.ru

            вот я беру и вешаю эту функцию на свой блог, только хочу что-бы из всех комментариев которые выведутся

            <?php kama_recent_comments(10, 40); ?>

            удалить админа, то-есть меня на моем блоге.
            Все комментарии кроме администратора сайта, меня!

            Ответить15.Окт.2010 в 21:59 #
          • Kama7644

            Теперь ясно. А то вы все про ссылку какую-то говорили smile

            после стр. 20 добавьте такую строчку
            AND comment_author <> 'ник'
            будет так:

            ```sql:firstline[20]
            AND comment_type = '' $AND
            AND comment_author <> 'ник'

            
            Вместо ник ваш ник естественно.
            Ответить15.Окт.2010 в 23:38 #
            • Андрей

              А как тогда правильно будет, у Вас в коде
              AND comment_type = '' {$and}

              Ответить20.Фев.2012 в 17:28 #
              • Виталий mojwp.ru

                Можно сделать через email исключение автора блога.

                AND comment_author_email <> 'site@gmail.com'
                Ответить18.Апр.2014 в 09:43 #
  • eavasi www.eavasi.ru

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

    Ответить09.Ноя.2010 в 11:33 #
    • Kama7644

      Дополнил функцию - добавил параметр $gravatar, значение которого, отличное от нуля (по умолчанию) активирует показ аватарок и станет размером выводимой аватарки (например, $gravatar=20 - выведет иконку шириной и высотой в 20px).

      Ответить09.Ноя.2010 в 12:06 #
      • eavasi www.eavasi.ru

        Спасибо, Тимур!

        Ответить09.Ноя.2010 в 12:38 #
      • eavasi.ru www.eavasi.ru
        Fatal error: Call to undefined function: iconv_strlen() in /home2/eavasiru/public_html/eavasi/wp-content/themes/idream/functions.php on line 258

        Такая ошибка возникает у меня при установке этой функции.

        Ответить09.Ноя.2010 в 17:27 #
        • Kama7644

          Видимо у вас php старый. Измените функцию в коде iconv_strlen на просто strlen и, возможно, нужно будет еще поменять iconv_substr на substr. Ничего страшного в такой замене нет.

          Ответить09.Ноя.2010 в 17:47 #
          • eavasi.ru www.eavasi.ru

            ок, попробуем.
            А php у меня №5
            Спасибо.

            Ответить09.Ноя.2010 в 18:37 #
  • Ольга

    Вставила код, подправила стили под мой сайт, все работает великолепно. За одним маааленьким, но досадным исключением: проблема с отображением gravatar-ов. Они выводятся там где нужно, но размером 1х1px. Видно, как точки появляются и исчезают, если включать\выключать показ. Как с этим справиться? В самом коде функции не меняла ни символа.

    Ответить10.Дек.2010 в 18:12 #
    • Kama7644

      Не знаю в чем проблема может быть, все должно работать! unknw Может сервис глючил, когда вы тестировали, нет?

      Была небольшая ошибка в коде, но с ней аватарки должны были выводиться! Благодаря вашему комменту заметил и поправил. Было: если в последнем параметре указать, например 30, то должен был активироваться показ аватаров размером в 30 пикселей, но на деле показ только активировался и размер не задавался и выводился полный размер.

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

      Ответить10.Дек.2010 в 23:15 #
      • Ольга

        Попробовала еще раз, с тем же результатом. Но потом решила проверить на другом хостинге (платном) - все замечательно вывелось. Так что, видимо, проблема именно в этом. Я сижу на бесплатном RedZ и уже не первый раз замечаю, что какие-то фишки просто отказываются там работать, возможно, дело в каких-то их админских настройках.
        Попробовала способ, описанный Гудвином, с использованием плагина Get Recent Comments, - сработало. Придется довольствоваться этим, но на остальных проектах заменю вывод комментариев на Вашу функцию, она намного легче и "изящней", что ли smile Не люблю кучи плагинов.

        Ответить11.Дек.2010 в 15:40 #