WordPress как на ладони
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   ('')   = {thumb} {date:j.M.Y} - {a}{title}{/a} ({comments})
 * cache    ('')   = включить кэш (по умолчанию выключен). Пишем 1, чтобы включить
 * list_tag (li)   = тег списка
 * echo     (true) = Выводить на экран или возвращать для обработки (false)
 * ver 1.0
 */
function kama_previous_posts_from_cat( $args ){
	global $post, $wpdb;

	$args = (object) wp_parse_args( $args, array(
		'post_num'  => 5,
		'format'    => '',
		'cache'     => true,
		'list_tag'  => 'li', // тег
		'echo'      => true,
	) );

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

	if( $args->cache && $cache_out = wp_cache_get($cache_key, $cache_flag) ){
		if( $args->echo )
			return print( $cache_out );
		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 = $wpdb->prepare( "AND tax.term_id = %s AND tax.taxonomy = 'category' AND p.post_status = 'publish' AND p.post_type = 'post'", $cat_id );

	// пробуем получить предыдущие записи
	$sql = "$same_join WHERE p.ID < $post->ID $same_and ORDER BY p.post_date DESC LIMIT ". intval($args->post_num);

	$res = $wpdb->get_results( $sql );

	$count_res = count($res);

	// если количество меньше нужного, делаем 2-й запрос
	if ( ! $res || $count_res < $args->post_num ){
		$exclude = $post->ID;

		if( $res ) foreach( $res as $id ) $exclude .= ','. $id->ID;

		$post_num = (int) $args->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 ". intval($post_num);

		$res2 = $wpdb->get_results( $sql );

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

	if ( $args->format )
		preg_match( '!{date:(.*?)}!', $args->format, $date_m );
	if ( false !== strpos($args->format, '{thumb}') )
		$add_thumb = 1;

	$out = $x = '';
	foreach( $res as $pst ){
		$x = ($x == 'li1') ? 'li2' : 'li1';
		$a1 = '<a href="'. get_permalink($pst->ID) .'" title="'. esc_attr($pst->post_title) .'">';
		$a2 = "</a>";

		if ( $args->format ){
			$date      = apply_filters('the_time', mysql2date($date_m[1], $pst->post_date) );
			$com_count = $pst->comment_count == 0 ? '' : $pst->comment_count;

			$formated = str_replace( $date_m[0], $date, $args->format );
			$formated = str_replace('{title}', esc_html($pst->post_title), $formated );
			$formated = str_replace('{a}', $a1, $formated );
			$formated = str_replace('{/a}', $a2, $formated );
			$formated = str_replace('{comments}', $com_count, $formated );
			// есть миниатюра
			if( isset($add_thumb) ){
				$thumb = get_the_post_thumbnail( $pst->ID, 'thumbnail' );
				$formated = str_replace('{thumb}', $thumb, $formated );
			}
		}
		else
			$formated = $a1 . esc_html($pst->post_title) . $a2;

		$out .= "\n<$args->list_tag class=\"$x\">$formated</$args->list_tag>";
	}

	if( $args->cache ) wp_cache_add($cache_key, $out, $cache_flag);

	if( $args->echo ) return print $out;

	return $out;
}

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

<ul>
<?php kama_previous_posts_from_cat('post_num=5');  ?>
</ul>

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

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

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

Для настройки формата вывода используйте

В параметре format можно использовать следующие шорткоды:

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

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

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

Кэширование по умолчанию включено, но пользу от использования можно будет ощутить, если функция вызывается несколько раз или если включен плагин объектного кэширования: WP File Cache, SJ Object Cache и другие...

Тег списка

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

<?php kama_previous_posts_from_cat('post_num=5&list_tag=div'); ?>

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

Изменения

Версия 1.0.

  • Добавил шорткод {thumb} в параметр format
  • Теперь все аргументы передаются в первом параметре функции, в виде массива или строки.
Перелинковка статей в WordPress (предыдущие записи из категории) 129 комментариев
Полезные 1 Вопросы 2 Все
  • Velimudr-1 cайт: freelance.ru/tim4ik

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

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

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

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

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

    Ответить2 года назад #
    • Kama4662

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

      Ответить2 года назад #
  • Михаил ATs cайт: mihalica.ru @

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

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

    Ответитьгод назад #
  • Андрей cайт: beguza.ru @

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

  • Анатолий cайт: designzoom.ru @

    Здравствуйте! Как убрать список с главной страницы и как-то улучшить его внешний вид на последующих? Спасибо.

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

    Есть у кого этот код с добавлением миниатюр записей? Спасибо!

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

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

      Добавил шорткод {thumb} в параметр format, тестани плз все ли норм работает. Версия 1.0

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

        скобочку одну не закрыл.

        Да миниатюра подставляется! Спасибо!

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

        Да миниатюра подставляется! Спасибо!

        Огонь спасибо Kama!!! Вот что вышло

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

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

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