Have posts
Всем привет! Сегодня на seo-mayak.com я расскажу, что такое цикл WordPress, как он работает и какую роль играют циклы в формировании страницы. Познакомимся с функциями: have_posts(), the_post(), the_permalink() и the_title(), а также разберем глобальную переменную $post.
Признаюсь, что на самом деле я планировал написать пост совершенно на другую тему, но в процессе понял, что сначала мне необходимо растолковать понятие the loop ( в переводе с англ. — петля или цикл).
А так как тема циклов WordPress довольно обширная, мне пришлось изменить планы и начать писать новую статью. Кстати такое у меня случается уже не в первый раз.
В комментариях часто спрашивают о том, в какое место файла надо вставить тот или иной код и мне парой очень сложно объяснить, особенно новичкам, что некоторые функции работают только в пределах цикла.
Итак, что такое цикл WordPress?
Конечно общее определение не дает ясного понимание сего процесса. Возьмем для примера главную страницу блога, на которой выводятся анонсы записей.
Вы никогда не задумывались, каким образом WordPress выводит те самые анонсы и почему на странице отображаются 5 и более превьюшек?
Для того, чтобы попытаться дать понятное объяснение тому, как работает цикл WordPress, давайте разберемся с процессами, которые происходят в глубине сознания WordPress, когда пользователь открывает главную страницу Вашего блога. Поехали!
Условия цикла WordPress. Функция have_posts()
Содержание
- 0.1 Условия цикла WordPress. Функция have_posts()
- 0.2 Анатомия цикла WordPress. Функция the_post() и переменная $post
- 1 1. Получаем запись, опубликованную в промежуток между двумя датами
- 2 2. Используем больше, чем один главный цикл на странице без дублирования записей.
- 3 3. Вставляем рекламу после первой записи
- 4 4. Получаем записи с определенными пользовательскими полями и определенными значениями
- 5 5. Список запланированных записей
- 6 6. Выводим записи, опубликованные год назад
- 7 7. Используем главный цикл для создания шаблона страницы архива
- 8 8. Создаем главный цикл с помощью объекта WP_Query
- 9 9. Выводим последние прилепленные записи
- 10 10. Создаем цикл изображений
- 11 This issue is now finally resolved by myself. Find the solution in the end of this post. Question was in short: How can i ask in my WP template, IF the whole array of have_posts contains any post from a certain category
- 12 Понимание цикла в WordPress
- 13 Примеры цикла
- 14 Настраиваем query_posts()
- 15 Настраиваем WP_Query
- 16 Настраиваем get_posts
- 17 Цикл не беспокоится о разметке
- 18 Мощь WP_Query
Сразу оговорюсь, что существует несколько способов запуска цикла WordPress и я опишу некоторые из них, в своих будущих статьях, а для облегчения восприятия начнем мы с самого распространенного, стандартного цикла.
В файле index.php, а именно этот файл отвечает за главную страницу любого блога, стандартный цикл начинается со строк:
<?php if (have_posts()) : while (have_posts()) : the_post(); ?>
И заканчивается строками:
<?php endwhile; else: ?> <p><?php _e('К сожалению, по Вашему запросу ничего не найдено');?></p> <?php endif; ?>
Итак, пользователь открывает главную страницу и в работу вступает функция have_posts(), которая проверяет базу данных на наличие постов, соответствующих данному запросу.
Конструкция if в PHP задает условие для выполнения сценария, исходя из которого будут выполнятся все действия (if можно перевести, как «Если»). Данный сценарий включает в себя два условия.
Условие №1. ЕСЛИ ответ БД положительный (т.е, если функция have_posts() возвращает значение true), то выражение while запускает цикл.
Цикл делает определенное количество витков, пока не дойдет до последней записи, количество которых регулируется настройками WordPress (по умолчанию десять записей).
Если выражаться профессиональным языком, цикл будет продолжаться до тех пор, пока функция have_posts() не вернет значение false.
После того, как цикл сделал свой последний виток и функция have_posts() вернула значение false, выражение endwhile дает команду остановить цикл.
Условие №2. ЕСЛИ ответ БД отрицательный (т.е, функция сразу возвращает значение false), это значит, что в БД не было обнаружено записей, соответствующих запросу и цикл не запустится.
В этом случаи вступает в силу второе условие, которое «включается» с помощью выражения else (можно перевести, как «Иначе»).
ИНАЧЕ откроется страница ошибки 404 и на экран будет выведено сообщение, наподобие: «К сожалению, по Вашему запросу ничего не найдено».
И наконец, выражение endif завершает выполнение сценария.
Теперь давайте вернемся как условию №1 и более подробно разберем все происходящие в нем события.
Анатомия цикла WordPress. Функция the_post() и переменная $post
Итак, пользователь открыл главную страницу, функция have_posts() проверила БД на наличие записей, соответствующих запросу и вернула значение true, что означает — данные найдены. Далее выражение while запускает цикл и активируется функция the_post().
Функция the_post() вступает в взаимодействие с глобальной переменной $post и получат от нее все необходимы данные, которые в последствии передает в браузер пользователя.
Наверняка у многих возник вопрос, а что такое глобальная переменная? Думаю об этом надо рассказать по-подробней. Но прежде всего необходимо понять, что такое переменная в принципе.
На заметку! Переменная — это некий контейнер, в который помещаются данные, необходимые для работы тех или иных функций.
Переменные в PHP могут быть трех типов: локальные, глобальные и статические.
Локальные переменные создаются непосредственно внутри функции и данные, занесенные в них, предназначаются для работы только той функции, в которой они были созданы и не могут быть использованы за ее пределами.
Глобальные переменные — это переменные, которые объявляются в не тела какой-то конкретной функции, поэтому могут распространятся и на другие функции, но в рамках определенной программы.
Статические переменные в отличии от локальных и глобальных не затираются при выходе их функций, но распространяют свое действие только в пределах определенной блока кода или файла.
В нашем случаи, данной программой является цикл WordPress. Как я уже говорил ранее, цикл можно создать с помощью разных функций и в работе всех этих функций допускается использование переменной $post. Надеюсь понятно.
Глобальная переменная $post создается веб-сервером и является, так сказать, одноразовой, в том смысле, что при каждом новом витке цикла, она создается заново и принимает данные следующего поста. Работает данная переменная только в пределах цикла.
Переменная $post может принимать ряд свойств (до это я их называл данными). Названия этих свойств, ни что иное, как названия полей в таблице wp_posts базы данных. Вот эти свойства:
ID – идентификатор записи;
post_author – идентификатор автора записи;
post_parent – идентификатор родительского поста;
post_title – название записи;
post_content – содержание записи;
comment_count – количество комментариев к записи;
comment_status – можно ли добавлять комментарии к записи (open | closed | registered_only);
post_date – дата записи (формат этой даты YYYY-MM-DD HH:MM:SS);
post_date_gmt – дата записи в виде GMT (формат даты YYYY-MM-DD HH:MM:SS);
post_modified – дата последнего обновления записи (формат даты YYYY-MM-DD HH:MM:SS);
post_modified_gmt — дата последнего обновления записи в GMT (формат YYYY-MM-DD HH:MM:SS);
post_excerpt – выдержка из записи (цитата);
post_status – статус записи (publish | pending | draft | private | static | object | attachment | inherit | future | trash);
ping_status — разрешен/запрещен пинг к записи: pingback и trackback (open | closed);
post_password – пароль для записи;
post_name – slug (слаг записи);
to_ping – URL для пинга;
pinged – URL, которые уведомляются о том, что в данном посте на них сослались;
guid – уникальная ссылка на пост (shortlink);
post_type – тип записи. Например, ‘post’, ‘page’, ‘attachment’ или другой тип;
post_mime_type – MIME-тип (для вложений, имеющих тип ‘attachment’);
menu_order – рейтинг записи (влияет на порядок вывода записей).
В соответствии с вышеперечисленными свойствами, в переменной $post формируется массив элементов, который обрабатывается функцией the_post() и отдается в браузер пользователя.
Я понимаю, что новичкам будет не просто усвоить столь сложный материал, но если вспомнить, как я набирался знаний, собирая информацию по кусочкам, то сие подробное изложение, было бы для меня просто находкой. Идем дальше.
Итак, с формирование цикла мы малость разобрались, теперь давайте познакомимся с основными функциями, которые работают непосредственно внутри цикла WordPress.
seo-mayak.com
1. Получаем запись, опубликованную в промежуток между двумя датами
Проблема
Главный цикл и функция WordPress query_posts()
WordPress позволяют легко получить список записей, опубликованных в определённую неделю или месяц. К сожалению, вытащить записи, опубликованные, например, после 17 марта и до 3 мая будет не просто. Решим данную задачу.
Решение
Просто скопируйте ниже приведённый код в вашу тему в то место, где нужно выводить список записей, опубликованных между двумя датами. Обязательно поменяйте даты в коде на те, которые нужны вам.
Описание решения
Для решения задачи сначала мы создаем функцию filter_where()
, которая содержит условие SQL “WHERE
”. Затем перед запуском главного цикла функция filter_where()
будет вызываться функцией WordPress post_where()
.
В результате условие “WHERE
”, которое содержится в функции filter_where()
, добавляется в конец запроса SQL, содержащегося в функции post_where()
. Значит, главный цикл вернет только те записи, которые были опубликованы в период между двумя датами, заданными в функции filter_where()
.
2. Используем больше, чем один главный цикл на странице без дублирования записей.
Проблема
Большинство современных тем, а особенно «журнальные» темы, выводят как минимум два главных цикла на главной странице. Данный метод очень полезен, например, для раздела «выделенные записи». Но, если использование двух главных циклов на странице реализуется легко, то предотвратить вывод дублирующихся записей не так просто. Пока вы не знаете о данном методе.
Решение
1. Начнем с первого главного цикла. Ничего сложного: в примере мы просто получаем 8 последних записей с помощью параметра showposts
. Открываем файл index.php и вставляем в него следующий код:
2. Затем наступает время реализовать второй главный цикл. В нем мы получаем все записи, за исключением тех, которые уже выведены в первом цикле:
3. Сохраняем файл index.php и наслаждаемся результатом.
Описание решения
Первый цикл начинается с очень полезной функции query_posts()
, которая позволяет задавать параметры, используемые в главном цикле. Параметр showposts
дает вам возможность указать количество записей. Непосредственно перед циклом мы создаем массив PHP $ids
, в котором хранятся все ID записей, используемых в цикле.
Как и первый цикл, второй использует функцию query_posts()
с параметром post__not_in
. Данный параметр позволяет вам определить список записей, которые не нужно выводить, в форме массива PHP. Мы передаем массив $ids
в качестве данного параметра. Все записи, полученные в первом цикле, будут пропускаться во втором цикле.
3. Вставляем рекламу после первой записи
Проблема
Реклама является отличным средством монетизации вашего блога. Но для ваших рекламодателей очень важны клики ваших посетителей. Многие блогеры выводят рекламу в боковые панели, нижний или верхний колонтитул, что не всегда является лучшим местом для получения высокого рейтинга нажатий. Чтобы его повысить и сделать вашего рекламодателя счастливым, хорошей идеей будет вставить рекламный блок после первой записи.
Решение
Просто используйте следующий код вместо вашего текущего кода главного цикла. Обязательно вставьте код вашего рекламного блока в строке 6:
Описание решения
Переменная целого типа используется в качестве счетчика практически с первых дней появления программирования. Перед главным циклом мы создаем переменную $count
. Данная переменная увеличивается на 1 в каждом проходе цикла.
Затем, добавляем структуру if
(строка 5) и проверяем $count
на равенство 2. Если это так, то первая запись уже выведена, и мы можем добавить рекламный блок.
4. Получаем записи с определенными пользовательскими полями и определенными значениями
Проблема
Благодаря популярности пользовательских полей WordPress очень часто возникает необходимость вывести список записей с определенными пользовательскими полями и определенными значениями в них.
Решение
Все не так сложно, как кажется. Нужно использовать функцию query_posts()
с параметрами meta_key
и meta_value
:
Описание решения
Значение параметра meta_key
— имя нужного пользовательского поля, а значение meta_value
— нужное значение.
5. Список запланированных записей
Проблема
Благодаря опции планирования, WordPress позволяет составить расписание публикации записей и выводить их в назначенное время. Хорошей идеей является составление списка запланированных записей, чтобы ваши посетители возвращались на ваш сайт или подписывались на фид RSS.
Решение
Описание решения
Для решения используется функция query_posts()
с параметром post_status
. Параметр post_status
позволяет вам получать записи в соответствии с их статусом публикации (“published,” “draft” или, как в нашем примере, “future”). Так как используется параметр showposts=10
, то код вернет только 10 запланированных записей.
6. Выводим записи, опубликованные год назад
Проблема
Часто блоги содержат много интересной информации в старых записях. Но посетители обычно ограничиваются просмотром свежих изменений.
Решение
Если ваш сайт сравнительно «старый», то почему бы не выводить записи, которые были опубликованы год назад? Задача решается просто. Вставляем следующий код в боковую панель или в файл single.php:
Описание решения
Сначала получаем текущую дату на строке 2 с помощью функции PHP date()
. Затем получаем год с помощью вызова date('Y')
и вычитаем из него 1, что дает нам прошедший год.
Остается передать переменные $current_day
и $last_year
в параметры day
и year
функции query_posts
.
7. Используем главный цикл для создания шаблона страницы архива
Проблема
Как описывалось в предыдущей вставке кода, посетители часто не могут найти информацию, опубликованную ранее. Для облегчения поиска информации можно создать страницу, которая будет содержать все записи, когда-либо опубликованные в блоге.
Решение
Описание решения
Шаблон страницы создается добавлением в начало файла следующих строк:
В строке 8 мы создаем счетчик с помощью переменной PHP $numposts
и объекта $wpdb,
который получает результат запроса SQL к базе данных WordPress.
Затем переменная $numposts
выводится для отображения общего количества записей.
В главном цикле используется функция get_posts()
. get_posts()
простое сокращение для создания нескольких главных циклов. Мы получаем все записи из базы данных, и для каждой выводим дату, ссылку и заголовок. Просто и эффективно.
8. Создаем главный цикл с помощью объекта WP_Query
Проблема
Классический цикл WordPress, который используется в большинстве вставок кода в данном уроке, является достаточно удобным в применении. Но при задействовании нескольких главных циклов (например, в сложных “журнальных” темах), возрастает риск сбросов, смещений, неправильных тегов и других ошибок.
Решение
Нужно использовать объект WP_Query
и создать свой собственный цикл:
Описание решения
Выше приведенный код выводит пять последних записей. Вот его детальное описание:
- Строка 2, создаем новый объект
WP_Query
с именем$myPosts
. - Строка 3, выполняем запрос с параметром
showposts
для получения пяти последних записей. - Строка 5, запуск нашего собственного главного цикла.
- Строки 6 и 7, выводим информацию из записи (заголовок и ее содержание)
- Строка 8, завершение нашего главного цикла.
Если вы хотите вывести больше или меньше записей, просто поменяйте значение параметра showposts
в строке 3.
9. Выводим последние прилепленные записи
Проблема
Начиная с версии WordPress 2.7, прилепленные записи являются отличным инструментом для блогеров. Очень часто они спрашивают, как включить прилепленные записи в главный цикл.
Решение
Для вывода последних пяти прилепленных записей скопируйте следующий код в файл вашей темы. Если требуется выводить больше записей, то нужно поменять 5 на желаемое число в строке 4.
Описание решения
Сначала получаем все прилепленные записи (строка 2). Затем производим их упорядочивание, выводя вверху самые последние, с помощью функции PHP sort()
(строка 3). В строке 4, получаем 5 последних прилепленных записей. Можно изменить число.
Затем используем функцию query_posts()
для управления циклом WordPress. С помощью параметра post__in
мы проверяем факт, что возвращаемые записи содержатся в массиве. Затем мы просто устанавливаем основной цикл и выводим нужную информацию.
10. Создаем цикл изображений
Проблема
В наши дни многие блогеры выводят выдержки из заметок вместе с изображениями на главную страницу. Можно пойти еще дальше и создать оригинальную галерею, в которой будут выводиться изображения для самых последних записей. Можно решить задачу с помощью пользовательских полей. Но есть и более элегантное решение.
Решение
Для создания собственного цикла изображений сначала нужна функция PHP, которая будет вытаскивать первые изображения из каждой заметки, и возвращать их URL. Скопируйте следующий код в ваш файл functions.php. Обязательно установите изображение по умолчанию в строке 10.
После сохранения файла можно изменять главный цикл:
Описание решения
Первая часть кода является функцией catch_that_image()
, которая включается в файл functions.php. Данная функция разбирает код содержание записи с использованием глобальных переменных $post
и $posts
и регулярных выражений PHP. Если изображения не найдено (то есть, запись не имеет ни одного изображения), возвращается адрес изображения по-умолчанию. Иначе функция возвращает адрес первого изображения в заметке.
Вторая часть кода является главным циклом. В данном цикле не выводится текстовое содержание. Вместо него выводиться первое изображение заметки с помощью функции catch_that_image()
.
ruseller.com
This issue is now finally resolved by myself. Find the solution in the end of this post. Question was in short: How can i ask in my WP template, IF the whole array of have_posts contains any post from a certain category
I programmed my tag page so that the output is seperated into three styled boxes according to the categories. The loop is done three times and with an IF i sort out the categories. This is a simplified! draft of the working structure:
<div><ul> <?php if (have_posts()) : while (have_posts()) : the_post(); ?> <?php if (in_category('cat1')) : ?> <li>... <endif> </ul></div> <div><ul> <?php if (have_posts()) : while (have_posts()) : the_post(); ?> <?php if (in_category('cat2')) : ?> <li>... <endif> </ul></div> <div><ul> <?php if (have_posts()) : while (have_posts()) : the_post(); ?> <?php if (in_category('cat3')) : ?> <li>... <endif> </ul></div>
Here you can see the output: http://imlichte.net/tag/interdependenz/
Now my point is to avoid emtpy boxes when no posts are found in a category. The boxes (divs) should then not be rendered at all. For this i thought to put an IF condition for the div and ul, which are outside of the loop. So i want to actually ask this thing:
IF have_posts contains posts from a certain category
The div and ul that creates the box on the page will only be shown if the result is not zero, thus the result of suppressing empty boxes is reached.
I hope i could explain my request well enough to be understood and hope for a solution from the experts, since i am just a hobby programmer.
Thanks for help Sofian
Edit: to make it very clear, here comes the whole code that generates my category structured tag list:
<div class="box"> <h2 class="archive-title" style="text-align:center">Artikel</h2> <hr /> <ul class="postlist"> <?php if (have_posts()) : while (have_posts()) : the_post(); ?> <?php if (in_category('wissen')) : ?> <li> <?php if (has_post_thumbnail()): ?> <a href="<?php the_permalink();?>"><?php the_post_thumbnail(array(150,150));?> <?php else: ?> <div class="postlistfilling"></div> <?php endif; ?> <a class="postlisttitle" href="<?php the_permalink();?>"><?php the_title(); ?></a> <div class="pthumb"> <?php the_excerpt();?> </div> </li> <?php endif; endwhile; endif; ?> </ul> </div> <div class="box"> <h2 class="archive-title" style="text-align:center">Empfehlungen</h2> <hr /> <ul class="postlist"> <?php if (have_posts()) : while (have_posts()) : the_post(); ?> <?php if (in_category('empfehlungen')) : ?> <li> <?php if (has_post_thumbnail()): ?> <a href="<?php the_permalink();?>"><?php the_post_thumbnail(array(150,150));?> <?php else: ?> <div class="postlistfilling"></div> <?php endif; ?> <a class="postlisttitle" href="<?php the_permalink();?>"><?php the_title(); ?></a> <div class="pthumb"> <?php the_excerpt();?> </div> </li> <?php endif; endwhile; endif; ?> </ul> </div> <div class="box"> <h2 class="archive-title" style="text-align:center">Seminare</h2> <hr /> <ul class="postlist"> <?php if (have_posts()) : while (have_posts()) : the_post(); ?> <?php if (in_category('seminare')) : ?> <li> <?php if (has_post_thumbnail()): ?> <a href="<?php the_permalink();?>"><?php the_post_thumbnail(array(150,150));?> <?php else: ?> <div class="postlistfilling"></div> <?php endif; ?> <a class="postlisttitle" href="<?php the_permalink();?>"><?php the_title(); ?></a> <div class="pthumb"> <?php the_excerpt();?> </div> </li> <?php endif; endwhile; endif; ?> </ul> </div>
The solution: I run through the whole loop once just to set a variable to true if it comes across a post in that category. If there is no post, the var stays false and the Div Box around the actual loop will not be output.
<?php $categoryexisting = false; if (have_posts()) : while (have_posts()) : the_post(); if (in_category('articles')) : $categoryexisting = true; endif; endwhile; endif; ?> <?php if ($categoryexisting): ?> <div class="box"> <h2 class="archive-title" style="text-align:center">Articles</h2> <hr /> <ul class="postlist"> <?php endif; ?>
… Actual loop …
wordpress.stackexchange.com
Понимание цикла в WordPress
Лучший способ понять принцип работы цикла WordPress — это посмотреть, как он используется в теме WordPress. Поэтому, давайте изначально рассмотрим простой код, а затем и каждую его строку по отдельности, чтоб понять, какую функцию каждая из них выполняет.
Ниже приведен пример самого простого цикла WordPress. Код в используемой вами теме на WordPress для цикла может быть более длинным, но его структура ничем не отличается.
<?php if ( have_posts() ) : while ( have_posts() ) : the_post(); // // Post Content here // endwhile; // end while endif; // end if ?>
Если вы хоть немного разбираетесь в PHP, то вышеупомянутый код, скорее всего, будет вам понятен. Но, тем не менее, мы все-таки детально рассмотрим каждую строку кода на случай, если вы абсолютный новичок в этом.
Первым делом мы сообщаем серверу, что мы будем использовать PHP. Открываем функцию PHP следующим образом:
<?php
В следующей строке у нас идет привычная функция проверки «if» с функцией have_posts. Эта функция относится к логической, что означает, что она может быть как правдивой, так и ложной.
Поэтому следующая строка в коде говорит нам следующее, что «Если есть записи, которые должны выводиться – эту строку нужно использовать, если их нет — ничего не делать»:
if ( have_posts() ) :
В следующей строке используется цикл while. Он будет выполняться, если информация «правдива». То есть, если есть записи, которые должны выводиться на сайте, то эта строка должна быть в коде.
Поэтому, если на вашем сайте должны отображаться пять постов на домашней странице, функция while будет отображать данные в цикле пять раз:
while ( have_posts() ) :
Затем мы берем данные со следующей записи, используя функцию the_post. Это позволяет настроить запись и получить любую часть или информацию о посте, включая контент, дату публикации, автора записи, категорию публикации и многое другое:
the_post();
Раз уж мы упомянули нашу запись, мы можем отобразить в ней все, что хотим. Существует более тысячи доступных тэгов, которые могут быть использованы только в цикле WordPress. Например, the_title для вывода заголовка поста, the_content для отображения самого поста, the_category — для категорий и рубрик:
// // Post Content here //
После подтверждения информации, которая должна отображаться на сайте, мы закрываем цикл while:
endwhile; // end while
Затем мы закрываем функцию проверки «if»:
endif; // end if
И закрываем код PHP:
?>
Как видите, если разбить цикл по строчкам, то все становится понятным.
Примеры цикла
В WordPress Codex есть шаблон маленького кода index.php. В коде ниже видно, что в шаблоне index.php упоминается шапка, цикл WordPress, сайдбар и футер:
<?php get_header(); if (have_posts()) : while (have_posts()) : the_post(); the_content(); endwhile; endif; get_sidebar(); get_footer(); ?>
Код для цикла WordPress выглядит немного иначе в большинстве тем WordPress, потому что и отображаемая информация немного другая. Самый лучший способ понять, как цикл работает на практике – это изучить цикл WordPress в разных темах оформления.
Ниже приведен пример кода, который используется для цикла в шаблоне нынешней стандартной темы на WordPress — Twenty Fourteen. Как вы видите, в этой теме используются разные шаблоны для контента, в зависимости от типа поста. Например, стандартный пост будет выводить разную информацию из видео-постов и цитат-постов.
Навигационные линки выводятся после последнего поста, и сообщение отображается для посетителей в случае, если пост был не найден (это осуществляется с помощью шаблона content-none.php).
<?php if ( have_posts() ) : // Start the Loop. while ( have_posts() ) : the_post(); /* * Include the post format-specific template for the content. If you want to * use this in a child theme, then include a file called called content-___.php * (where ___ is the post format) and that will be used instead. */ get_template_part( 'content', get_post_format() ); endwhile; // Previous/next post navigation. twentyfourteen_paging_nav(); else : // If no content, include the "No posts found" template. get_template_part( 'content', 'none' ); endif; ?>
Цикл легче использовать в темах TwentyFourteen и Twenty Thirteen, потому что код для вывода контента и мета-информации находится в разных шаблонах. Более практично структурировать код для тем, которые поддерживают форматы постов.
Если проанализировать популярную тему Twenty Twelve, то можно заметить, что цикл требует наличия других файлов шаблона. Но большинство кода остается в шаблоне цикла — index.php.
<?php if ( have_posts() ) : ?> <?php /* Start the Loop */ ?> <?php while ( have_posts() ) : the_post(); ?> <?php get_template_part( 'content', get_post_format() ); ?> <?php endwhile; ?> <?php twentytwelve_content_nav( 'nav-below' ); ?> <?php else : ?> <article id="post-0" class="post no-results not-found"> <?php if ( current_user_can( 'edit_posts' ) ) : // Show a different message to a logged-in user who can add posts. ?> <header class="entry-header"> <h1 class="entry-title"><?php _e( 'No posts to display', 'twentytwelve' ); ?></h1> </header> <div class="entry-content"> <p><?php printf( __( 'Ready to publish your first post? <a href="%s">Get started here</a>.', 'twentytwelve' ), admin_url( 'post-new.php' ) ); ?></p> </div><!-- .entry-content --> <?php else : // Show the default message to everyone else. ?> <header class="entry-header"> <h1 class="entry-title"><?php _e( 'Nothing Found', 'twentytwelve' ); ?></h1> </header> <div class="entry-content"> <p><?php _e( 'Apologies, but no results were found. Perhaps searching will help find a related post.', 'twentytwelve' ); ?></p> <?php get_search_form(); ?> </div><!-- .entry-content --> <?php endif; // end current_user_can() check ?> </article><!-- #post-0 --> <?php endif; // end have_posts() check ?>
Лучше всего запомнить принцип кодирования «Не повторяйте самостоятельно!». Сокращая количество повторений, вы можете создать более компактные темы, и вам будет легче их изменять.
hostenko.com
Настраиваем query_posts()
Типичный цикл по умолчанию выглядит вот так:
<?php // The WordPress Loop if (have_posts()) : while (have_posts()) : the_post(); ... endwhile; else: ... endif; ?>
Информация, отображаемая в цикле, зависит от огромного количества факторов, включая запрашиваемый урл и соответствующий шаблон, генерирующий страницу. Например, когда кто-то посещает главную страницу сайта, исходный цикл выводит записи из всех категорий в количестве, заданном в админке.
Но что, если мы хотим вместо отображения записей из всех категорий исключить содержимое определенной, чтобы вывести их в отдельном месте страницы. Это идеальная задача для query_posts(), которая легко с ней справится:
<?php query_posts('cat=-9'); // исключаем категорию с ID = 9 if (have_posts()) : while (have_posts()) : the_post(); ... endwhile; else: ... endif; ?>
Но нужно учитывать необходимость внести некоторые модификации в стандартный код вызова: убедиться, что запрос был сделан правильно и сбросить запрос в состояние по умолчанию сразу после выполнения.
<?php global $query_string; $posts = query_posts($query_string.'&cat=-9'); if (have_posts()) : while (have_posts()) : the_post(); ... endwhile; else: ... endif; wp_reset_query(); ?>
Тег wp_reset_query восстанавливает оригинальный запрос query_posts и используется при применении в шаблонах нескольких последовательных циклов.
Используя такой шаблон можно легко вносить нужные правки в запрос, например, сделав такой
$posts = query_posts($query_string.'&cat=-7,-8,-9&posts_per_page=3&order=ASC');
что значит вывести 3 записи, исключив 7,8,9 категории и отсортировать записи по алфавиту.
Ключ к успешному использованию query_posts заключается в сохранении оригинального формата запроса с помощью $query_string переменных. Будучи однажды подключенными, можно добавить столько параметров, сколько нужно (подробнее тут https://codex.wordpress.org/Function_Reference/WP_Query#Parameters ).
Этот способ хорош, но не лишен недостатков. query_posts использует дополнительные запросы к базе данных и может повлиять на работоспособность других условных тегов, таких как is_page() и is_ single(). Поэтому рекомендуется не использовать этот способ, хотя он и работоспособен, а заменить его на WP_Query с которым точно проблем не будет.
Настраиваем WP_Query
Для полного контроля над любым количеством циклов, WP_Query – самый лучший способ. Если нужно модифицировать дефолтовый цикл, то это выглядит очень похоже на query_posts:
<?php // The WordPress Loop - customized with WP_Query $custom_query = new WP_Query('cat=-9'); while($custom_query->have_posts()) : $custom_query->the_post(); ... endwhile; wp_reset_postdata(); // reset the query ?>
Применяются те же параметры, что и для query_posts, поэтому для модификации числа постов, используемыхисключаемых рубрик, порядка сортировки делается все то же самое.
$custom_query = new WP_Query('cat=-7,-8,-9'); // исключить категории $custom_query = new WP_Query('posts_per_page=3'); // ограничить количество $custom_query = new WP_Query('order=ASC'); // порядок сортировки
А также любые нужные комбинации
$custom_query = new WP_Query('cat=-7,-8,-9&posts_per_page=3&order=ASC');
В дополнение к сферам применения, мы также можем создавать и настраивать дополнительные множественные циклы, вот типовой пример:
<?php // Loop 1 $first_query = new WP_Query('cat=-1'); // исключили категорию 1 while($first_query->have_posts()) : $first_query->the_post(); ... endwhile; wp_reset_postdata(); // reset the query // Loop 2 $second_query = new WP_Query('cat=-2'); // исключили категорию 2 while($second_query->have_posts()) : $second_query->the_post(); ... endwhile; wp_reset_postdata(); // reset the query // Loop 3 $third_query = new WP_Query('cat=-3'); // исключили категорию 3 while($third_query->have_posts()) : $third_query->the_post(); ... endwhile; wp_reset_postdata(); // reset the query ?>
Каждый из этих циклов может быть размещен в любом месте шаблона, не нужно вписывать их последовательно. Например, первый цикл может быть в сайдбаре, второй в футере и т.д.. И каждый выводит свои собственные списки записей, в соответствии с параметрами.
При желании можно комбинировать вместе 3 разных способа query_posts , get_posts и WP_Query в множественных циклах. А в версии вордпресса 3.3 появилась функция is_main_query, позволяющая модифицировать только главные объекты в WP_Query, подробнее на https://codex.wordpress .org/Functi on_Reference/i s_main_query
Настраиваем get_posts
Самый легкий и безопасный способ создать множественные циклы, это get_posts. Просто добавляете в нужном месте шаблона
<?php global $post; $args = array('category' => -9); // исключили категорию $custom_posts = get_posts($args); foreach($custom_posts as $post) : setup_postdata($post); ... endforeach; ?>
Этот код создает циклы всех постов за исключением указанной рубрики. Конечно, исключение рубрик не единственный способ применения циклов. Опять же, используя различные параметры можно получить любой нужный результат.
Но есть один момент, get_posts требует передачи параметров в виде массива, т.е.
$args = array('category'=>-7,-8,-9, 'numberposts'=>3, 'order'=>'ASC');
Также обратите внимание, что мы используем numberposts вместо posts_per_page для ограничения количества записей. В соответствии с кодексом WP параметр posts_per_page все же должен работать, но если нет — то замените его на numberposts.
Стандартный цикл, а также модифицированные с помощью query_posts и WP_Query поддерживают постраничную навигацию, используя next_posts_link и previous_posts_link, а вот get_posts не поддерживает ее, отображая статический список постов, соответствующих выбранному критерию и все.
Подытожим:
- Чтобы модифицировать стандартный цикл, используйте query_posts()
- Чтобы модифицировать иили создать множественные циклы, используйте WP_Query()
- Чтобы создать статический, дополнительный цикл, используйте get_posts()
Цикл не беспокоится о разметке
Это правда. Можно использовать все, что нам в голову придет. Вот пример типового цикла, закрытого в тег <div>
<?php if (have_posts()) : while (have_posts()) : the_post(); ?> <div <?php post_class(); ?> id="post-<?php the_ID(); ?>"> <h2><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></h2> <p class="meta">Posted on <?php the_time('F jS, Y'); ?></p> <?php the_content('Read More'); ?> <p><?php the_tags('Tags: ', ', ', '<br />'); ?> Posted in <?php the_category(', '); ?></p> </div> <?php endwhile; ?> <div class="next-posts"><?php next_posts_link('« Older Entries') ?></div> <div class="prev-posts"><?php previous_posts_link('Newer Entries »') ?></div> <?php endif; ?>
И вот точно такой же цикл, оформленный в стиле нумерованного списка
<?php if (have_posts()) : ?> <ol> <?php while (have_posts()) : the_post(); ?> <li <?php post_class(); ?> id="post-<?php the_ID(); ?>"> <h2><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></h2> <p class="meta">Posted on <?php the_time('F jS, Y'); ?></p> <?php the_content('Read More'); ?> <p><?php the_tags('Tags: ', ', ', '<br />'); ?> Posted in <?php the_category(', '); ?></p> </li> <?php endwhile; ?> </ol> <?php endif; ?>
А вот пример списка определений
<?php if (have_posts()) : ?> <dl> <?php while (have_posts()) : the_post(); ?> <dt <?php post_class(); ?> id="post-<?php the_ID(); ?>"> <a href="<?php the_permalink(); ?>"><?php the_title(); ?></a> </dt> <dd> <?php the_excerpt(); ?> </dd> <?php endwhile; ?> </dl> <?php endif; ?>
Обратите внимание, что не только разметка отличается в этих трех примерах, но и используемые функции разные. Например, в третьем случае использовался the_excerpt() для вывода цитат вместо контента.
По умолчанию the_excerpt() выводит первые 55 слов записи, если не задано поле цитата записи. Поэтому для постов длиной меньше 55 слов будет выведено полное содержание, более 55 слов – только часть.
Мораль такая — циклы WordPress очень удобная, гибкая и мощная штука — вы можете как угодно применять их и где угодно размещать.
Мощь WP_Query
Много магии осуществляется с помощью функции WP_Query, которая определенно стоит того, чтобы с ней разобраться. Как мы видели ранее, каждое выполнение цикла основано на запросе, соответствующем типу загруженной страницы, настройкам сайта и т.п.. Этот запрос по умолчанию может быть изменен и заменен с помощью WP_Query.
В большинстве случаев вы можете сохранить оригинальный запрос и модифицировать только некоторые параметры, например вот так
<?php $custom_query = new WP_Query('cat=10&showposts=2&paged='.$paged); while($custom_query->have_posts()) : $custom_query->the_post(); ... endwhile; next_posts_link('« Старые записи'); previous_posts_link('Новые записи »'); wp_reset_postdata(); // сбрасываем запрос ?>
Как и в предыдущих примерах, изменением параметров в новом WP_Query вы легко настраиваете вывод любого набора записей. Давайте подробно разберем наиболее типичные способы применения.
Отображение разного количества записей
Глобальная настройка количества отображаемых постов настраивается в админке, но мы можем менять это значение прямо в цикле. Например, так мы задаем свое значение вместо значения по умолчанию.
$custom_query = new WP_Query('showposts=6&paged='.$paged);
Таким образом мы ограничим количество выводимых постов шестью, вместо десяти (значение по умолчанию). Чтобы вывести абсолютно все записи, нужно указать параметр равный «-1».
Исключаем некоторые категории
Одна из самых популярных задач – исключение записей определенной категории на главной странице сайта. Например, у вас есть несколько записей про хомячков, но вы хотели бы убрать их с главной страницы сайта. Этот контент остается в базе данных, отображается в своей рубрике и RSS ленте, но только не на главной. Есть множество способов сделать это, но мы применим самое простое из решений…да, это WP_Query class:
$custom_query = new WP_Query('cat=-3&paged='.$paged); // нет хомячкам
В общих случаях, знак минус означает исключить данный параметр.
Поэтому мы исключили третью рубрику (про хомячков).
Другие возможности исключить содержимое этой рубрики — использовать php функцию continue и пропускать записи определенной категории, скрывать контент с помощью css и javascript, править файлы ядра вордпресс и использовать плагины. Согласитесь, WP_Query однозначно лучше.
Изменяем порядок сортировки
WordPress относится к приложениям LIFO типа — last in, first out, т.е. последний пришел, первый вышел. Что означает, что мы видим сначала свеже опубликованные записи, а старички спрятаны глубоко в недрах навигации. Это рационально, т.к. большинство блоговых сайтов стремится первым показать самый свежий контент. Это дает людям смысл периодически возвращаться на сайт, т.к. они смогут найти что-то новенькое прямо на первой странице сайта. Но это не идеальный вариант для каждого типа сайтов.
Допустим, вы используете вордпресс для того, чтобы публиковать свой роман. Это означает, что вы писали и публиковали его хронологически, главу за главой. Поэтому, когда посетители приходят на ваш сайт, вы хотите показать им сначала главу Один, но она является фактически самой старой записью, поэтому вместо этого они увидят самую последнюю опубликованную главу. Но нет проблем, всего навсего изменим порядок сортировки:
$custom_query = new WP_Query('orderby=date&order=ASC&paged='.$paged);
Покажем специфические страницы, встраивая страницу в страницу
Другой интересный и полезный цикл, это использовать новый WP_Query class для отображения только одной определенной страницы. Это может быть полезно из разных соображений, например, для встраивания одной страницы в другую. Вот пример запроса, когда содержимое страницы About встраивается в другую страницу:
$custom_query = new WP_Query('pagename=about&paged='.$paged);
Обратите внимание, что в pagename нужно использовать не реальное название страницы, а ее слаг.
Пример использования множественных циклов
Ничто не заставляет вас ограничиваться только одним циклом. Вы можете использовать ровно столько, сколько вам нужно. Фактически, это в целом нормально иметь множественные циклы в шаблоне. Простым примером будет главная страница, которая показывает полное содержание трех новых публикаций. А затем в сайдбаре, в втором цикле показывает выдержки из остальных семи публикаций. И все работает чудесным образом.
А вот пример более сложной реализации. Допустим, у нас есть милый четырех колоночный шаблон. В левом сайдбаре мы покажем выдержки из одной категории. Затем в главной центральной части, разбитой на две колонки, мы покажем 10 последних записей по 5 в каждой. И затем в правом сайдбаре, мы покажем еще 10 записей, идущих после первых десяти.
Таким образом у нас получается 4 цикла