have_posts() – проверяет наличие постов для вывода на странице

Циклы – не самая лёгкая для понимания тема в изучении WordPress, поэтому возможно вам будет легче изучить её при помощи моего видеоурока.

Обратите внимание, что эта функция только для основного цикла. Если мы работаем с дополнительным циклом при помощи WP_Query, то используем метод класса WP_Query::have_posts().

Ещё раз о том, что делает функция, подробнее:

  • Когда вы используете её в качестве условия на странице if( have_posts() ) – тут всё просто, если есть посты на странице – return true, нет – false.
  • Когда используется в цикле while( have_posts() ), ситуация становится интереснее. Как вы знаете, у нас есть функции для вывода параметров текущего поста, например the_title(), the_permalink(). Как они определяют, что это тот самый пост? При помощи функции the_post(), которая при каждой итерации цикла хватает следующий пост в очереди. А что происходит, когда очередь заканчивается? – тогда while ( have_posts() ) возвращает false и цикл завершается. Однако (!) в то же время функция have_posts() также делает и сброс значения текущего поста, возвращаясь к самому первому на этой странице! 🎉

Пример 1. Стандартно

В шаблонах тем WordPress можно часто встретить подобную запись:

if( have_posts() ) :
 
	while( have_posts() ) : the_post();
 
		// тут обычно что-то происходит        
 
	endwhile;
 
else :
	echo 'Ничего не найдено на этой странице';
endif;
  • Сначала при помощи условия if ( have_posts() ) :, мы проверяем, есть ли вообще посты на этой странице? Это может быть страница рубрики, или главная – неважно. Если эта, предположим рубрика, пуста, то выводим «Ничего не найдено…» и больше ничего не делаем.
  • На строчках 3-7 мы проходим циклом по всем постам на странице «до тех пор, пока есть посты» и что-то делаем в теле цикла, например выводим заголовок поста через the_title() или же подключаем HTML/PHP темплейт записи функцией get_template_part() (это довольно часто встречается в темах).
  • Если убрать на 3-й строке функцию the_post(), то мы получим бесконечный цикл, потому что что the_post() сдвигает значение ткущего поста к следующему и в один момент, когда ей уже будет некуда сдвигать, have_posts() вернёт false, а если не производить «этот сдвиг», то have_posts() всегда будет возвращать true.

Пример 2. Множество циклов

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

while( have_posts() ) : the_post();
 
	// тут обычно что-то происходит        
 
endwhile;
 
while( have_posts() ) : the_post();
 
	// невероятные вещи продолжают происходить     
 
endwhile;

Как такая запись вообще возможна?

Об этом я и говорил в самом начале, когда упомянул сброс цикла. Когда функция the_post() доводит цикл до конца, у нас происходит сразу две вещи:

  1. have_posts() возвращает false,
  2. have_posts() сбрасывает цикл, устанавливая значение текущего поста на самый первый пост на странице;

Пример 3. Хитрое условие для последнего поста цикла

Или ещё можно сказать – для последней итерации цикла while ( have_posts() ). Обычно, когда идёт разговор об итерациях цикла, первое, что приходит в голову (мою), это уроки информатики с переменными-счетчиками.

Но только не сегодня.

while( have_posts() ) : the_post();
 
	// ... выводится пост например
 
	if( ! have_posts() ) { 
		echo 'это последний пост цикла';
	}
endwhile;

Стоп! Не копируйте, прошу!

Что думаете про этот код? Норм или что-то смущает?

Представьте:

  1. Идёт последняя итерация цикла, выводится последний пост.
  2. Затем функция have_posts() (строка 5) определяет, что это последний пост, возвращает false, и соответственно выводится месседж «это последний пост цикла».
  3. И вроде бы всё хорошо и цикл должен закончиться, однако have_posts() сбрасывает текущий пост цикла и всё начинается снова, так и не закончившись!

Как исправить? Вместо условия have_posts() на 5-й строке используем другое условие:

	global $wp_query;
	if( $wp_query->current_post + 1 == $wp_query->post_count ) {
		echo 'это последний пост цикла';
	}

Миша

В последние годы я долго не знал, что мне делать с сайтом misha.blog, ведь он практически не приносит никакого профита, но недавно я осознал, что моя миссия – способствовать распространению WordPress. Ведь WordPress – это лучший движок для разработки сайтов – как для тех, кто готов использовать заложенную структуру этой CMS, так и для тех, кто предпочитает headless решения.

Сам же я впервые познакомился с WordPress в 2009 году. Организатор WordCamp. Преподаватель в школах Epic Skills и LoftSchool.

Если вам нужна помощь с вашим сайтом или может даже разработка с нуля на WordPress / WooCommerce — пишите. Я и моя команда сделаем вам всё на лучшем уровне.

Оставить комментарий

Если вы хотите добавить код, не забудьте обернуть его в <pre lang="php"></pre>, в случае несоблюдения этого условия в 99% случаях ваш коммент будет удалён, а автор заблокирован. Печалька.