WordPress как на ладони
Недорогой хостинг для сайтов на WordPress: wordpress.jino.ru

Перелинковка статей (предыдущие записи)

По мотивам одной из статей на сайте dimox.name «Отличный способ внутренней перелинковки статей (для WordPress)». Где я собственно уже писал в комментариях. Теперь решил написать у себя на блоге.

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

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

Для наглядности, предположим, что у нас на сайте 10 статей и мы выводим по 4 предыдущие ссылки. Теперь, когда мы зайдем на 10-ю статью, то на этой странице будут показаны ссылки на: 9,8,7,6 статьи. Если зайдем на 6-ю, то будут показаны ссылки на: 5,4,3,2 статьи. Теперь, "кольцевая перелинковка", когда зайдем на 3-ю статью будут показаны ссылки на: 2,1,10,9 статьи.

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

Ближе к делу

Предыдущие статьи для WordPress (в целом по сайту):

/** Предыдущие записи
------------------------------------------------------
$format ('') = {date:j.M.Y} - {a}{title}{/a} ({comments})
$post_num (5) = количество ссылок
$list_tag (li) = Тег списка
*/
function kama_previous_posts ($post_num=5, $format = '', $list_tag='li', $echo=true){
	global $post, $wpdb;
	$sql ="SELECT ID, post_title, post_date, comment_count, guid
	FROM $wpdb->posts p
	WHERE post_date < '$post->post_date'
		AND post_type = 'post' AND post_status = 'publish'
	ORDER BY post_date DESC LIMIT $post_num";
	$res = $wpdb->get_results($sql);
		$exclude = $post->ID;
		foreach ($res as $id) $exclude .= ','.$id->ID;
		$count_res = count($res);

	if ( !$res || $count_res<$post_num ){
		$post_num = $post_num-$count_res;
		$sql2 ="SELECT ID, post_title, post_date, comment_count, guid
		FROM $wpdb->posts p
		WHERE ID NOT IN ($exclude)
			AND post_type = 'post' AND post_status = 'publish'
		ORDER BY post_date DESC LIMIT $post_num";
		$res2 = $wpdb->get_results($sql2);
		$res = array_merge($res,$res2);
	}
	if (!$res) return false;
	preg_match ('!\{date:(.*?)\}!',$format,$date_m);
	foreach ($res as $pst){
		$x == 'li1' ? $x = 'li2' : $x = 'li1';
		$Title = $pst->post_title;
		$a1 = "<a href='". get_permalink($pst->ID) ."' title='{$Title}'>";
		$a2 = "</a>";

		if ($format){
			$date = apply_filters('the_time', mysql2date($date_m[1],$pst->post_date));
			$Sformat = str_replace ($date_m[0], $date, $format);
			$Sformat = str_replace('{title}', $Title, $Sformat);
			$Sformat = str_replace('{a}', $a1, $Sformat);
			$Sformat = str_replace('{/a}', $a2, $Sformat);
			$Sformat = str_replace('{comments}', $pst->comment_count, $Sformat);
		}
		else $Sformat = $a1.$Title.$a2;
		$out .= "\n<$list_tag class='$x'>{$Sformat}</$list_tag>";
	}
	if ($echo) echo $out;
	else return $out;
}

Копируем эту функцию в файл темы functions.php, а где нужно вывести предыдущие ссылки вызываем функцию так:

<ul>
	<?php kama_previous_posts (5); ?>
</ul>
//выведет 5 предыдущих ссылок.

Подобную функцию я писал в комментариях на dimox.name. Эта функция отличается тем, что тут можно легко настроить формат вывода. для этого используем теги:

  • {comments} - покажет колличество комментариев у статьи;

  • {title} - заголовок статьи;

  • {date:j.M.Y} - дата в формате j.M.Y (11.Апр.2010). Формат даты есно можно поменять smile

Так же, здесь я добавил классы li1 и li2 к тегу <li>, чтобы легко можно было раскрасить список в зебру. Еще, если указать третий параметр $list_tag, то можно изменить тег списка. К примеру:

<?php kama_previous_posts (6, '', 'div') ?>
// выведет не в li списке, а в div: <div class='li1'>Здесь ссылка</div>
Пример использования функции с указанием формата вывода:
<ul>
	<?php kama_previous_posts (6, '{date:j.M.Y} - {a}{title}{/a} (Комментариев: {comments})'); ?>
</ul>
//выведет в формате: <li class='li1'>17.Апр.2010 - <a href='http://ссылка на статью' title='заголовок статьи'>заголовок статьи</a> (Комментариев: 10)</li>

Обратите внимание

Эта функция выводит просто предыдущие статьи, а не предыдущие из категории в которой находится текущая статья. Чтобы выводить предыдущие из категории используйте эту функцию.

65 комментов
  • nike

    Вы код функции в файл темы functions.php вставили?
    Конечно вставил функцию, и всё отлично отображается,только без слова скачать, а вот когда пытаюсь добавить оба предложенных варианта, то выдаёт ошибку.

    Ответить13.Янв.2011 в 13:04 #
  • @ adem zaloguspeha.ru

    Спасибо большое! После некоторых колупаний получилось. smile Есть пара вопросов не по данной теме. Если позволите, то куда лучше задать? Спасибо.

    Ответить17.Янв.2011 в 19:45 #
    • Kama7643

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

      Ответить17.Янв.2011 в 23:23 #
      • @ adem zaloguspeha.ru

        Вроде не особо и глобально.
        Есть скрипт фотоконкурса http://wordpress.org/extend/plugins/wp-photocontest/ По описанию должен быть просто то, что надо, но в реалии то ли не доработан, то ли еще что, ну и не переведен конечно. Короче говоря, у меня не пошел, хотя и установился через загрузчик без проблем и в админку добавился, но в работе я его до ума довести не сумел. В интернете ничего путного по этой теме более не нашел. Мне кажется, было бы много благодарных читателей, я в первых рядах, которые с радостью бы приняли этот плагин себе на вооружение.
        И второе, более приземленное smile , как бы убрать эту злосчастную ссылку на Вордпресс, которая находится в правой колонке в блоке мета (честно говоря, отыскать ее в файлах блога просто не сумел), к тому же где-то читал, что если не сделать правильно, то блог вообще перестает работать.
        Спасибо!

        Ответить18.Янв.2011 в 13:58 #
        • @ adem zaloguspeha.ru

          Вот еще что обнаружилось. После установки плагина перелинковки начал сегодня добавлять сообщение и в админке на странице добавления выскакивает ошибка Warning: Cannot modify header information - headers already sent by (output started at /home/z/public_html/blog/wp-content/themes/jarrah/functions.php:1) in /home/zalogus6/public_html/blog/wp-includes/classes.php on line 1601
          Визуально не могу определить на что она влияет, но наблюдается такое предупреждение.

          Ответить18.Янв.2011 в 15:35 #
  • @ adem zaloguspeha.ru

    Ошибка скорее всего в размещении кода в файл functions.php.

    Читал ранее. Сейчас попытался убрать пробел и все улетело... пустой экран и ошибка Fatal error: Call to undefined function: add_action() in /home/z/public_html/blog/wp-includes/functions.php on line 18
    Гружу новый пустой файл functions.php и ничего не меняется - так и не аозвращается блог

    Ответить18.Янв.2011 в 18:45 #
    • @ adem zaloguspeha.ru

      Откатил все обратно. Подскажите пожалуйста как правильно вставить Ваш плагин в код.

      Ответить18.Янв.2011 в 18:56 #
    • Kama7643

      Вставьте код функции прям перед последней ?> и никаких ошибок быть не должно.

      Ответить19.Янв.2011 в 09:26 #
      • @ adem zaloguspeha.ru

        Добавил код непосредственно перед последним ? ... без пробелов и переносов. Та же самая ситуация получается. При создании сообщения, в момент автоматического сохранения черновика выскакивает эта ошибка прям в центре экрана.

        Warning: Cannot modify header information - headers already sent by (output started at /home/z/public_html/blog/wp-content/themes/jarrah/functions.php:1) in /home/z/public_html/blog/wp-includes/classes.php on line 1601

        Что характерно, и строки с таким номером нет, там максимум 290 что ли...

        Ответить19.Янв.2011 в 10:24 #
        • @ adem zaloguspeha.ru

          А скрипт работает. Где же, что же... Образец

          Ответить19.Янв.2011 в 10:31 #
          • @ adem zaloguspeha.ru

            Вот что получается... теперь при каждой операции выскакивает ошибка. Удалил из черновика записи и получил следующее:

            Warning: Cannot modify header information - headers already sent by (output started at /home/z/public_html/blog/wp-content/themes/jarrah/functions.php:1) in /home/z/public_html/blog/wp-includes/pluggable.php on line 890

            А вот и видимое... при комментировании записи получил вот:

            Warning: Cannot modify header information - headers already sent by (output started at /home/z/public_html/blog/wp-content/themes/jarrah/functions.php:1) in /home/z/public_html/blog/wp-includes/pluggable.php on line 890

            Елки-палки... а жаль-то как

            Ответить19.Янв.2011 в 10:41 #
        • Kama7643

          Похоже у вас в самом начале файла перенос строки потом <?php а потом уже начинаются все коды. Ошибка в первой строчке functions.php.
          Причем тут моя функция я чет понят не могу smile

          Ответить19.Янв.2011 в 14:10 #
          • @ adem zaloguspeha.ru

            Я же не виню Вашу функцию, а очень даже наоборот хочу ее установить smile

            Елки-палки, нет пробела в начале, прям от стеночки стартует. Может быть скинуть Вам файл?

            По фото что скажете? Не интересно и бесперспективно или есть смысл подождать?

            Ответить19.Янв.2011 в 18:44 #
          • Kama7643

            Киньте файл на tkama@bk.ru посмотрю, может че полезное увижу smile

            Ответить20.Янв.2011 в 22:37 #
  • @ Алексей

    Странные вещи творятся... Вставил код в function.php и вызов функции в single.php. Всё работает, ссылки есть. Но! Нифига не в том порядке!
    Так, например, если представить, что у нас 10 записей, и последней была опубликована 10-я, то открыв её мы видим ссылки (сверху вниз) на 1-ю, 6-ю, 5-ю, 4-ю, 3-ю... Если зайдём на 9-ю запись, то ссылки (сверху вниз) такие: 8, 7, 10, 1, 6... Если зайдём на 8-ю, то ссылки такие: 7, 10, 1, 6, 5. И так далее...
    А зайдя в первую запись видим такие ссылки: 6, 5, 4, 3, 2.
    Это глюк такой? Как его можно поправить?

    Ответить21.Мар.2011 в 22:49 #
  • @ Алексей

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

    Ответить22.Мар.2011 в 00:47 #
    • Kama7643

      Для данной функции категория не имеет никакого значения.

      Возможно у вас записи публиковались задним числом, поэтому такая ересь творится. Других объяснений я не вижу.

      Попробуйте изменить ORDER BY ID DESC на ORDER BY post_date DESC. В общем-то, так правильнее!

      Ответить26.Мар.2011 в 08:58 #
      • @ Алексей

        Да, вы правы. Была пара статей, которые я кинул в прошлое... smile

        Теперь по поводу правки. Попробовал заменить ORDER BY ID DESC на ORDER BY post_date DESC. Изменил код в двух местах. Помогло частично. С теми статьями, которые опубликованы в прошлое засада осталась. Возможно, это связано с тем, что в других местах вашего кода ID статей всё-таки используется в функциях... В связи с этим - вопрос: можно ли вообще отойти от ID, и что для этого нужно изменить в коде?
        Или проще поменять ID статей руками? И тогда - с помощью чего это можно сделать? Есть ли такой плагин?

        Ответить26.Мар.2011 в 14:21 #
        • Kama7643

          О, точно: условие WHERE ID < $post->ID опять на ID завязано smile
          Замените на WHERE post_date < $post->post_date.

          А вообще, если это не критично, то лучше оставить по ID, потому что выборка из БД быстрее происходит, чем по дате. Я поэтому изначально по ID сделал.

          П.С. ID для каждой статьи уникальный, его менять нельзя!

          Ответить26.Мар.2011 в 14:31 #
          • @ Алексей

            Заменил. Теперь на каждой статье показываются ссылки только на последние пять статей, независимо от того, какую статью мы читаем сейчас.
            А в коде ещё есть WHERE ID NOT IN ($exclude). Попробовал заменить и в ней ID на post_date - нифига не помогло... sad
            Больше ID нигде пока не нашёл... sad

            Ответить26.Мар.2011 в 15:18 #
          • Kama7643

            WHERE ID NOT IN ($exclude) - это не надо трогать - это правильно!

            Я направил вас по ложному следу, простите меня, грешного laugh . Дата ведь строковые данные поэтому надо в кавычки её:WHERE post_date < '$post->post_date'

            Ответить26.Мар.2011 в 16:47 #
  • @ Алексей

    Так вот оно чё, Михалыч... wink

    Ответить26.Мар.2011 в 17:49 #
  • @ Алексей

    Кавычки вставил, что не надо было трогать - исправил обратно, и .....

    Шайтанама! Всё работает как надо! smile

    Пасиб, Кама!

    Ответить26.Мар.2011 в 17:51 #
  • Dez dezflight-underground.com

    Большое спасибо! Как раз то, что искал.
    Установил за минуту. Всё работает отлично.

    Ответить06.Апр.2011 в 16:12 #
  • Нурлан domgood.ru

    Спасибо автору. Заработал сразу. Классная штука.

    Ответить22.Май.2011 в 15:45 #