Вывод последних комментариев в блоге
-
Здравствуйте форумчане. Подскажите пожалуйста, почему может не корректно работать следующий код:
function get_avatar_recent_comment() { $comment_len = 80; $comments = get_comments('number=10'); if ($comments) { foreach ($comments as $comment) { //ob_start(); ?> <li> <img class="alignleft" src="/img/comment.png" /> <?php echo strip_tags($comment->comment_author); ?>:<br /> <a href="<?php echo get_permalink($comment->ID); ?>#comment-<?php echo $comment->comment_ID; ?>" title="Запись: <?php echo $comment->post_title; ?>"> <?php echo strip_tags(mb_substr(apply_filters('get_comment_text', $comment->comment_content), 0, $comment_len)); ?>... </a> </li> <?php //ob_end_flush(); } } else { echo "<li>No comments</li>"; } }
Обнаружено 2 проблемы:
1. Коментарии выводит правильно, а вот при переходе по неу — открывает не тот пост
2. Не выводит в тайтл заголовок новости.И наверное надо правильно убрать
"<li>No comments</li>"
Использовать буду на проекте, в котором уже есть комментарии, а следовательно это сообщение никогда уже не выведется.
Очень надеюсь на вашу помощь. Спасибо.
-
Вы не правильно используете функцию
get_permalink()
. Ей необходимо передать ID записи, а вы передаете атрибут ID комментария, который кстати не существует. То же самое касается атрибута post_title. Попробуйте так:<?php $post = get_post( $comment->comment_post_ID ); ?> <a href="<?php echo get_permalink( $post->ID ); ?>#comment-<?php echo $comment->comment_ID; ?>" title="Запись: <?php echo esc_attr( $post->post_title ); ?>">
Успехов!
Заработало. Спасибо большое !!! Одно обидно, что эта функция добавляет 3 запроса в БД ((( Никак нельзя ее оптимизировать ? Или может быть кто-то подскажет более оптимизированный вариант ?
Избавился от связки if-else, возможно кому-нибудь пригодится. Вот мой код:
function get_avatar_recent_comment() { $comment_len = 80; $comments = get_comments('number=10'); foreach ($comments as $comment) { ?> <li> <img class="alignleft" src="/img/comment.png" /> <?php echo strip_tags($comment->comment_author); ?>:<br /> <?php $post = get_post( $comment->comment_post_ID ); ?> <a href="<?php echo get_permalink( $post->ID ); ?>#comment-<?php echo $comment->comment_ID; ?>" title="Запись: <?php echo esc_attr( $post->post_title ); ?>"> <?php echo strip_tags(mb_substr(apply_filters('get_comment_text', $comment->comment_content), 0, $comment_len)); ?>...</a> </li> <?php } }
Если у кого-то есть предложения по улучшению — буду только рад.
Покажите запросы?
Вот эти 3 запроса:
[10] => Array ( [0] => SELECT * FROM wp_comments WHERE ( comment_approved = '0' OR comment_approved = '1' ) ORDER BY comment_date_gmt DESC LIMIT 4 [1] => 0.00012612342834473 [2] => require('wp-blog-header.php'), require_once('wp-includes/template-loader.php'), include('/themes/ny/index.php'), get_sidebar, locate_template, load_template, require_once('/themes/ny/sidebar.php'), last_comment, get_comments, WP_Comment_Query->query ) [11] => Array ( [0] => SELECT * FROM wp_posts WHERE ID = 2203 LIMIT 1 [1] => 0.00010108947753906 [2] => require('wp-blog-header.php'), require_once('wp-includes/template-loader.php'), include('/themes/ny/index.php'), get_sidebar, locate_template, load_template, require_once('/themes/ny/sidebar.php'), last_comment, get_post, WP_Post::get_instance ) [12] => Array ( [0] => SELECT t.*, tt.* FROM wp_terms AS t INNER JOIN wp_term_taxonomy AS tt ON tt.term_id = t.term_id INNER JOIN wp_term_relationships AS tr ON tr.term_taxonomy_id = tt.term_taxonomy_id WHERE tt.taxonomy IN ('category') AND tr.object_id IN (2203) ORDER BY t.name ASC [1] => 7.8916549682617E-5 [2] => require('wp-blog-header.php'), require_once('wp-includes/template-loader.php'), include('/themes/ny/index.php'), get_sidebar, locate_template, load_template, require_once('/themes/ny/sidebar.php'), last_comment, get_permalink, get_the_category, get_the_terms, wp_get_object_terms )
Второго и третьего запроса не будет при внешнем кэшировании объектов. Вообще я не уверен, что они идут именно от
get_post()
, хотя если у вас например пермалинки /категория/название то вполне оправдано, т.к. вы используетеget_permalink()
.Если комментариев в цикле будет больше к разным записям, то у вас наверняка появится еще по 2 запроса на каждую из них.
Как вариант можно пройтись по всем выводимым комментариям до вывода и собрать comment_post_ID в один массив, затем выполнить new WP_Query с параметром post__in, и отключит поиск и кэширование мета-данных (но оставить термины если они используются в чпу) для данного запроса. При таком подходе у вас будет всего 3 запроса в WP_Query() а get_post() будет уже из объектного кэша все необходимые данные брать.
Еще как вариант обернуть эту функцию в транзитный кэш без срока жизни и сбрасывать его при публикации или изменении комментариев.
Ради теста удалили строчку
<?php $post = get_post( $comment->comment_post_ID ); ?>
сразу же минус 2 запроса.
Да, ссылки идет вида категория/пост.
Сейчас вывожу 4 комментария из 2-х постов. Количество запросов 23.
Ради теста вывел 10 комментариев из 5 постов, запросов стало 29[10] => Array ( [0] => SELECT * FROM wp_comments WHERE ( comment_approved = '0' OR comment_approved = '1' ) ORDER BY comment_date_gmt DESC LIMIT 10 [1] => 0.00011205673217773 [2] => require('wp-blog-header.php'), require_once('wp-includes/template-loader.php'), include('/themes/ny/index.php'), get_sidebar, locate_template, load_template, require_once('/themes/ny/sidebar.php'), last_comment, get_comments, WP_Comment_Query->query ) [11] => Array ( [0] => SELECT * FROM wp_posts WHERE ID = 2203 LIMIT 1 [1] => 9.5129013061523E-5 [2] => require('wp-blog-header.php'), require_once('wp-includes/template-loader.php'), include('/themes/ny/index.php'), get_sidebar, locate_template, load_template, require_once('/themes/ny/sidebar.php'), last_comment, get_post, WP_Post::get_instance ) [12] => Array ( [0] => SELECT t.*, tt.* FROM wp_terms AS t INNER JOIN wp_term_taxonomy AS tt ON tt.term_id = t.term_id INNER JOIN wp_term_relationships AS tr ON tr.term_taxonomy_id = tt.term_taxonomy_id WHERE tt.taxonomy IN ('category') AND tr.object_id IN (2203) ORDER BY t.name ASC [1] => 7.2002410888672E-5 [2] => require('wp-blog-header.php'), require_once('wp-includes/template-loader.php'), include('/themes/ny/index.php'), get_sidebar, locate_template, load_template, require_once('/themes/ny/sidebar.php'), last_comment, get_permalink, get_the_category, get_the_terms, wp_get_object_terms ) [13] => Array ( [0] => SELECT * FROM wp_posts WHERE ID = 393 LIMIT 1 [1] => 8.4877014160156E-5 [2] => require('wp-blog-header.php'), require_once('wp-includes/template-loader.php'), include('/themes/ny/index.php'), get_sidebar, locate_template, load_template, require_once('/themes/ny/sidebar.php'), last_comment, get_post, WP_Post::get_instance ) [14] => Array ( [0] => SELECT t.*, tt.* FROM wp_terms AS t INNER JOIN wp_term_taxonomy AS tt ON tt.term_id = t.term_id INNER JOIN wp_term_relationships AS tr ON tr.term_taxonomy_id = tt.term_taxonomy_id WHERE tt.taxonomy IN ('category') AND tr.object_id IN (393) ORDER BY t.name ASC [1] => 6.9856643676758E-5 [2] => require('wp-blog-header.php'), require_once('wp-includes/template-loader.php'), include('/themes/ny/index.php'), get_sidebar, locate_template, load_template, require_once('/themes/ny/sidebar.php'), last_comment, get_permalink, get_the_category, get_the_terms, wp_get_object_terms ) [15] => Array ( [0] => SELECT * FROM wp_posts WHERE ID = 830 LIMIT 1 [1] => 0.00012922286987305 [2] => require('wp-blog-header.php'), require_once('wp-includes/template-loader.php'), include('/themes/ny/index.php'), get_sidebar, locate_template, load_template, require_once('/themes/ny/sidebar.php'), last_comment, get_post, WP_Post::get_instance ) [16] => Array ( [0] => SELECT t.*, tt.* FROM wp_terms AS t INNER JOIN wp_term_taxonomy AS tt ON tt.term_id = t.term_id INNER JOIN wp_term_relationships AS tr ON tr.term_taxonomy_id = tt.term_taxonomy_id WHERE tt.taxonomy IN ('category') AND tr.object_id IN (830) ORDER BY t.name ASC [1] => 7.2002410888672E-5 [2] => require('wp-blog-header.php'), require_once('wp-includes/template-loader.php'), include('/themes/ny/index.php'), get_sidebar, locate_template, load_template, require_once('/themes/ny/sidebar.php'), last_comment, get_permalink, get_the_category, get_the_terms, wp_get_object_terms ) [17] => Array ( [0] => SELECT * FROM wp_posts WHERE ID = 6103 LIMIT 1 [1] => 0.00010204315185547 [2] => require('wp-blog-header.php'), require_once('wp-includes/template-loader.php'), include('/themes/ny/index.php'), get_sidebar, locate_template, load_template, require_once('/themes/ny/sidebar.php'), last_comment, get_post, WP_Post::get_instance ) [18] => Array ( [0] => SELECT t.*, tt.* FROM wp_terms AS t INNER JOIN wp_term_taxonomy AS tt ON tt.term_id = t.term_id INNER JOIN wp_term_relationships AS tr ON tr.term_taxonomy_id = tt.term_taxonomy_id WHERE tt.taxonomy IN ('category') AND tr.object_id IN (6103) ORDER BY t.name ASC [1] => 6.8902969360352E-5 [2] => require('wp-blog-header.php'), require_once('wp-includes/template-loader.php'), include('/themes/ny/index.php'), get_sidebar, locate_template, load_template, require_once('/themes/ny/sidebar.php'), last_comment, get_permalink, get_the_category, get_the_terms, wp_get_object_terms )
Как вариант можно пройтись по всем выводимым комментариям до вывода и собрать comment_post_ID в один массив, затем выполнить new WP_Query с параметром post__in, и отключит поиск и кэширование мета-данных (но оставить термины если они используются в чпу) для данного запроса. При таком подходе у вас будет всего 3 запроса в WP_Query() а get_post() будет уже из объектного кэша все необходимые данные брать.
Это как то очень сложно для моего восприятия ))) Если честно, то даже не особо понял, как это работает, не говоря уже про реализацию (с программированием на Вы и шепотом)
Еще как вариант обернуть эту функцию в транзитный кэш без срока жизни и сбрасывать его при публикации или изменении комментариев.
А вот это уже интереснее. Только понятия не имею, как это реализовать правильно (((
Я бы предложил пару модификаций:
- Вместо
get_permalink()
и ручного добавления#comment-
можно воспользоваться функцией get_comment_link(), которая корректно работает и в том случае, если комментарии разбиты на несколько страниц. - Вместо
mb_substr()
иstrip_tags()
можно воспользоваться функцией wp_trim_words() (которая также вырезает теги), чтобы текст не обрезался на полуслове.
function get_avatar_recent_comment() { $comment_words = 10; $comments = get_comments( 'number=10' ); foreach ( $comments as $comment ) { ?> <li> <img class="alignleft" src="/img/comment.png" /> <?php echo strip_tags( $comment->comment_author ); ?>:<br /> <a href="<?php echo get_comment_link( $comment ); ?>" title="Запись: <?php echo get_the_title( $comment->comment_post_ID ); ?>"> <?php echo wp_trim_words( get_comment_text( $comment ), $comment_words ); ?> </a> </li> <?php } }
Sergey Biryukov, спасибо большое. Протестировал, все работает.
Подскажите пожалуйста, как можно сделать, чтобы ограничивалась длина выводимого комментария по словам, уложившимся в определенные символы. Грубо говоря, пусть это будет 55 символов.
Сейчас в примере стоит ограничение на 10 слов, но если слова будут длинные (электрификация и т.п.), то смотрится не очень симпатично.
P.S. В голове родилась еще идея, чтобы в не зависимости от того, показывается полные комментарий или только его часть, чтобы он всегда заканчивался многоточием, а если он заканчивается на знаки препинания или смайлы, то они терлись при выводе. Таким образом есть шанс повысить ПФ для поисковиков за счет внутренних кликов, т.к. пользователь будет думать, что это только часть коммента и при клике он увидит продолжение. Все это обернуть в транзитный кэш и вот он готовый сео инструмент. Возможно кто-нибудь возьмется за реализацию такого …
Второй день надоедаю гуглу по поводу своей «чудо» доработки вывода и оптимизации последних комментариев, толку ноль ((( Очень надеюсь на помощь сообщества, т.к. решение на мой взгляд интересное и полезное.
Ограничение длины по количеству слов мне кажется не лучшее решение, если ты заботишься в внешнем виде сайта. Один напишет «спасибо», другой забьет все 10 слов и т.д. Если в блок выводить 10 последних комментариев, то такой разброс в количестве символов будет бросаться в глаза.
как можно сделать, чтобы ограничивалась длина выводимого комментария по словам, уложившимся в определенные символы. Грубо говоря, пусть это будет 55 символов.
Хороший вопрос. Тоже интересно.
P.S. В голове родилась еще идея, чтобы в не зависимости от того, показывается полные комментарий или только его часть, чтобы он всегда заканчивался многоточием, а если он заканчивается на знаки препинания или смайлы, то они терлись при выводе. Таким образом есть шанс повысить ПФ для поисковиков за счет внутренних кликов, т.к. пользователь будет думать, что это только часть коммента и при клике он увидит продолжение. Все это обернуть в транзитный кэш и вот он готовый сео инструмент.
Не уверен, что такой способ повысит какие-нибудь факторы, но аналогов такого не встречал. Будет интересно протестировать, с чем черт не шутит 🙂
Всем добра.
Гуру !!! Хелп !!! По каким-то причинам в сайтбар выводятся не одобренные комментарии. Как это исправить ???
- Вместо
- Тема «Вывод последних комментариев в блоге» закрыта для новых ответов.