В этой статье:
Цикл WordPress и дополнительные циклы
функции have_posts(), the_post(), rewind_posts(), query_posts(), wp_reset_postdata()
объект WP_Query
глобальные массивы $wp_query $posts
Цикл WordPress
Цикл WordPress имеет такой вид:
// если есть записи
<?php if (have_posts()) : ?>
// пока есть записи, извлекать по одной записи
<?php while (have_posts()) : the_post(); ?>
<!--обработка ... -->
<?php endwhile; ?>
<?php endif; ?>
Функции have_posts() и the_post() работают с глобальным (global) объектом $wp_query, который вызывается в header блога. При этом формируется и выполняется запрос к базе данных (БД), возвращающий массив записей блога, который затем хранится в этом объекте, а также в глобальном массиве $posts (для обеспечения обратной совместимости).
have_posts() (вызывает $wp_query->have_posts()) проверяет, есть ли еще записи в массиве записей
the_post() (вызывает $wp_query->the_post()) заполняет глобальную переменную $post и все глобальные данные, связанные с текущей извлекаемой записью, и увеличивает счетчик цикла.
Несколько циклов на одной странице
Для того чтобы в случае необходимости выполнить цикл еще раз, нужно "отмотать все назад" с помощью функции
<?php rewind_posts(); ?>
Или можно использовать функцию query_posts(), которая выполняет новый запрос, создает новый массив записей и отматывает назад счетчик цикла.
Если нужно сохранить (не перезаписывать) результаты исходного запроса, можно создать копию $wp_query или создать новый объект запроса.
Использование функции query_posts()
// 10 последних записей из категории cat1
<?php query_posts('category_name=cat1&posts_per_page=10'); ?>
<?php while (have_posts()) : the_post(); ?>
...
<?php endwhile;?>
Внимание! Чтобы не нарушалась "пагинация" - работа ссылок "Предыдущие записи" - для функции query_posts() необходимо использовать параметр paged:
$page_num = $paged;
if ($pagenum='') $pagenum =1;
query_posts('showposts=4&paged='.$page_num=3');
Рекомендации автора плагина PageNavi (wp_pagenavi ):
Плагин wp_pagenavi создает страничную навигацию (страница 1, страница 2 и т.д.) для страниц записей, но навигация не будет работать, если в теме используется вызов функции query_posts() вида
query_posts('cat=8');
или
query_posts( array( 'cat' => 8 ) );
Должно быть так:
query_posts( array( 'cat' => 8, 'paged' => get_query_var('paged') ) );
если это не сработает, попробуйте передать переменную page:
query_posts( array( 'cat' => 8, 'paged' => get_query_var('page') ) );
(http://scribu.net/wordpress/wp-pagenavi/right-way-to-use-query_posts.html)
Внимание! Использование функции query_posts() означает изменение глобального массива и не рекомендуется. Предпочтительнее создание нового объекта WP_Query или применение фильтра pre_get_posts .
Создание нового объекта WP_Query
Если нужно сохранить (не перезаписывать) результаты исходного запроса, можно создать копию $wp_query или создать новый объект запроса. Вот, например, два цикла: сначала вывод одной записи из рубрики featured и затем вывод последних добавленных записей, исключая первую выведенную запись
<?php $my_query = new WP_Query('category_name=featured&posts_per_page=1');
while ($my_query->have_posts()) : $my_query->the_post();
$do_not_duplicate = $post->ID; ?>
...
<?php endwhile; ?>
...
<?php if (have_posts()) : while (have_posts()) : the_post();
if( $post->ID == $do_not_duplicate ) continue;?>
...
<?php endwhile; endif; ?>
Или вывод нескольких записей в первом цикле:
<?php $my_query = new WP_Query('category_name=featured&posts_per_page=3');
while ($my_query->have_posts()) : $my_query->the_post();
$do_not_duplicate[] = $post->ID ?> // массив id записей
...
<?php endwhile; ?>
...
<?php if (have_posts()) : while (have_posts()) : the_post();
if (in_array($post->ID, $do_not_duplicate)) continue;
?>
...
<?php endwhile; endif; ?>
Можно пойти и другим путем - сразу исключить из запроса записи из массива:
<?php query_posts(array('post__not_in'=>$do_not_duplicate));
if (have_posts()) : while (have_posts()) : the_post();
?>
Вложенные циклы
Цикл внутри основного (по окончании внутреннего цикла продолжается внешний цикл ):
$my_query = new WP_Query( "cat=3" );
if ( $my_query->have_posts() ) {
while ( $my_query->have_posts() ) {
$my_query->the_post();
the_content();
}
}
// Установка некоторых глобальных переменных:
wp_reset_postdata();
Изменение количества записей только на главной странице - query_posts
Новый запрос с помощью функции query_posts():
<?php
if (is_front_page()) {
$page_num = $paged;
if ($pagenum='') $pagenum =1;
query_posts('showposts=4&paged='.$page_num);
}
?>
<?php //while ( have_posts() ) : the_post(); ?>
На главной будут выводиться 4 записи, а на страницах рубрик, меток и т.д. - в соответствии с настройкой, заданной в
Параметры - Чтение - На страницах блога отображать не более 10 записей
Изменение запросов с помощью фильтра pre_get_posts
Фильтр pre_get_posts применяется после формирования запроса но до его выполнения, т.е. его использование не создает дополнительной нагрузки!
Исключение рубрик на главной странице
Если нужно не показывать на главной / домашней странице записи блога из некоторых рубрик (например, с id= '1' и '67'), используйте в плагине или добавьте в файл functions.php код:
function exclude_category( $query ) {
if ( $query->is_home() && $query->is_main_query() ) {
$query->set( 'cat', '-1,-67' );
}
}
add_action( 'pre_get_posts', 'exclude_category' );
Изменение количества записей для разных случаев
В WordPress есть одна глобальная настройка для количества записей на главной странице блога и на страницах рубрик, архивов по месяцам и т.д. (Параметры - Чтение). Применяя фильтр, можно избирательно изменять эту и другие настройки, например, для главной страницы или страницы определенной рубрики.
Пример изменения параметра 'posts_per_page' (записей на странице):
function change_posts_per_page( $query ) {
// изменять не в админке и только главный запрос
if ( is_admin() || ! $query->is_main_query() )
return;
if ( is_home() ) {
// На главной показывать только 1 запись
$query->set( 'posts_per_page', 1 );
return;
}
if ( is_post_type_archive( 'movie' ) ) {
// 50 записей в архиве произвольноготипа'movie'
$query->set( 'posts_per_page', 50 );
return;
}
}
add_action( 'pre_get_posts', 'change_posts_per_page', 1 );
Дополнительно: в разделе "Функции WordPress" также:
- URL и другая информация о блоге
- Функции, подключающие шаблоны
- wp_list_categories
- Вход в систему
- wp_list_pages - список ссылок на страницы
- Функции даты и времени в WordPress
- wp_link_pages - ссылки на страницы статьи с nextpage
- Шорткод [gallery]
- Функции для работы с метками
- Функции action, filter, plugin и локализация
- Произвольные поля (custom fields)
- Функции для работы с типами данных (записей)
- Функция wp_insert_post - обновление/добавление записи заданного типа
- Административные меню
- Функции для работы с пользователями и ролями пользователей
Спасибо за подробное объяснение.
А не знаете как изменить обрамление ссылки тега the_title(), который вызывает ссылку на запись (more), а то надо убрать которые обрамляет эту ссылку.
Обрамление ссылки READ MORE (читать далее)?
Стиль текста ссылки MORE (или READ MORE) задает класс стилей more-link
Так что изменяй .more-link в файле темы style.css
the_title() выводит заголовок статьи
Есть следующая задача: реализовать возможность изменения вида вывода для каждого пользователя. Используется два варианта вывода:
1. Полный (изобрадение, описание, ссылка)
2. Компактный (Миниатюра, ссылка)
В шаблоне используется условие и два цикла.
Первый выводит 5 полных записей(как указано в настройках)
Как сделать чтобы один выводил не 5, а любое другое количество постов ??
---выводит 5 полных записей(как указано в настройках)---
5 задано в каких настройках?
Параметры - Чтение -
На страницах блога отображать не более 5 записей?
Да. В настройках: Параметры - Чтение - На страницах блога отображать не более 5 записей.
Для первого цикла это норма. Однако как сделать, чтобы второй выводил не 5, а скажем 30 ?
Как показано в статье, перед выводом цикла можно выполнить новый запрос и в нем задать количество постов на странице:
query_posts(...&posts_per_page=30&...)
Да, это то, что мне нужно. Однако возникла ещё одна проблема: не работает сортировка по страницам и рубрикам. Вот мой код:
dstyle) {print ''; query_posts('posts_per_page=32');
while ( have_posts() ) : the_post(); get_template_part( 'content', 'all' ); endwhile;
print ''; }
else {
while ( have_posts() ) : the_post(); get_template_part( 'content', get_post_format() ); endwhile; }
getpagenavi(); ?>
Результатом его работы ВСЕГДА являются 32 последние записи, независимо от выбранной рубрики или страницы пейджера...
Посмотрите, в статью добавлены рекомендации по использованию функции query_posts: для query_posts нужно задавать параметр paged.
Или вместо использования query_posts создайте новый объект запроса WP_Query.
ПРОСТО АСТРАНОМИЧЕСКОЕ ВАМ СПАСИБО!!
Всё получилось именно так, как мне нужно ))
умения на главный страниц отображается записа 2 записа,я из меню устанавливаю 10 записа но не изменяется,Пожалуйста подскажите какой файл php?? отвечает за это
Спасибо за разъяснения по циклу query_posts(). Много перерыл по теме WP_Query(), но хотя советов много нашёл - в моём случае помогло только то, чем вы поделились со всеми для решения проблем в условиях вывода сортированных рубрик на главной странице и сохранения работоспособной пагинации при использовании плагина PageNavi (wp_pagenavi ).
У меня получился вот такой рабочий код на одном из проектов:
4,'paged' => get_query_var('paged'))); ?>
... вывод контента ...
... и всё заработало без попадания в предыдущие записи постов из других рубрик и ошибок при формировании пагинации.
PS: Важно! Советую более КРУПНО прописать важность применения wp_reset_query() после использования цикла query_posts(), ибо многие не акцентируют внимание на "убийстве" этим циклом $wp_query и необходимости возврата основного запроса данной функцией, ведь это ведёт к подобным заморочкам, которые я решил при вашей помощи )))
Удачи!
Сорри, код не получился(((
query_posts(array('cat'=>n,'paged' => get_query_var('paged')));
if (have_posts()) : while (have_posts()) : the_post();
... вывод контента ...
endwhile;
wp_pagenavi();
wp_reset_query();
Добрый день!
У меня тема в которой уже встроен этот слайдер.
Мне бы хотелось узнать : как переделать, чтобы загружались не записи блога, а статьи (простые статьи с картинками? Или на крайний случай - из определенной папки только картинки?
Очень функциональный слайдер! Респект!