Перелинковка записей в WordPress: новая функция кольцевой перелинковки.

# Перелинковка записей в WordPress (предыдущие записи из категории). Функция 2

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

## Зачем нужна эта функция?

Эта функция была создана по запросу читателя, который хотел возможнос��ь кольцевой перелинковки для произвольных страниц на сайте. Мы также создали новую таксономию для этой цели. В новой версии я изменил подход к получению таксономии: теперь она извлекается напрямую из базы данных, что, с моей точки зрения, более логично и быстрее.

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

## Как установить функцию

Чтобы установить функцию, выполните следующие шаги:

1. Скопируйте приведенный ниже код.
2. Вставьте его в файл вашей темы functions.php.
3. В шаблоне, где вы хотите отобразить ссылки, вызовите функцию с нужными параметрами.

## Код функции

Вот код функции, который вы можете использовать:


/**
 * Получение предыдущих записей из рубрики (относительно текущей записи) +
 * кольцевая перелинковка (можно указывать таксономию и тип записи).
 * 
 * Кэширует результат в объектный кэш, если он включен.
 *
 * Вызываем функцию так:
 *
 *     echo kama_previous_posts_from_tax_lis( [
 *         'post_num' => 5,
 *         'format' => '{date:j.M.Y} - {a}{title}{/a}',
 *     ] );
 *
 * @param array|string $args {
 *     Параметры, переданные в виде массива или строки запроса.
 *
 *     @type int          $post_num      Количество ссылок.
 *     @type string       $format        Формат ссылки.
 *     @type string       $list_tag      Тег, оборачивающий каждую ссылку.
 *     @type string       $tax           Таксономия. Пр. category.
 *     @type string|array $exclude_terms  Элементы таксономии, которые нужно исключить.
 *     @type string       $post_type     Тип записи. Пр. post.
 * }
 *
 * @version 1.3
 */
function kama_previous_posts_from_tax_lis( $args = array() ){
    global $post, $wpdb;

    $rg = (object) wp_parse_args( $args, [
        'post_num'      => 5,
        'format'        => '',
        'list_tag'      => 'li',
        'tax'           => 'category',
        'post_type'     => 'post',
        'exclude_terms' => '',
    ] );

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

        if( $cache_out = wp_cache_get( $cache_key, $cache_flag ) ){
            return $cache_out;
        }
    }

    // Аналог wp_parse_list() для работы с WP < 5.1
    if ( is_string( $rg->exclude_terms ) ) {
        $rg->exclude_terms = preg_split( '/[s,]+/', $rg->exclude_terms, -1, PREG_SPLIT_NO_EMPTY );
    }
    if( 'exclude_terms' ){
        $exclude_terms = $rg->exclude_terms;
        foreach( $exclude_terms as & $term_id ){
            if( ! is_numeric( $term_id ) ){
                $term = get_term_by( 'slug', $term_id, $rg->tax );
                $term_id = $term ? $term->term_id : 0;
            }
            else {
                $term_id = (int) $term_id;
            }
        }
        unset( $term_id );
        $exclude_terms = array_map( 'intval', array_filter( $exclude_terms ) );

        $AND_NOT_IN = $exclude_terms ? sprintf( ' AND term_id NOT IN (%s)', implode( ',', $exclude_terms ) ) : '';
    }

    $sub_query_term_id = $wpdb->prepare(
        "(SELECT term_id FROM $wpdb->term_relationships rl
            LEFT JOIN $wpdb->term_taxonomy tx ON (rl.term_taxonomy_id = tx.term_taxonomy_id)
            WHERE object_id = %d AND tx.taxonomy = %s $AND_NOT_IN
            LIMIT 1)",
        $post->ID, $rg->tax
    );

    $WHERE_arr = [
        "p.post_status = 'publish'",
        "tax.term_id = $sub_query_term_id",
        $wpdb->prepare( 'p.post_date < %s', $post->post_date ),
        $wpdb->prepare( 'tax.taxonomy = %s', $rg->tax ),
        $wpdb->prepare( 'p.post_type = %s', $rg->post_type ),
    ];

    $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)";

    $WHERE = implode( ' AND ', $WHERE_arr );
    $ORDER_BY = 'ORDER BY p.post_date DESC';

    $sql = "$SELECT WHERE $WHERE $ORDER_BY LIMIT " . (int) $rg->post_num;

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

    $posts_count = count( $posts_data );

    // Если записей меньше чем нужно, делаем второй запрос
    if( ! $posts_data || $posts_count < $rg->post_num ){
        $NOT_IN = $post->ID;
        foreach( $posts_data as $pdata ){
            $NOT_IN .= ",$pdata->ID";
        }

        $WHERE_arr[] = "p.ID NOT IN ($NOT_IN)";
        $WHERE = implode( ' AND ', $WHERE_arr );

        $sql = "$SELECT WHERE $WHERE $ORDER_BY LIMIT " . (int) ( $rg->post_num - $posts_count );

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

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

    if( ! $posts_data ){
        return '';
    }

    // Формирование вывода
    $out = '';
    foreach( $posts_data as $pdata ){
        $a = sprintf( '', get_permalink( $pdata->ID ), esc_attr( $pdata->post_title ) );

        $formatted_title = sprintf( '%s%s%s', $a, esc_html( $pdata->post_title ), '' );
        $out .= sprintf( '
  • %s
  • ', $formatted_title ); } if( wp_using_ext_object_cache() ){ wp_cache_add( $cache_key, $out, $cache_flag ); } return $out; } ## Параметры, передаваемые функции 1. **post_num** — количество ссылок, которые нужно отобразить. По умолчанию 5. 2. **format** — формат отображаемых ссылок. По умолчанию "{a}{title}{/a}". 3. **tax** — таксономия, к которой принадлежит запись. По умолчанию — category. 4. **post_type** — тип записи, для которого происходит перелинковка. По умолчанию — post. ## Примеры использования функции ### Пример 1: Отобразить 10 предыдущих ссылок из категории для стандартных записей WordPress ```php

    Пример 2: Указание параметров и формата

    Отобразите 6 предыдущих ссылок для записей из таксономии movies, с типом записи movie. В вывод добавьте дату публикации записи и миниатюру:

     6,
        'format'    => '{thumb} {a}{title}{/a} - {date:j.M.Y}',
        'tax'       => 'movies',
        'post_type' => 'movie',
    ));
    ?>

    Эти примеры помогут вам лучше понять, как применять функцию на вашем сайте WordPress.

    Leave a Reply

    Ваш адрес email не будет опубликован. Обязательные поля помечены *