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

| Скачать исходники |

Шаг 1. Вступление

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

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

  • простую HTML разметку и CSS3, так что все можно будет легко настроить
  • jQuery для работы с Ajax
  • PHP и "зацепки" для обработки данных

Шаг 2. HTML разметка

Мы собираемся показать кнопку в форме сердечка в нижней части статьи. Чтобы сделать это, мы добавим следующую разметку в файл content-single.php (в теме Twenty Eleven):

<p class="post-like">
	<a data-post_id="POST_ID" href="#">
		<span class="qtip like" title="I like this article"></span>
	</a>
	<span class="count">POST_LIKES_COUNT</span>
</p>

Обратите внимание, что мы используем мета атрибуты HTML5 для хранения данных, так что работать с jQuery будет просто. Затем для этих целей будет использован код PHP, как мы увидим на следующем шаге.

Шаг 3. CSS3

Мы будем использовать CSS3 анимацию чтобы добавить некоторую визуальною интерактивность и sprites CSS чтобы уменьшить количество внешних изображений.

article footer  .post-like{
	margin-top:1em
}

article footer .like{
	background:url(images/icons.png) no-repeat;
	width: 15px;
	height: 16px;
	display: block;
	float:left;
	margin-right: 4px;
	-moz-transition: all 0.2s ease-out 0.1s;
	-webkit-transition: all 0.2s ease-out 0.1s;
	-o-transition: all 0.2s ease-out 0.1s
}

article footer .post-like a:hover .like{
	background-position:-16px 0;
}

article footer .voted .like, article footer .post-like.alreadyvoted{
	background-position:-32px 0;
}

На этом этапе должно получиться вот так:

Шаг4. jQuery

Мы будем использовать встроенный jQuery для обработки запросов ajax. По клику jQuery передаст некоторые параметры нашему php обработчику и обработает ответ для представления правильной информации.

Так что давайте создадим новый файл под названием post-like.js и добавим его в папку js. Затем откройте его и добавьте следующий код:

jQuery(document).ready(function() {

	jQuery(".post-like a").click(function(){

		heart = jQuery(this);

		// Retrieve post ID from data attribute
		post_id = heart.data("post_id");

		// Ajax call
		jQuery.ajax({
			type: "post",
			url: ajax_var.url,
			data: "action=post-like&nonce="+ajax_var.nonce+"&post_like=&post_id="+post_id,
			success: function(count){
				// If vote successful
				if(count != "already")
				{
					heart.addClass("voted");
					heart.siblings(".count").text(count);
				}
			}
		});

		return false;
	})
})

Объяснения

Для начала, давайте получим ID поста с помощью метода jQuery и затем передадим его нашему обработчику PHP. Переменная ajax_var создается динамически с помощью PHP (мы опишем это в следующем разделе).

Лучший способ использования ajax в WordPress — это делать запросы к admin-ajax.php. Он находится в папке wp-admin, и вы можете прикрепить ваши функции вызова к "зацепкам". Давайте посмотрим, как это работает.

Шаг 5. PHP и "зацепки"

Как мы будем действовать дальше? Мы собираемся привязать некоторые функции к функциям-зацепкам WordPress, а затем вызвать наш скрипт и добавить некоторые созданные PHP переменные JavaScript, которые будут использоваться jQuery.

Условия

Давайте откроем файл functions.php и начнем добавлять наши функции. Сначала нам нужно привязать функции к функциям WordPress. Так что добавьте эти две строки в ваш файл:

add_action('wp_ajax_nopriv_post-like', 'post_like');
add_action('wp_ajax_post-like', 'post_like');

Первое условие начинает действовать, когда пользователь авторизован, второе — когда не авторизован. Информацию о том, как  правильно внедрить ajax, можно найти здесь.

Вы видите часть зацепки "post-like", это параметр action, который мы использовали на предыдущем шаге.

Теперь мы включим в очередь наш скрипт и объявим наши переменные:

wp_enqueue_script('like_post', get_template_directory_uri().'/js/post-like.js', array('jquery'), '1.0', true );
wp_localize_script('like_post', 'ajax_var', array(
	'url' => admin_url('admin-ajax.php'),
	'nonce' => wp_create_nonce('ajax-nonce')
));

Здесь мы определили два важных параметра:

  • url: полный URI к расположению admin-ajax.php
  • nonce: хеш для предотвращения атак и ошибок

Вы можете использовать эти параметры в jQuery таким образом: ajax_var.url и ajax_var.nonce. Использование функций WordPress и admin-ajax.php – самый надежный способ работы с Ajax.

Функции

Давайте добавим функцию post_like function. Что выполнит эта функция?

  • проверит nonce;
  • получит ID поста, IP пользователя и метаданные поста;
  • проверит, голосовал ли уже пользователь;
  • сохранит данные (IP + количество голосов) для текущего поста;
  • вернет значение количества голосов jQuery.
function post_like()
{
	// Check for nonce security
	$nonce = $_POST['nonce'];

    if ( ! wp_verify_nonce( $nonce, 'ajax-nonce' ) )
        die ( 'Busted!');

	if(isset($_POST['post_like']))
	{
		// Retrieve user IP address
		$ip = $_SERVER['REMOTE_ADDR'];
		$post_id = $_POST['post_id'];

		// Get voters'IPs for the current post
		$meta_IP = get_post_meta($post_id, "voted_IP");
		$voted_IP = $meta_IP[0];

		if(!is_array($voted_IP))
			$voted_IP = array();

		// Get votes count for the current post
		$meta_count = get_post_meta($post_id, "votes_count", true);

		// Use has already voted ?
		if(!hasAlreadyVoted($post_id))
		{
			$voted_IP[$ip] = time();

			// Save IP and increase votes count
			update_post_meta($post_id, "voted_IP", $voted_IP);
			update_post_meta($post_id, "votes_count", ++$meta_count);

			// Display count (ie jQuery return value)
			echo $meta_count;
		}
		else
			echo "already";
	}
	exit;
}

Мы сохраняем IP пользователя и текущее время в одном post_meta и количество голосов в другом. Время поможет нам убедиться, может ли пользователь проголосовать через какое-то время.

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

Мы определим, как долго должен ждать пользователь, прежде чем проголосовать снова (в минутах):

$timebeforerevote = 120; // = 2 hours

Эта переменная может храниться в панели администратора темы, так что ее можно легко изменить.

Теперь добавьте следующий код, чтобы проверить, голосовал ли уже пользователь:

function hasAlreadyVoted($post_id)
{
	global $timebeforerevote;

	// Retrieve post votes IPs
	$meta_IP = get_post_meta($post_id, "voted_IP");
	$voted_IP = $meta_IP[0];

	if(!is_array($voted_IP))
		$voted_IP = array();

	// Retrieve current user IP
	$ip = $_SERVER['REMOTE_ADDR'];

	// If user has already voted
	if(in_array($ip, array_keys($voted_IP)))
	{
		$time = $voted_IP[$ip];
		$now = time();

		// Compare between current time and vote time
		if(round(($now - $time) / 60) > $timebeforerevote)
			return false;

		return true;
	}

	return false;
}

Здесь нет ничего сложного, мы просто проверяем, голосовал ли уже пользователь (то есть, есть ли его IP в списке голосовавших) , и можно ли ему голосовать снова (то есть, больше ли время, прошедшее с момента голосования, чем значение $timebeforerevote).

Шаг 6. Функция для генерации HTML разметки

Для того, чтобы у вас была возможность управлять тем, как отображаются голоса, и сделать обновление, если оно используется в разных файлах, — мы сделаем функцию, генерирующую разметку. Если пользователь уже проголосовал, мы не будем показывать сердечко как ссылку, чтобы избежать бессмысленных обращений к ajax.

function getPostLikeLink($post_id)
{
	$themename = "twentyeleven";

	$vote_count = get_post_meta($post_id, "votes_count", true);

	$output = '<p class="post-like">';
	if(hasAlreadyVoted($post_id))
		$output .= ' <span title="'.__('I like this article', $themename).'" class="like alreadyvoted"></span>';
	else
		$output .= '<a href="#" data-post_id="'.$post_id.'">
					<span  title="'.__('I like this article', $themename).'"class="qtip like"></span>
				</a>';
	$output .= '<span class="count">'.$vote_count.'</span></p>';

	return $output;
}

Вы можете заменить код, вставленный на Шаге 2 этой функцией:

<?php echo getPostLikeLink(get_the_ID());?>

Шаг 7. Идем дальше

Теперь, когда пользователи могут голосовать за посты, вам, возможно, захочется получить обратную связь. Например, вы можете отобразить топ 10 лучших постов.

Чтобы это сделать, мы можем использовать query_post со следующими параметрами:

query_posts('meta_key=votes_count&orderby=meta_value_num&order=DESC&posts_per_page=10');

Заключение

На этом все. Теперь вы можете отбирать лучшие посты по голосам и предпочтениям ваших читателей. Вы также можете применить свой стиль и дизайн с помощью CSS к блоку рейтинга. Это только лишь один из способов, как создать свою систему рейтинга записей, так что не забывайте комментировать и предлагать свои варианты.

Источник: WP.tutsplus.com

Вам понравился материал?

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

Такой e-mail уже зарегистрирован. Воспользуйтесь формой входа или введите другой.

Вы ввели некорректные логин или пароль

Извините, для комментирования необходимо войти.

9 комментариев

сначала новые
по рейтингу сначала новые по хронологии
Алексей

По моему в этой строке есть что-то лишнее:
data: "action=post-like&nonce="+ajax_var.nonce+"&post_like=&post_id="+post_id,
А именно &post_like=
Я прав?)

Бектур

а не можете дополнить функцию времени, то есть рейтинг за неделю или за месяц и т.п ???

firefly_can_fly

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

а как сделать еще кнопочку "не нравится" и уменьшать счетчик?

Извините, но мы не консультируем по кастомным настройкам.

Ннихера не роботает.

Статья очень кстати, на днях попробую внедрить ваш метод на одном из сайтов. Хочу попробовать сделать рейтинг сайтов на Wordpress. Не подскажите, как можно добавить на сайт вывод данных о PR и Alexe сайта (Каждый пост это отдельный сайт). Т.е чтоб под каждым постом на главной выводился PR и alexa сайта, урл которого был добавлен в посте.
Как то так :)

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