WordPress как на ладони
rgbcode is looking for WordPress developers.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

GitHub
<?php
/**
 * Previous posts from the category (relative to the current post) + circular linking
 * Parameters passed to the function. Default values are indicated in parentheses.
 *
 * @param int    $post_num  (5)    Number of links.
 * @param string $format    ('')   Output format: `{thumb} {date:j.M.Y} - {a}{title}{/a} ({comments})`.
 * @param string $cache     ('')   Enable cache (default is off). Write 1 to enable.
 * @param string $list_tag  (li)   List tag.
 * @param string $post_type (post) Type of post we are working with.
 * @param bool   $echo      (true) Output to screen or return for processing (false).
 *
 * @version 1.1
 */
function kama_previous_posts_from_cat( $args ){
	global $post, $wpdb;

	$args = (object) wp_parse_args( $args, [
		'post_num' => 5,
		'format'   => '',
		'cache'    => true,
		'list_tag' => 'li',
		'post_type' => 'post',
		'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;

	$sql_SELECT = "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 = %s",
		$cat_id, $args->post_type
	);

	// try to get previous posts
	$sql = "$sql_SELECT WHERE p.ID < $post->ID $same_AND ORDER BY p.post_date DESC LIMIT " . (int) $args->post_num;

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

	$count_res = count( $res );

	// if the count is less than required, make a 2nd request
	if( ! $res || $count_res < $args->post_num ){
		$exclude = array_merge( [ $post->ID ], wp_list_pluck( $res, 'ID' ) );
		$exclude = implode( ',', array_map( 'intval', $exclude ) );

		$post_num = (int) $args->post_num - $count_res;

		$sql = "$sql_SELECT WHERE p.ID NOT IN ($exclude) AND p.ID != {$post->ID} $same_AND
		ORDER BY p.post_date DESC LIMIT " . (int) $post_num;

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

		$res = array_merge( $res, $res2 );
	}

	if( ! $res ){
		return false;
	}

	// output

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

	$add_thumb = ( false !== strpos( $args->format, '{thumb}' ) );

	$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 ?: '';

			$formatted = strtr( $args->format, [
				$date_m[0] => $date,
				'{title}' => esc_html( $pst->post_title ),
				'{a}' => $a1,
				'{/a}' => $a2,
				'{comments}' => $com_count,
			] );

			// thumbnail exists
			if( isset( $add_thumb ) ){
				$thumb = get_the_post_thumbnail( $pst->ID, 'thumbnail' );
				$formatted = str_replace( '{thumb}', $thumb, $formatted );
			}
		}
		else{
			$formatted = $a1 . esc_html( $pst->post_title ) . $a2;
		}

		$out .= apply_filters( 'kama_previous_posts_from_cat__append_out',
			"\n<$args->list_tag class=\"$x\">$formatted</$args->list_tag>",
			$args, $formatted, $x, $pst
		);
	}

	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
  • Теперь все аргументы передаются в первом параметре функции, в виде массива или строки.
126 комментариев
Полезные 1 Все
    Войти