setup_postdata()
Устанавливает всевозможные данные поста (кроме глобальной переменной $post).
Заполняет глобальные переменные, которые нужны для корректной работы некоторых Тегов Шаблона, которые используются внутри Цикла WordPress. Некоторые из таких тегов шаблона: the_author(), wp_link_pages(), the_weekday_date(), is_new_day().
Устанавливает следующие глобальные переменные:
$id $authordata $currentday $currentmonth $page $pages $multipage $more $numpages
Функция не устанавливает переменную $post как глобальную. Поэтому вам нужно сделать это самостоятельно.
Функция ожидает, что передаваемая переменная имеет тот же объект что и глобальная переменная $post. Т.е. передаваемая переменная должна быть глобальным объектом $post. Если функция используется внутри цикла, то нужно передать текущий объект поста в цикле.
Всегда, когда используется эта функция, после цикла нужно сбрасывать глобальную переменную $post с помощью wp_reset_postdata().
Смотрите функцию the_post() - она работает на основе этой функции.
Хуков нет.
Возвращает
true|false
. Почти всегда возвращает true. Вернет false, когда глобальная переменная $wp_query не установлена или не является объектом WP_Query.
Использование
global $post; setup_postdata( $post );
- $post(объект/число) (обязательный)
- Объект или ID текущего поста.
Примеры
#1 Еще пример объясняющий работу setup_postdata()
Этот пример взят из комментария пользователя:
Вопрос:
Приветствую! Кажется я что то не допонимаю:
1) Такой код:
$top_posts = get_posts([ 'posts_per_page' => 5, ]); if ( $top_posts ) { foreach ( $top_posts as $post ) { // setup_postdata($post); the_title(); echo '<hr>'; } } wp_reset_postdata();
Работает нормально, выводит то что нужно. Зачем тогда использовать setup_postdata($post); ?
2) Такой код:
$top_posts = get_posts([ 'posts_per_page' => 5, ]); if ( $top_posts ) { foreach ($top_posts as $item) { setup_postdata($item); the_title(); echo '<hr>'; } } wp_reset_postdata();
Выводит 5 раз заголовок первой записи. Вот тут вообще не понял, почему? Разве обязательным является имя переменной $post при переборе цикла?
Ответ:
1 код
В описании setup_postdata(), написано зачем она нужна:
Заполняет глобальные переменные: $id, $authordata, $currentday, $currentmonth, $page, $pages, $multipage, $more, $numpages. Они нужны для корректной работы Тегов Шаблона, которые должны использоваться внутри Цикла WordPress.
Т.е. без нее некоторые теги шаблона будут работать некорректно! Для конкретно the_title() она не нужна...
2 код
the_title() и подобные ей работают именно с $post, указывая $post для foreach ты как бы изменяешь значение глобальной $post на текущее, а если указываешь $item, то переопределения не происходит, поэтому 5 одинаковых заголовков...
setup_postdata() в этом вопросе не фигурирует, у него другая задача - определить другие глоб.переменные кроме $post нужные для тегов шаблона. Например можно написать так:
... foreach ($top_posts as $item) { $post = $item; // перепишем глоб. `$post` setup_postdata($item); the_title(); echo '<hr>'; } ...
И из этого кода видно, что проще сразу $post использовать...
Кроме того, у тебя в коде нет определения $post как глобальной, а это значит что твой код находится в каком-то файле напрямую (т.е. он в глобальной области видимости PHP) и поэтому там $post уже глобальная. Так например, если обернуть твой код в функцию, то в начале функции нужно будет написать global $post, чтобы $post была глобальной, когда используется внутри функции (в локальной области видимости кода). Иначе теги шаблона типа the_title() правильно работать не будут.
#2 Как правильно передавать аргумент $post
Допустим мы получаем данные поста в переменную $post_object, тогда нам нужно создать переменную с названием $post и передать в нее эти данные. setup_postdata() работает именно с глобальной переменной $post.
global $post; setup_postdata( $post ); // или // Изменим глоб. $post - это нужно обязательно, но это не входит // в задачи функции setup_postdata() $post = $post_object; setup_postdata( $post_object ); // Используем Теги Шаблона // the_title(); // в конце всех операций обязательно возвращаем $post в исходную wp_reset_postdata();
Короткая запись примера выше:
setup_postdata( $GLOBALS['post'] = $post_object );
А вот так неправильно:
global $post; setup_postdata( $post_object );
#3 Если в аргумент функции передать не $post
Демонстрация того, что получится, если в качестве аргумента передать не глобальную переменную $post, а любую другую - функция не будет работать как нужно:
global $post; // Неправильно! $posts = get_posts("posts_per_page=2"); foreach( $posts as $pst ){ setup_postdata( $pst ); echo the_title(); echo '<br>'; } echo '$post->post_title - '. $post->post_title . '<br>'; wp_reset_postdata(); /* Вернет: Заголовок текущей страницы Заголовок текущей страницы $post->post_title - Заголовок текущей страницы */ // Правильно! // повторяем только определим $post $posts = get_posts("posts_per_page=2"); foreach( $posts as $pst ){ $post = $pst; setup_postdata( $pst ); echo the_title(); echo '<br>'; } echo '$post->post_title - '. $post->post_title . '<br>'; wp_reset_postdata(); /* Вернет: Заголовок полученного поста Заголовок второго полученного поста $post->post_title - Заголовок второго полученного поста */ // Правильно! // повторяем только с $post вместо $pst $posts = get_posts("posts_per_page=2"); foreach( $posts as $post ){ setup_postdata( $post ); echo the_title(); echo '<br>'; } echo '$post->post_title - '. $post->post_title . '<br>'; wp_reset_postdata(); /* Вернет тоже что и код до этого: Заголовок полученного поста Заголовок второго полученного поста $post->post_title - Заголовок второго полученного поста */
#4 Пример с циклом get_posts()
Получим посты из категории 1 и выведем их в виде ссылок:
<ul> <?php global $post; $args = array( 'numberposts' => 5, 'offset'=> 1, 'category' => 1 ); $myposts = get_posts( $args ); foreach( $myposts as $post ){ setup_postdata($post); ?> <li><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></li> <?php } wp_reset_postdata(); ?> </ul>
#5 Получим посты прямым запросом из базы данных
<ul> <?php global $wpdb, $post; $result = $wpdb->get_results( "SELECT * FROM $wpdb->posts WHERE post_type = 'post' AND post_status = 'publish'" ); foreach($result as $post){ setup_postdata($post); ?> <li><a href="<?php the_permalink()?>"><?php the_title();?></a></li> <?php } wp_reset_postdata(); ?> </ul>
Заметки
- Global. WP_Query. $wp_query WordPress Query object.
Список изменений
С версии 1.5.0 | Введена. |
С версии 4.4.0 | Added the ability to pass a post ID to $post. |
Код setup_postdata() setup postdata WP 6.4.3
function setup_postdata( $post ) { global $wp_query; if ( ! empty( $wp_query ) && $wp_query instanceof WP_Query ) { return $wp_query->setup_postdata( $post ); } return false; }