Я вчера считал @nacin Вы не знаете Запроса и был отправлен вниз что-то вроде кроличьей норы запросов. Прежде вчера, я (неправильно) использовал query_posts()
для всех моих запросов потребностей. Теперь я немного более мудр об использовании WP_Query()
, но все еще имейте некоторые серые области.
Что я думаю, что знаю наверняка:
Если я делаю дополнительные циклы где-нибудь на странице — на боковой панели, на нижнем колонтитуле, каком-либо виде "связанных сообщений", и т.д. — я хочу использовать WP_Query()
. Я могу неоднократно использовать это на единственной странице без любого вреда. (право?).
Что я не знаю наверняка
pre_get_posts
по сравнению с. WP_Query()
? Если я использую pre_get_posts
для всего теперь? if have_posts : while have_posts : the_post
часть и запись мое собственное WP_Query()
? Или сделайте я изменяю выходное использование pre_get_posts
в моем functions.php файле? tl; доктор
tl; доктор постановляет, что я хотел бы потянуть из этого:
query_posts
большеWP_Query()
Спасибо за любую мудрость
Terry
PS: Я видел и читал: Когда необходимо использовать WP_Query по сравнению с query_posts () по сравнению с get_posts ()? Который добавляет другой размер — get_posts
. Но не имеет дело с pre_get_posts
вообще.
Вы правы сказать:
Никогда не используйте
query_posts
больше
pre_get_posts
фильтр, для изменения любого запроса. Это чаще всего используется для изменения только 'основного запроса':
add_action('pre_get_posts','wpse50761_alter_query');
function wpse50761_alter_query($query){
if( $query->is_main_query() ){
//Do something to main query
}
}
(Я также проверил бы это is_admin()
возвращает false - хотя это может быть избыточно.). Основной запрос появляется в Ваших шаблонах как:
if( have_posts() ):
while( have_posts() ): the_post();
//The loop
endwhile;
endif;
Если Вы когда-нибудь чувствуете потребность отредактировать этот цикл - использование pre_get_posts
. т.е. Если Вы испытываете желание использовать query_posts()
- использовать pre_get_posts
вместо этого.
Основной запрос является важным экземпляром a WP_Query object
. WordPress использует его для решения, который шаблон использовать, например, и любые аргументы передал в URL (например, разбиение на страницы) все направлены в тот экземпляр WP_Query
объект.
Для вторичных циклов (например, на боковых панелях, или 'связанных сообщениях' списки) Вы захотите создать свой собственный отдельный экземпляр WP_Query
объект. Например.
$my_secondary_loop = new WP_Query(...);
if( $my_secondary_loop->have_posts() ):
while( $my_secondary_loop->have_posts() ): $my_secondary_loop->the_post();
//The secondary loop
endwhile;
endif;
wp_reset_postdata();
Заметить wp_reset_postdata();
- это вызвано тем, что вторичный цикл переопределит глобальное $post
переменная, которая определяет 'текущее сообщение'. Это по существу сбрасывает это к $post
мы идем.
Это - по существу обертка для отдельного экземпляра a WP_Query
объект. Это возвращает массив объектов сообщения. Методы, используемые в цикле выше, больше не доступны Вам. Это не 'Цикл', просто массив объекта сообщения.
<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 endforeach; wp_reset_postdata(); ?>
</ul>
pre_get_posts
изменить Ваш основной запрос. Используйте отдельное WP_Query
объект (метод 2) для вторичных циклов на шаблонных страницах.pre_get_posts
. Существует два различных контекста для циклов:
Проблема с query_posts()
это, это - вторичный цикл, который пытается быть основным и терпит полный провал. Таким образом забудьте, что это существует.
query_posts()
pre_get_posts
фильтр с $query->is_main_query()
проверитьrequest
фильтр (немного слишком грубо так выше лучше),Использовать new WP_Query
или get_posts()
то, которые являются в значительной степени взаимозаменяемыми (последний является тонкой оберткой для формирователя).
Использовать wp_reset_query()
если Вы использовали query_posts()
или смешанный с глобальным $wp_query
непосредственно - таким образом, Вы почти никогда не должны будете.
Использовать wp_reset_postdata()
если Вы использовали the_post()
или setup_postdata()
или смешанный с глобальным $post
и должен восстановить начальное положение постсвязанных дел.
Существуют законные сценарии для использования query_posts($query)
, например:
Вы хотите отобразить список сообщений или сообщений пользовательского типа сообщения на странице (использующий шаблон страницы)
Вы хотите сделать разбиение на страницы тех сообщений работой
Теперь, почему Вы хотели бы отобразить его на странице вместо того, чтобы использовать шаблон архива?
Это более интуитивно для администратора (Ваш клиент?) - они видят страницу на 'Страницах'
Это лучше для добавления его к меню (без страницы, они должны были бы добавить URL непосредственно),
Если Вы хотите отобразить дополнительное содержание (текст, миниатюра сообщения или какое-либо пользовательское meta содержание) на шаблоне, можно легко получить его от страницы (и все это имеет больше смысла для клиента также). Посмотрите, использовали ли Вы шаблон архива, Вам или были бы нужны к hardcode дополнительное содержание или использование, например, опции темы/плагина (который делает это менее интуитивным для клиента),
Вот упрощенный пример кода (который был бы на Вашем шаблоне страницы - например, page-page-of-posts.php):
/**
* Template Name: Page of Posts
*/
while(have_posts()) { // original main loop - page content
the_post();
the_title(); // title of the page
the_content(); // content of the page
// etc...
}
// now we display list of our custom-post-type posts
// first obtain pagination parametres
$paged = 1;
if(get_query_var('paged')) {
$paged = get_query_var('paged');
} elseif(get_query_var('page')) {
$paged = get_query_var('page');
}
// query posts and replace the main query (page) with this one (so the pagination works)
query_posts(array('post_type' => 'my_post_type', 'post_status' => 'publish', 'paged' => $paged));
// pagination
next_posts_link();
previous_posts_link();
// loop
while(have_posts()) {
the_post();
the_title(); // your custom-post-type post's title
the_content(); // // your custom-post-type post's content
}
wp_reset_query(); // sets the main query (global $wp_query) to the original page query (it obtains it from global $wp_the_query variable) and resets the post data
// So, now we can display the page-related content again (if we wish so)
while(have_posts()) { // original main loop - page content
the_post();
the_title(); // title of the page
the_content(); // content of the page
// etc...
}
Теперь, чтобы быть совершенно ясными, мы могли избегать использования query_posts()
здесь также и использование WP_Query
вместо этого - как так:
// ...
global $wp_query;
$wp_query = new WP_Query(array('your query vars here')); // sets the new custom query as a main query
// your custom-post-type loop here
wp_reset_query();
// ...
Но, почему мы сделали бы это, когда мы имеем такую миленькую функцию в наличии для него?
get_posts()
более эффективно. – Stephen Harris 25.08.2012, 21:00get_posts()
для основного запроса - для вторичных запросов. – Stephen Harris 27.08.2012, 01:42