Перелинковка статей в WordPress (предыдущие записи из категории)
Это продолжение поста о перелинковке статей.
В этой статье я хочу поделиться очередной функцией для WordPress, в задачи, которой входит вывод предыдущих записей из категории (рубрики), текущей статьи. Функция, так же, создает кольцевую перелинковку (см. первую статью).
Принципиальное отличие этой функции в том, что она выводит предыдущие записи из категории, тогда как, прошлая подобная функция выводит просто предыдущие записи.
Альтернатива этой функции находится по этой ссылке, в ней можно указать таксономию и тип записи, для которых будет происходить перелинковка.
Почти, такую же функцию я публиковал в комментариях на сайте Dimox.name здесь. Почему "почти"? Потому что, эта функция обладает рядом преимуществ над той, что была опубликована на Dimox.name, а именно:
-
Можно задавать формат вывода, благодаря чему её очень просто внедрить в любой шаблон;
-
Для этой функции не нужно заранее определять текущую категорию (функция сама определит её), т.е. меньше лишнего кода в шаблоне и проще новичкам.
-
Функция не использует тяжелую функцию самого WordPress get_posts()
-
К каждому тегу ссылки добавляется классы li1 и li2, чтобы легко можно было раскрасить список в зебру.
-
Можно включить кэширование. Подробнее об этом ниже.
- Список сортируется по дате, а не по 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
- Теперь все аргументы передаются в первом параметре функции, в виде массива или строки.