Отличный способ внутренней перелинковки статей (для WordPress)

Отличный способ внутренней перелинковки статей (для WordPress) Евгений Самборский в своей статье «Как добиться хорошей индексации статей» рассказал про занятный способ внутренней перелинковки статей сайта.

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

Процитирую Женю:

Под текстом каждой статьи на своих и клиентских сайтах я делаю список из 5-ти ранее опубликованных статей из рубрики. Замечу, что многие делают подобные списки, но зачастую в них ссылки на последние статьи. Я же линкую именно предыдущие, грубо говоря если у текущей статьи ID = 10, то в списке предыдущих будут статьи с ID 9,8,7,6,5. Каждая статья получает минимум 4 вечных внутренних ссылки.

Естественно, после прочтения статьи я загорелся желанием реализовать такую полезную штуку на WordPress’е. И, естественно, я ее сделал.

Более того, по подсказке Дэна я пошел еще дальше, чем задумывал первоначально — сделал кольцевую перелинковку. Для наглядности пример — в рубрике есть 10 статей, и в списке мы выводим 5 статей. При заходе в 3-ю статью, список «Предыдущие из рубрики» будет содержать ссылки на статьи 2, 1, 10, 9, 8.

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

«Давай уже, Димокс, не томи, выкладывай код на стол!» (голос из зала =).

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

<?php
$li = 5; // сколько ссылок показывать в списке
$postID = $post->ID;
$postDate1 = get_the_time('YmdHis','','',false);
$cat = get_the_category(); $cat = $cat[0]; $cat = $cat->cat_ID;
$catQuery = new WP_Query('showposts=-1&cat='.$cat);
$i = 0;
if ($catQuery->have_posts() && $catQuery->post_count > 1) :
?>
<ul>
<?php
 while ($catQuery->have_posts()) : $catQuery->the_post();
 $postDate2 = get_the_time('YmdHis','','',false);
 if ($postDate2 < $postDate1 && $post->ID != $postID) {
 $i++;
 if ($i <= $li) {
?>
 <li><a href="<?php the_permalink() ?>" rel="bookmark"><?php the_title(); ?></a></li>
<?php
 }
 }
 endwhile;
?>
<?php
 $posts = $li - $i;
 $cat_count = get_category($cat)->category_count;
?>
<?php
 if (($cat_count - 1) > $i) {
 if ($posts > 0) {
 $temp_query = $wp_query;
 if (($cat_count - 1) < $li) $posts = $cat_count - 1 - $i;
 query_posts('showposts='.$posts.'&cat='.$cat);
 if (have_posts()) : while (have_posts()) : the_post();
?>
 <li><a href="<?php the_permalink() ?>" rel="bookmark"><?php the_title(); ?></a></li>
<?php
 endwhile; endif;
 $wp_query = $temp_query;
 }
 }
?>
</ul>
<?php endif; wp_reset_query(); ?>

Код необходимо запихнуть в файл single.php. Если вы не разбираетесь в шаблонах WordPress, то лучше вообще ничего не трогать.

Шаблон ссылки встречается в этом коде 2 раза (обратите на это внимание) и имеет следующий вид:

<li><a href="<?php the_permalink() ?>" rel="bookmark"><?php the_title(); ?></a></li>

В этом шаблоне можно использовать все те же php-теги, которые используются в стандартном WordPress-цикле.

Код проверялся только на WordPress 2.8.4, поэтому работу в других версия я не гарантирую.

Живой пример вы можете увидеть непосредственно на данном блоге во вкладке «Предыдущие из рубрики», которая находится под каждой статьей.

P.S. Кстати, по аналогии можно сделать внутреннюю перелинковку статей и для блога в целом, а не только в пределах рубрик.

Update 29.11.09

В комментариях подсказали более правильный вариант кода для вывода списка (спасибо пользователю Kama!), который, по сравнению с моим вариантом, берет из БД только те посты, которые появятся в списке (в моем варианте сначала считываются ВСЕ записи текущей рубрики, и только потом происходит выборка).

<?php
function show_previous_posts_from_category ($the_post_id, $the_category_id = 0, $post_num) {

	$num = 0;
	global $wpdb;

	$sql = "SELECT wposts.*
	FROM $wpdb->posts wposts
	LEFT JOIN $wpdb->term_relationships ON (wposts.ID = $wpdb->term_relationships.object_id)
	LEFT JOIN $wpdb->term_taxonomy ON ($wpdb->term_relationships.term_taxonomy_id = $wpdb->term_taxonomy.term_taxonomy_id)
	WHERE $wpdb->term_taxonomy.taxonomy = 'category'
	AND $wpdb->term_taxonomy.term_id = '$the_category_id'
	AND wposts.post_status = 'publish'
	AND wposts.post_type = 'post'
	AND wposts.ID < '$the_post_id'
	ORDER BY wposts.ID DESC
	LIMIT $post_num";

	$result = $wpdb->get_results($sql, OBJECT);
	global $post;
?>
<ul>
<?php
	foreach ($result as $post) {
		setup_postdata($post);
?>
	<li><a href="<?php the_permalink() ?>" rel="bookmark"><?php the_title(); ?></a></li>
<?php
		$num++;
		$save_ids[] = $post->ID;
	}
	if ( $num < $post_num || !$result ) {
		$need_more = $post_num-$num;
		$save_ids[] = $the_post_id;
		$save_ids = join (',', $save_ids);
		$more_posts = get_posts("numberposts=$need_more&category=$the_category_id&exclude=$save_ids");
		foreach ($more_posts as $post){
			setup_postdata($post);
?>
	<li><a href="<?php the_permalink() ?>" rel="bookmark"><?php the_title(); ?></a></li>
<?php
		}
	}
?>
</ul>
<?php } ?>

<?php
	$the_cat = get_the_category();
	$the_cat_id = $the_cat[0]->cat_ID;
	show_previous_posts_from_category($post->ID, $the_cat_id, 5);
	wp_reset_query();
?>

Количество ссылок указывается в самой последней строке кода. Шаблон ссылки также находится в двух местах.

* * *

Система обмена cсылками нового поколения LinkToLink.ru — бесплатное продвижение сайтов, дополнительный заработок без комиссий.

Полезные комментарии (1)
Комментарии (156)
  1. 1

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

  2. 2
    Евгений

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

  3. 3
    Alexandr

    chrome не дает использовать код «ERR_BLOCKED_BY_XSS_AUDITOR»

  1. 1
    Дмитрий

    Решил проблему исключением из запроса индексов для таблицы wp_posts
    заменил строку:
    FROM $wpdb->posts wposts
    на
    FROM $wpdb->posts wposts IGNORE INDEX (PRIMARY,type_status_id_date)
    костыль конечно, но помог, снизил время выполнения запроса с 5 секунд до 0.5
    актуально для сайтов с большим количеством постов, у моего в проблемной рубрике уже более 70000 постов, отсюда такая нагрузка.

Ваш комментарий