Перелинковка статей в 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 string $post_type (post) Тип записи с которой работаем. * @param bool $echo (true) Выводить на экран или возвращать для обработки (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 ); // пробуем получить предыдущие записи $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 ); // если количество меньше нужного, делаем 2-й запрос 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 ?: ''; $formated = strtr( $args->format, [ $date_m[0] => $date, '{title}' => esc_html( $pst->post_title ), '{a}' => $a1, '{/a}' => $a2, '{comments}' => $com_count, ] ); // есть миниатюра 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
- Теперь все аргументы передаются в первом параметре функции, в виде массива или строки.