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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

/**
 * Предыдущие записи из рубрики (относительно текущей записи) + кольцевая перелинковка
 * Параметры передаваемые функции. В скобках указано дефолтное значение.
 *
 * @param int    $post_num (5)    количество ссылок
 * @param string $format   ('')   {thumb} {date:j.M.Y} - {a}{title}{/a} ({comments})
 * @param string $cache    ('')   включить кэш (по умолчанию выключен). Пишем 1, чтобы включить
 * @param string $list_tag (li)   тег списка
 * @param bool   $echo     (true) Выводить на экран или возвращать для обработки (false)
 *
 * @version 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 .= apply_filters( 'kama_previous_posts_from_cat__append_out', 
					"\n<$args->list_tag class=\"$x\">$formated</$args->list_tag>",
					$args, $formated, $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
  • Теперь все аргументы передаются в первом параметре функции, в виде массива или строки.
125 комментов
Полезные 1 Все
  • Domen

    Вы меня неправильно поняли.
    Я хочу, чтобы если запись в категории только одна и ссылаться ей не на кого, то вместо пустого окна выводилось бы сообщение, что записей в данной категории нет.
    Вы это реализовали вот этим кодом:

    $res = $wpdb->get_results($sql);  
    if( !$res )  
    	 return print "Нет похожих записей.";

    Но с этим кодом происходит небольшая ошибка - у самой ПЕРВОЙ записи в какой-либо категории выводится это сообщение, даже если в этой категории есть и другие записи, на которые можно ссылаться. Т.е. получается, что все первые записи каких-либо категорий остаются без ссылок на другие записи этих категорий. Вот как это исправить?

    Ответить7.8 лет назад #
    • Kama7482

      Это видимо глюк шаблона. Попробуйте шаблон сменить на дефолтный.

      У меня на этом блоге используется эта функця, вот первая запись. Как видите, все работает нормально. Где может быть ошибка — идей нет.

      Ответить7.8 лет назад #
  • Kareg cайт: seo-newbie.ru

    Выражаю огромную благодарность за данную функцию - очень помогла в перелинковке. Поставил себе и крайне доволен тем, что ссылки статические.

    Ответить7.6 лет назад #
  • @ Kite

    Что-то весь сайт падает... На wp 3.2.1 - работает? воть...

    -1
    Ответить7.6 лет назад #
    • Kama7482

      Так вы этот мой код в конструкцию вида:

      <?php 
      //здесь код
      ?>

      суньте, а то он у вас как обычный текст работает mosking

      Ответить7.6 лет назад #
  • @ Kite

    Parse error: syntax error, unexpected T_VARIABLE in /var/www/bot-in9803/data/www/furgeschaft.net/wp-content/themes/coralis/functions.php on line 135
    " $Sformat = str_replace('{comments}', (($pst->comment_count==0)?'':$pst->comment_count), $Sformat)"
    Пробовал сразу так..mosking
    Может из-за того что коменты вырезаны?

    Ответить7.6 лет назад #
    • Kama7482

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

      Ответить7.6 лет назад #
  • @ Kite

    sad
    и самое интересное что на др. сайте работает...

    Ответить7.6 лет назад #
  • fantini cайт: new-aquarist.ru

    Здравствуйте.
    Установил эту функцию. Почти идеально работает.
    На моем сайте есть подрубрики, то есть: рубрика -> в ней подрубрика -> пост. В таких постах отображаются не 5 последних записей, а только те, которые есть в этой подрубрике. Если в подрубрике только 2 статьи, то и покажет 2 ссылки. Это возможно исправить?

    Ответить7.6 лет назад #
    • Kama7482

      Теоретически конечно можно, а так - нет - долго, сложно.

      Ответить7.6 лет назад #
  • Денис

    Здравствуйте. У меня такой вопрос, код конечно работает идеально, но если к примеру у меня к посту указывается две рубрики, одна основная а другая дочерняя, этот код выводит только ссылки по первой рубрике, в моем случае она дочерняя идет. Как сделать так чтоб выводились ссылки из всех (двух) указанных рубрик к посту, а не только к дочерней? Спасибо!

    Ответить7.5 лет назад #
    • Kama7482

      Не могу помочь, это связано с изменением кода и с рядом сложностей. ищите альтернативу этой функции, если не подходит.

      Ответить7.5 лет назад #
  • Андрей

    Здравствуйте. Скажите как убрать точки перед сылками?

    Ответить7.5 лет назад #
  • Meoblog.ru cайт: www.meoblog.ru

    добрый день. Отличный вариант для перелинковки. Ставлю его на всех своих сайтах. недавно столкнулся с проблемой - необходимо было выводить предыдущие записи категории с миниатюрами. Прикрутил Ваш код, но учитывая, что я от слова "программист" очень далек, пришлось методом научного тыка дорабатывать Ваш код (надеюсь Вы не против). В общем с горем пополам получилось. Возможно еще кому-то будет интересен такой вариант вывода:

    После строки:

    $Title = $pst->post_title;

    Добавляем:

    $image_attributes = wp_get_attachment_image_src(get_post_thumbnail_id($pst->ID), 'medium');
    $imth = '<img style="width:34px; height:34px;" src="'.$image_attributes[0].'"/>';

    А вместо следующей:

    $a1 = $imth . "<a href='". get_permalink($pst->ID) ."' title='{$Title}'>";

    Ставим:

    $a1 = $imth . "<a href='". get_permalink($pst->ID) ."' title='{$Title}'>";

    Возможно такой вариант нелогичен, или присутствуют лишние строки - я без понятия, собирал функции из WP-кодекса как Lego в детстве, в итоге добился результата smile

    Ответить7.4 лет назад #
  • igbur cайт: igbur.com

    Спасибо! smile Отличная перелинковка, жаль раньше о ней не узнал..
    У меня почему то отказывался работать код, пришлось вырезать вот эту часть:

    $Sformat = str_replace('{comments}', (($pst->comment_count==0)?'':$pst->comment_count), $Sformat);

    Наверное проблема в моем шаблоне sad ..

    Ответить7 лет назад #
Здравствуйте, !     Войти . Зарегистрироваться