Вывод действительно популярных записей на Wordpress без плагина

43875

Один из популярных способов улучшения поведенческих факторов – использование блока “Популярные записи”. Он позволяет привлечь внимание к самому интересному и повысить глубину просмотра сайта. В общем, это очень хорошо для продвижения сайта.

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

Теория популярности

Обычно для реализации задачи, разработчики прибегают к простому алгоритму: выводят публикации по количеству просмотров или комментариев. Больше просмотров/комментариев – больше популярность. Кажется, всё логично.

Но на мой взгляд, используя такой алгоритм ранжирования, мы допускаем небольшую ошибку. Дело в том, что в этом случае мы не учитываем фактор времени. Это значит, что публикация, размещенная на сайте год назад, скорее всего будет иметь больше просмотров или комментариев, чем размещённая вчера. Даже если новая объективно лучше и интереснее, чем более старая. Таким образом, старые публикации, по стечению обстоятельств, навсегда пропишутся в блоке “Популярные записи”.

На эту мысль натолкнул один известный сайт, посвященный работе в Photoshop. Так, в блоке “Популярные”, выводятся уроки, которые качественно хуже, чем более новые. Но, из-за их более раннего появления, имеют больше просмотров. Список популярных записей не меняется вот уже более полутора лет. Нужно ли это и вам?

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

Создаем алгоритм популярности

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

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

Индекс популярности = Просмотры / Дни существования

Разберемся. Исходя из формулы, пост “A”, который существует 100 дней, и имеет 100 просмотров, будет менее популярен, чем более новый пост “B”, но за 1 день, собравший 10 просмотров. Это логично, ведь теоретически, пост “B” за те же 100 дней наберет значительно больше просмотров, чем его конкурент.

Однако, и эта формула не учитывает еще один момент. 100 дней назад посещаемость сайта могла быть всего лишь 1 человек в день, а в момент публикации поста “B” – 100 человек в день. Давайте введем еще один фактор ранжирования. Это показатель комментирования. Логично, ведь если публикацию обсуждают, значит она интересна. Наша формула будет выглядеть следующим образом:

Индекс популярности = Комментарии + Просмотры / Дни существования

Итак, в нашем алгоритме будут учитываться следующие факторы:

  1. количество просмотров записи
  2. количество дней существования публикации
  3. количество комментариев

Теперь, определившись с формулой, приступим к реализации вывода записей по созданному индексу популярности.

Вывод записей

Создадим заготовку, которая послужит отправной точкой. Выводим 5 записей. Разместите следующий код там, где хотите вывести посты.

<div id="popular_posts">
	<ul>
	<?php $query = new WP_Query('posts_per_page=5'); while ($query->have_posts()) : $query->the_post(); ?>
		<li>
			<a href="<?php the_permalink(); ?>" title="<?php the_title(); ?>"><?php the_post_thumbnail(array()); ?>
			<p><?php the_title(); ?></p></a>
		</li>
	<?php endwhile; ?>
	</ul>
</div>

Теперь можно его красиво оформит. Этот код нужно разместить в файл style.css вашей темы.

#popular_posts ul {
	margin-left:10px;
}
#popular_posts ul li{
	display:block;
	border-bottom:1px solid #f1f1f1;
	padding:15px 0px 20px 0px;
	height:50px;
	font-size:13px;
} 
#popular_posts ul li img {
	width: 50px;
	height: 50px;
	float: left;
	margin: 0 13px 0 0px;
	background: #fff;
	border: 2px solid #f1f1f1;
	border-radius: 50%;
}
#popular_posts ul li p {
	margin-top:10px;
}

Рассчитываем индекс популярности

Количество просмотров страницы

Чтобы его рассчитать, сначала внедрим на сайт подсчет количества просмотров страниц. Разместите в function.php:

function setPostViews($postID) {
	$count_key = 'views';
	$count = get_post_meta( $postID, $count_key, true );
	if( $count == '' ){
		$count = 0;
		delete_post_meta($postID, $count_key);
		add_post_meta( $postID, $count_key, '0' );
	} else {
		$count++;
		update_post_meta( $postID, $count_key, $count );
	}
}
function getPostViews($postID){
	$count_key = 'views';
	$count = get_post_meta( $postID, $count_key, true );
	if($count==''){
		delete_post_meta( $postID, $count_key );
		add_post_meta( $postID,	$count_key,	'0' );
		return	"0";
	}
	return	$count;
}

Обязательно считаем каждое посещение страницы. Его нужно разместить в файл одиночной записи, обычно это single.php

<?php setPostViews(get_the_ID()); ?>

На всякий случай, если нужно вдруг вывести во фронтэнде:

<span class="views" title="Просмотры">Просмотры: 
	<?php echo getPostViews((int)get_the_ID()); ?>
</span>

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

Считаем количество дней существования поста

// получаем дату публикации поста в секундах начиная с 1 января 1970 года
$dtNow = get_post_time('U', true, $postid);
// получаем текущее время
$dtTime = current_time('U');
// считаем разницу в днях
$diff = $dtTime - $dtNow;
$days = $diff/86400;

Считаем количество комментариев

comments_number( '0', '1', '%' );

Итак, мы определили, как будем получать данные каждой записи для подсчета индекса популярности.

Выводим записи по популярности

Есть один важный момент. Если мы станем пересчитывать индекс популярности всякий раз, когда кто-то заходит на сайт, это создаст довольно высокую нагрузку. Сайт может работать медленнее. Чтобы не создавать лишней нагрузки, давайте запланируем задачу, которая позволит нам производить пересчет один раз в сутки. Воспользуемся планировщиком wp_schedule_event(). Разместите код ниже в файл function.php:

// добавляем запланированный хук
add_action('wp', 'my_activation');
function my_activation() {
	if( ! wp_next_scheduled( 'my_daily_event' ) ) {
		wp_schedule_event( time(), 'daily', 'my_daily_event');
	}
}

// добавляем функцию к указанному хуку
function do_this_daily() {
 	global $wpdb;
	$postids = $wpdb->get_results("SELECT ID FROM $wpdb->posts WHERE post_status='publish' AND post_type='post' ORDER BY ID ASC");
	
	foreach( $postids as $postid ){
		$postid = $postid->ID; // ID записи
	
		// считаем количество просмотров
		$views = (int)get_post_meta( $postid, 'views', true );
		// считаем дни существования поста
		//$dtNow = get_the_time('U'); $dtTime = current_time('U'); $diff = $dtTime - $dtNow;
		$dtNow = get_post_time('U', true, $postid); $dtTime = current_time('U'); $diff = $dtTime - $dtNow;
		
		// считаем комментарии и сумму просмотров с комментариями
		$comments = get_comments_number( $postid );
		$summa = $views + $comments;
		// считаем индекс популярности
		if ( $days = '0' ){
			$pop_index = $summa / 1;
		} else {
			$days = (int)$diff/86400;
			$pop_index = $summa / $days;
		}
		$pop = round($pop_index, 2);
		// записываем индекс популярности в произвольное поле поста
		update_post_meta( $postid, 'popularity', $pop );
	}
}
add_action('my_daily_event', 'do_this_daily', 10, 2);

Теперь сам вывод постов.

<div id="popular_posts">
	<ul>
	<?php 
	$args = array(
		'meta_query'     => array(
			'meta_value_num' => array(
				'key'	=> 'popularity'
			),
		),
		'orderby'            => 'meta_value_num',
		'posts_per_page'     => 5,
		'post_status'        => 'publish',
		'order'              => 'DESC'
	);
	$query = new WP_Query( $args );
	while ($query->have_posts()) : $query->the_post(); ?>
		<li>
			<a href="<?php the_permalink(); ?>" title="<?php the_title(); ?>"><?php the_post_thumbnail(array()); ?>
			<p><?php the_title(); ?></p></a>
		</li>
	<?php endwhile; ?>
	</ul>
</div>

Вывод через шорткод

Для удобства, давайте попробуем выводить записи через шорткод [ popular-posts ] (не забудьте убрать пробелы).

function popular_posts() {

ob_start(); ?>

<div id="popular_posts">
	<ul>
	<?php 
	$args = array(
		'meta_query'     => array(
			'meta_value_num' => array(
				'key'	=> 'popularity'
			),
		),
		'orderby'            => 'meta_value_num',
		'posts_per_page'     => 5,
		'post_status'        => 'publish',
		'order'              => 'DESC'
	);
	$query = new WP_Query( $args );
	while ($query->have_posts()) : $query->the_post(); ?>
		<li>
			<a href="<?php the_permalink(); ?>" title="<?php the_title(); ?>">
				<?php the_post_thumbnail(array()); ?>
				<p><?php the_title(); ?></p>
			</a>
		</li>
	<?php endwhile; ?>
	</ul>
</div>
    <?php
        $myvariable = ob_get_clean();
        return $myvariable;
 
}
add_shortcode( 'popular-posts', 'popular_posts' );

Параметры ob_start() и ob_get_clean() позволяет нам выводить цикл в том месте, где мы хотим. Если их не добавить, список будет выводиться просто вверху до загрузки всего остального контента.

Вместо итогов

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

5 comments to post “"Вывод действительно популярных записей на WordPress без плагина"
  • Ян Александров
    Влад14 Aug 2017 16:25

    Спасибо за скрипт. Вопрос новичка. Каким образом вывести шорткодом последний запрос на вывод поста?

    Reply
    • Ян Александров
      Yan AlexandrovAuthor16 Aug 2017 20:12

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

      Reply
  • Ян Александров
    Алекс1 Jun 2022 16:41

    Код подсчета количества просмотров не считает.. на странице не выводятся просмотры..

    Reply
  • Ян Александров
    legos7 Sep 2022 11:09

    Ошибка в условии:
    if ( $days = ‘0’ )
    нужно:
    if ( $diff == 0 )

    Reply
  • Ян Александров
    legos7 Sep 2022 11:11

    if ( $days = ‘0’ )
    if ( $diff == 0 )

    Reply
Leave a Reply

B I PHP JS

Made with by CodyShop