Использование “setup_postdata” с “get_template_part” не работает.

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

Я хочу повторно использовать код, сделанный в шаблоне, в коротком коде.

Я сделал это в моем коротком коде

$args = array(...);             
$posts      = get_posts($args);
for ( $j=0; $j < count($posts); $j++ ) {

    ...
    $post_id = $posts[$j]->ID;

    setup_postdata($posts[$j]);
    ob_start();

    get_template_part( 'includes/post-formats/postbox' );
    $output .= ob_get_contents();
    ob_end_clean();
}

return $output;

Код в шаблоне выглядит примерно так:

<div class="post-header span3">
        <?php if(is_sticky()) : ?>
            <h5 class="post-label"><?php echo theme_locals("featured");?></h5>
        <?php endif; ?>
        <h2 class="post-title"><a href="https://wordpress.stackexchange.com/questions/192992/<?php the_permalink(); ?>" title="<?php the_title(); ?>"><?php the_title(); ?></a></h2>
        <?php
            the_post_thumbnail( 'medium' );
        ?>
    </div>
 <div class="foo">
 <?php the_content(); ?>
 </div>

Ну, проблема в том, что заголовок и миниатюра не работают, заголовок и миниатюра отображаются неправильно. Только содержимое отображается корректно (через the_content()).

Для тех, кто не создает запрос с помощью get_posts(), вам может понадобиться сначала сослаться на глобальную переменную $post перед использованием setup_postdata().

Вот пример короткого кода, использующего цикл foreach и итерацию по массиву объектов постов из поля связи ACF:

function your_shortcode() {
    // сначала сослаться на глобальный $post
    global $post;

    $featured_posts = get_field('relationship_field'); 
    $html="";

    ob_start();

    foreach( $featured_posts as $post ): 

        // Настройка этого поста для функций WP (переменная должна называться $post).
        setup_postdata($post);

        get_template_part('php/components/card', 'project');

    endforeach;

    $html .= ob_get_clean();

    // Сброс глобального объекта поста, чтобы остальная часть страницы работала корректно.
    wp_reset_postdata(); 

    return $html;

}
add_shortcode( 'your-shortcode', 'your_shortcode' );

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

Проблема с использованием setup_postdata и get_template_part в шорткодах WordPress

Введение

При разработке шорткодов в WordPress, одна из распространенных задач — это использование шаблонов для вывода постов, которые можно переиспользовать. Однако, часто возникают проблемы при использовании функций, таких как setup_postdata и get_template_part, что может приводить к неправильному отображению заголовков и миниатюр постов. Рассмотрим данную проблему на конкретном примере и предложим оптимальные решения.

Суть проблемы

В представленном коде вы используете цикл, чтобы пройти по массиву постов, полученным с помощью get_posts(). Вы вызываете setup_postdata($posts[$j]), чтобы подготовить данные поста для использования в вашем шаблоне. Однако, несмотря на это, заголовок и миниатюра выводятся некорректно, в то время как содержимое поста отображается правильно.

Причины проблемы

  1. Некорректное использование setup_postdata: Функция setup_postdata ожидает, что переменная $post будет ссылаться на глобальный объект поста. Если объект поста не установлен корректно, функции, такие как the_title() и the_post_thumbnail(), могут не работать должным образом.

  2. Контекст шаблона: Когда вы вызываете get_template_part, шаблон пытается получить доступ к переменной $post, но если она не была установлена верно, это приведет к ошибкам в выводе.

Решение проблемы

Чтобы решить данную проблему, необходимо учесть несколько важных моментов:

  1. Глобальная переменная $post: Убедитесь, что вы сначала определяете глобальную переменную $post, а затем передаете объект поста в setup_postdata.

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

Вот исправленный код вашего шорткода:

function your_custom_shortcode() {
    // Определяем глобальную переменную $post
    global $post;

    $args = array(...);             
    $posts = get_posts($args);

    $output = "";
    ob_start();

    foreach ($posts as $single_post) {
        // Устанавливаем глобальную переменную $post на текущий пост
        setup_postdata($single_post);

        // Получаем шаблон
        get_template_part('includes/post-formats/postbox');
    }

    // Сохраняем вывод
    $output .= ob_get_clean();

    // Сбрасываем данные поста
    wp_reset_postdata(); 

    return $output;
}
add_shortcode('your_shortcode', 'your_custom_shortcode');

Заключение

Следуя данным рекомендациям, вы сможете корректно использовать setup_postdata и get_template_part в своих шорткодах WordPress. Убедитесь, что глобальная переменная $post правильно установлена перед вызовом шаблона. Это позволит избежать распространенных ошибок, связанных с выводом заголовков и миниатюр постов.

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

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

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