setup_postdata() WP 1.5
Устанавливает глобальные данные поста. Нужен для удобного использования Тегов шаблона связанных с оформление поста: the_title()
, the_permalink()
и т.д.
Заполняет глобальные переменные: $id
, $authordata
, $currentday,
$currentmonth
, $page
, $pages
, $multipage
, $more
, $numpages
. Они нужны для корректной работы Тегов Шаблона, которые должны использоваться внутри Цикла WordPress.
Функция не устанавливает переменную $post
как глобальную, а ожидает, что передаваемая переменная $post
уже глобальная. Если функция используется внутри цикла, то нужно передать текущий объект поста в цикле.
Смотрите также аналогичную функцию the_post(), которая также работает на основе метода WP_Query::setup_postdata()
.
Функция работает именно с глобальной переменной $post
или с её копией, но лучше не экспериментировать и просто всегда использовать переменную $post
она в ВП центровая при работе с записями.
С WP 4.4 появилась возможность передать ID поста (число) в переменную $post
.
Всегда, когда используется эта функция, после цикла нужно сбрасывать запрос с помощью wp_reset_postdata().
WP_Query::setup_postdata()
Хуков нет.
Возвращает
true/false. Почти всегда возвращает true. Вернет false, когда глобальная переменная $wp_query не установлена или не является объектом WP_Query
.
Использование
global $post; setup_postdata( $post );
- $post(объект/число) (обязательный)
- Объект или ID текущего поста.
Примеры
#1 Как правильно передавать аргумент $post
Допустим мы получаем данные поста в переменную $post_object
, тогда нам нужно создать переменную с названием $post
и передать в нее эти данные. setup_postdata()
работает именно с глобальной переменной $post
.
global $post; // Перенаправим полученные данные поста в переменную $post и не в какую другую. $post = $post_object; setup_postdata( $post ); // the_title();
Короткая запись примера выше:
setup_postdata( $GLOBALS['post'] = & $post_object );
А вот так неправильно:
global $post; setup_postdata( $post_object ); // опс
#2 Пример с циклом 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>
#3 Получим посты прямым запросом из базы данных
<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>
#4 Если в аргумент функции передать не $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>'; /* Вернет: Заголовок текущей страницы Заголовок текущей страницы $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>'; /* Вернет: Заголовок полученного поста Заголовок второго полученного поста $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>'; /* Вернет тоже что и код до этого: Заголовок полученного поста Заголовок второго полученного поста $post->post_title - Заголовок второго полученного поста */
#5 Еще пример объясняющий работу 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()
правильно работать не будут.
Заметки
- 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:
wp-includes/query.php
WP 5.3
Cвязанные функции
Из метки: loop (Цикл WP)
Еще из метки: query (запрос)
Еще из раздела: Запросы
Еще из тегов шаблона: Основные
- bloginfo()
- calendar_week_mod()
- get_archives_link()
- get_bloginfo()
- get_calendar()
- get_current_blog_id()
- get_footer()
- get_header()
- get_search_form()
- get_sidebar()
- get_template_part()
- is_active_sidebar()
- is_admin()
Уважаемые товарищи, подскажите, а как сюда передать несколько определенных категорий?