WordPress как на ладони
Наставник Трепачёв Д.П., phphtml.net wordpress jino

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

Альтернатива этой функции находится по этой ссылке, в ней можно указать таксономию и тип записи, для которых будет происходить перелинковка.

Это продолжение поста о перелинковке статей.

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

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

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

  1. Можно задавать формат вывода, благодаря чему её очень просто внедрить в любой шаблон;

  2. Для этой функции не нужно заранее определять текущую категорию (функция сама определит её), т.е. меньше лишнего кода в шаблоне и проще новичкам.

  3. Функция не использует тяжелую функцию самого WordPress get_posts()

  4. К каждому тегу ссылки добавляется классы li1 и li2, чтобы легко можно было раскрасить список в зебру.

  5. Можно включить кэширование. Подробнее об этом ниже.

  6. Список сортируется по дате, а не по ID, т.е. если запись была опубликована задним числом она будет выводится как нужно.

Использование функции

А вот, собственно, и код, который нужно поместить в ваш файл шаблона functions.php.

/** Предыдущие записи из рубрики (относительно текущей записи) + кольцевая перелинковка
----------------------------------------------------------------------------------------
Параметры передаваемые функции. В скобках указано дефолтное значение.
post_num (5) = количество ссылок
format ('') = {date:j.M.Y} - {a}{title}{/a} ({comments})
cache ('') = включить кэш (по умолчанию выключен). Пишем 1, чтобы включить
list_tag (li) = Тег списка.
echo (true) = Выводить на экран или возвращать для обработки (false)
*/
function kama_previous_posts_from_cat ($post_num=5, $format = '', $cache = '', $list_tag='li', $echo=true){
	global $post, $wpdb;

	$cache_key = (string) md5( __FUNCTION__ . $post->ID );
	$cache_flag = __FUNCTION__;

	if ( $cache && $cache_out = wp_cache_get($cache_key, $cache_flag) ){
		if ($echo) return print($cache_out);
		else return $cache_out;
	}

	$cat = get_the_category($post->ID);
	$cat_id = (int) $cat[0]->term_id;

	$same_join = "SELECT ID, post_title, post_date, comment_count, guid
	FROM $wpdb->posts p
		LEFT JOIN $wpdb->term_relationships rel ON (p.ID = rel.object_id)
		LEFT JOIN $wpdb->term_taxonomy tax ON (rel.term_taxonomy_id = tax.term_taxonomy_id)";
	$same_and = "AND tax.term_id = '$cat_id'
		AND tax.taxonomy = 'category' AND p.post_status = 'publish' AND p.post_type = 'post'";
	// пробуем получить предыдущие записи
	$sql = "$same_join
	WHERE p.ID < {$post->ID}
		$same_and
	ORDER BY p.post_date DESC
	LIMIT $post_num";
	$res = $wpdb->get_results($sql);

	$count_res = count($res);

	// если количество меньше нужного, делаем 2-й запрос
	if ( !$res || $count_res<$post_num ){
		$exclude = $post->ID;
		if ($res) foreach ($res as $id) $exclude .= ','.$id->ID;
		$post_num = (int) $post_num-$count_res;
		$sql = "$same_join
		WHERE p.ID NOT IN ($exclude)
			AND p.ID != {$post->ID}
			$same_and
		ORDER BY p.post_date DESC
		LIMIT $post_num";
		$res2 = $wpdb->get_results($sql);

		$res = array_merge($res,$res2);
	}
	if (!$res)
		return false;

	if ($format)
		preg_match ('!{date:(.*?)}!',$format,$date_m);

	$out = $x = '';
	foreach ($res as $pst){
		$x = ($x == 'li1') ? 'li2' : '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==0)?'':$pst->comment_count), $Sformat);
		}
		else
			$Sformat = $a1.$Title.$a2;

		$out .= "\n<$list_tag class='$x'>{$Sformat}</$list_tag>";
	}

	if ($cache) wp_cache_add($cache_key, $out, $cache_flag);

	if ($echo)
		return print $out;

	return $out;
}

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

<ul>
<?php kama_previous_posts_from_cat (5);  ?>
</ul>
// 5 это количество выводимых ссылок

Вот, собственно, и все, что нужно сделать для простого использования функции.

Важно! Вызов будет работать корректно только в файле темы, отвечающем за вывод постов (обычно это single.php).

Расширенное использование

Для настройки формата вывода используйте:
  • {comments} - покажет количество комментариев у статьи;
  • {title} - заголовок статьи;
  • {date:j.M.Y} - дата в формате j.M.Y (11.Апр.2010);
  • {a} и {/a} - тег ссылки. Открывается и закрывается.

Вызов будет таким:

<ul>
<?php kama_previous_posts_from_cat (5, '{a}{title}{/a} ? {date:j.M.Y} // {comments}');  ?>
</ul>
// выведет список в формате - <li class='li1'><a href='http://ссылка' title='Заголовок статьи'>Заголовок статьи</a> ? дата // количество комментариев</li>
Использование кэша

Так как, в WordPress кэш, начиная с 2.х версии (не помню точно),  выключен, то кэширование будет работает только в связке с плагинами кэширования, которые совместимы с классом WP_Object_Cache. В частности, я говорю про плагины Владимира: WP File Cache и SJ Object Cache.

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

Вызов функции с использованием кэша

<ul>
<?php kama_previous_posts_from_cat (5, '', 1);  ?>
</ul>
// выведет 5 ссылок и закэширует результат в файл, с последующим извлечением информации из этого файла. Файл будет создавать отдельный для каждого поста.
Тег списка

Можно изменить тег списка li на любой другой, например div

<?php kama_previous_posts_from_cat (5, '', 0, 'div');  ?>

// выведет 5 ссылок в формате - <div class='li1'><a href='http://ссылка' title='Заголовок статьи'>Заголовок статьи</a></div> .
И последнее

Если передать последний (5-й) параметр, как false, то результат будет возвращен для обработки (return), а не выведен на экран.

Перелинковка статей в WordPress (предыдущие записи из категории) 125 комментариев
Вопросы 1 Все
  • Velimudr-1 cайт: freelance.ru/tim4ik

    Добрый день, Тимур.
    У меня вопрос; Нужно выводить 6 записей в хронологическом порядке (по времени от текущей статьи в порядке убывания) не с какой-то определённой категории, а с любой.
    Как сделать такой вывод?

    Ответить2.1 года назад #
  • Михаил

    добрый день, я в коде не спец и задам парочку глупых вопросов:

    1: Можно сделать перелинковку в обе стороны ? т.е например 2 назад и 2 вперед ?

    2: У меня есть несколько вложенных категорий. Я хочу чтобы линковка была только по родительской категории. Это возможно ?

    Ответить1.8 года назад #
    • Kama4472

      Все возможно, но конкретно код я вам не дам - времени нет... pardon

      Ответить1.8 года назад #
  • Дмитрий

    Люди, дайте решение использования этой функции с картинками (thumbnail). Пожалуйста!!! dash

    1
    Ответитьгод назад #
    • Виктор cайт: www.knep.ru

      Добавьте в код

      $thumb_id = get_post_thumbnail_id($pst->ID);
      $thumb_url = wp_get_attachment_image_src($thumb_id,'full', true);
      $img_url = $thumb_url[0];

      А в нужном месте для вставки урла thumbnail-картинки вставьте:

      $img_url
      1
  • Михаил ATs cайт: mihalica.ru
    @

    Спасибо, нормальный код!!
    На одном сайте нужно было вывести что-то подобное, только с картинками (превью): поковырялся - вроде, вывел. Правда все li поменял на дивы.
    Даже у себя воткнул подобный экзерсис, для наглядного экса...

    p|ss
    Есть у меня один сторонний вопросец по поводу одной улучшалки (оч. интересно Ваше мнение) не знаю как оформить: здесь или где-то в обратной связи сойдёт...
    Сяс сформулирую))

  • Андрей cайт: beguza.ru
    @

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

    Ответить4 месяца назад #

Здравствуйте, !

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