Шорткод в цикле всегда отображает данные первой записи на странице.

Вопрос или проблема

Я создаю шорткод для получения категорий данного поста и отображения их в стильном виде. Я создал следующий шорткод:

function t3_categories_fonction(){
    global $post; // Получаем глобальный объект поста
    
    // Получаем ID поста из глобального объекта поста, если ID не передан
    //$post_id = $post->ID;
    $post_id = get_the_ID();
    
    // тестовый цикл для отображения категорий в одной строке (стилизация будет позже)
    $post_cats = get_the_category($post_id);
    foreach($post_cats as $cat){
        $result .= '-';
        $result .= $cat->slug;
    }
    return $result;
}
add_shortcode('t3_categories', 't3_categories_fonction' );

Однако этот шорткод всегда отображает категории первого поста на странице, даже когда он находится в отдельном вторичном цикле, а не категории поста, в котором находится блок шорткода (я использую блоковые темы, я сделал циклы в виде блоков, а шорткод находится внутри блока модели публикации моего цикла).

Я пробовал как get_the_ID(), так и глобальный $post. Результат одинаковый.

Эта проблема похожа на ту, которую я разместил на StackOverflow, и решения, предложенные там, не устранили проблему.

Ответ или решение

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

Теория

Одной из наиболее вероятных причин данной проблемы является то, как WordPress управляет глобальной переменной $post и её идентификатором в различных циклах. В WordPress, когда вы создаете новый экземпляр цикла, особенно используя WP Query или блоки, система ожидает, что переменные $post и текущий ID будут изменяться в соответствии с текущей обрабатываемой записью. Однако в вашем случая, судя по поведению, похоже, что текущий $post не обновляется должным образом в вашем шорткоде, оставаясь на первой записи.

Пример

Давайте более детально изучим ваш текущий код:

function t3_categories_fonction() {
    global $post; // Получаем глобальный объект записи

    // Получаем ID записи
    $post_id = get_the_ID();

    // Получаем категории записи
    $post_cats = get_the_category($post_id);
    foreach ($post_cats as $cat) {
        $result .= '-';
        $result .= $cat->slug;
    }
    return $result;
}
add_shortcode('t3_categories', 't3_categories_fonction');

В данном коде мы видим использование функций get_the_ID() и get_the_category($post_id), которые зависят от правильной и актуальной настройки глобальной переменной $post. Если переменная не обновляется правильно, то get_the_ID() всегда будет возвращать ID первой записи, как это и происходит.

Применение

Для решения вашей проблемы, сначала убедитесь, что контекст записи изменяется надлежащим образом в вашем цикле. Может быть полезно воспользоваться функцией setup_postdata($post) каждую итерацию вашего цикла. Однако, в случае шорткодов, они часто используются вне основного цикла, что может привести к таким проблемам.

Модифицируйте свой код следующим образом:

function t3_categories_fonction($atts) {
    global $post;
    $original_post = $post; // Сохраняем исходный контекст

    // Пытаемся получить ID из атрибутов шорткода
    $atts = shortcode_atts(array('id' => 0), $atts);
    $post_id = $atts['id'];

    // Если ID не передан, используем глобальный объект
    if (!$post_id) {
        $post_id = get_the_ID();
    }

    // Если $post_id на этом этапе не определен, возвращаем пустую строку
    if (!$post_id) return '';

    // Устанавливаем данные текущей записи
    $post = get_post($post_id);
    setup_postdata($post);

    $result = '';
    $post_cats = get_the_category($post_id);

    if (!empty($post_cats)) {
        foreach ($post_cats as $cat) {
            $result .= '-' . $cat->slug;
        }
    }

    // Восстанавливаем исходный контекст поста
    wp_reset_postdata();
    $post = $original_post;

    return $result;
}
add_shortcode('t3_categories', 't3_categories_fonction');

Мы добавили аттрибут id для шорткода, чтобы в случае необходимости можно было явно указать ID записи. Это полезно, если шорткод используется вне цикла или в несколько сложных случаях. Мы также сохраняем и восстанавливаем состояние глобального объекта $post, чтобы убедиться, что после выполнения шорткода контекст не нарушится.

Заключение

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

Оцените материал
Добавить комментарий

Капча загружается...