Три способа сбросить цикл в WordPress: wp_reset_postdata, wp_reset_query и rewind_posts
Тщательный контроль над выполнением циклов – одно из неоспоримых преимуществ системы WordPress. Как только речь заходит о настройке различных параметров или работе с множественными циклами, разработчик должен получить возможность сброса циклов. Справиться с этим позволяют три тега шаблонов: wp_reset_postdata(), wp_reset_query() и rewind_posts().
Первый из них, wp_reset_postdata(), позволяет вернуть глобальную переменную $post к своему первоначальному состоянию в основном запросе. Тег шаблона особенно полезен при использовании с WP_Query; он позволяет изменить вывод циклов или создать множественные циклы на одной странице. Выглядит он следующим образом:
<?php wp_reset_postdata(); ?>
Насколько вы можете видеть, этот тег очень прост в своем применении: он не принимает никаких параметров и не возвращает никаких значений. Он просто сбрасывает данные записи после выполнения произвольного запроса. Скажем, к примеру, что у нас есть цикл WP_Query, находящийся в файле header.php темы:
$random_post = new WP_query(); $random_post->query('cat=3&showposts=1&orderby=rand'); while ($random_post->have_posts()) : $random_post->the_post(); <a href="<?php the_permalink() ?>" title="<?php the_title(); ?>"> <img src="<?php echo get_post_meta($random_post->ID, 'featured', true); ?>"> </a> endwhile;
Этот цикл показал бы случайную запись в заголовке, но он также изменил бы и объект запроса для любых других циклов на странице. Без исходных данных выполнение основного цикла с записями, который находится, скажем, в index.php, может привести к неожиданным результатам. К счастью, мы можем использовать wp_reset_postdata, чтобы вернуть объект запроса в его начальное состояние.
Для этого остаточно поместить wp_reset_postdata после всех своих произвольных циклов. Возвращаясь к нашему предыдущему примеру, чтобы сбросить цикл, достаточно применить wp_reset_postdata:
<a href="https://oddstyle.ru/?attachment_id=5542" rel="attachment wp-att-5542"><img src="https://oddstyle.ru/wp-content/uploads/2011/09/loopinfinity.jpg.png" alt="" title="loopinfinity.jpg" width="310" height="320" class="aligncenter size-full wp-image-5542" /></a> $random_post = new WP_query(); $random_post->query('cat=3&showposts=1&orderby=rand'); while ($random_post->have_posts()) : $random_post->the_post(); <a href="<?php the_permalink() ?>" title="<?php the_title(); ?>"> <img src="<?php echo get_post_meta($random_post->ID, 'featured', true); ?>"> </a> endwhile; wp_reset_postdata();
Тем самым мы избежим большинства неизвестных и непонятных ошибок, связанных с выполнением множественных циклов.
Wp_reset_postdata лучше всего использовать после циклов, созданных с помощью WP_Query.
Следующий тег шаблона, который мы рассмотрим, это wp_reset_query(). Функция wp_reset_query позволяет сбросить запрос, используемый в произвольных циклах. Эта функция, так же как и wp_reset_postdata, не принимает никаких параметров и не возвращает никаких значений. Она имеет следующий вид:
<?php wp_reset_query(); ?>
Эта функция была создана для предотвращения различных проблем с query_posts, как это описано в файле wp-includes/query.php:
/** * Destroy the previous query and set up a new query. * * This should be used after {@link query_posts()} and before another {@link * query_posts()}. This will remove obscure bugs that occur when the previous * wp_query object is not destroyed properly before another is set up. * * @since 2.3.0 * @uses $wp_query */
Если мы посмотрим на функцию wp_reset_query в query.php, то увидим, что она использует дополнительную функцию wp_reset_postdata, описанную выше:
// destroy and reset the query function wp_reset_query() { unset($GLOBALS['wp_query']); $GLOBALS['wp_query'] =& $GLOBALS['wp_the_query']; wp_reset_postdata(); // <-- RESET QUERY } // restore the query function wp_reset_postdata() { global $wp_query; if ( !empty($wp_query->post) ) { $GLOBALS['post'] = $wp_query->post; setup_postdata($wp_query->post); } }
Таким образом, обе функции wp_reset_query() и wp_reset_postdata() позволяют сбросить объект запроса путем восстановления глобальной переменной $post, однако wp_reset_query идет несколько дальше – эта функция фактически уничтожает предыдущий запрос перед совершением возложенной на нее задачи. Пример ниже иллюстрирует ее использование:
<?php query_posts('posts_per_page=3'); if (have_posts()) : while (have_posts()) : the_post(); ?> <h1><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></h1> <?php endwhile; endif; ?> <?php wp_reset_query(); ?>
Таким образом, функцию wp_reset_query лучше всего использовать после цикла query_posts, чтобы сбросить различные данные, оставшиеся после произвольного запроса.
Последняя, третья функция – это rewind_posts(). Она позволяет перемотать цикл в конец, что позволит вам снова использовать тот же самый запрос. Как и две предыдущие функции, rewind_posts() не принимает параметров и не возвращает значений.
<?php rewind_posts(); ?>
Чтобы понять, как использовать rewind_posts(), давайте предположим, что мы хотим использовать один и тот же запрос в двух различных местах на странице. Допустим, мы хотим вывести на экран заголовки записей в первом цикле, и содержимое записей во втором цикле. Чтобы использовать те же самые записи в первом цикле и во втором цикле, мы включаем rewind_posts после первого цикла:
if (have_posts()) : while (have_posts()) : the_post(); ?> <h1><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></h1> <?php endwhile; endif; ?> <?php rewind_posts(); ?> <?php while (have_posts()) : the_post(); ?> <?php the_content(); ?> <?php endwhile; ?>
Если wp_reset_query и wp_reset_postdata сбрасывают весь объект запроса, то rewind_posts сбрасывает счетчик записей, как это и указано в файле wp-includes/query.php:
// rewind the posts and reset post index function rewind_posts() { $this->current_post = -1; if ( $this->post_count > 0 ) { $this->post = $this->posts[0]; } }
Функцию rewind_posts лучше всего использовать для повторного использования одного и того же запроса на одной и той же странице.
http://digwp.com/2011/09/3-ways-to-reset-the-wordpress-loop/