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

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

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

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

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

На эту мысль натолкнул один известный сайт, посвященный работе в 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() позволяет нам выводить цикл в том месте, где мы хотим. Если их не добавить, список будет выводиться просто вверху до загрузки всего остального контента.
к содержанию ↑

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

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

3 коментариев к записи

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

  • вот пробовал шорткодом вывести не получилось:

    function popular_post( $atts ) {
    ob_start();	
    
    	$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 );
     if ( $query->have_posts() ) { ?>
     
       <a href="" title="">
       
    
    ;
        <?php
            $myvariable = ob_get_clean();
            return $myvariable;
     }
    }
    add_shortcode('popular', 'popular_post');
    • Прошу прощения за долгую паузу. Ответил в тексте статьи. Посмотрите подзаголовок про вывод через шорткод.

Добавить комментарий