Я прочитал @ nacin's. Вы не знаете Query вчера, и меня отправили в какую-то дырку с кроликом. До вчерашнего дня я (неправильно) использовал query_posts()
для всех моих запросов. Теперь я немного мудрее в использовании WP_Query()
, но у меня все еще есть серые области.
То, что я думаю, я знаю наверняка:
Если я создаю дополнительные циклы в любом месте на странице - на боковой панели, в нижнем колонтитуле, любых видах «связанных сообщений» и т. Д. - я хочу использовать WP_Query()
. Я могу использовать это неоднократно на одной странице без какого-либо вреда. (правильно?).
Что я точно не знаю
- Когда я использую @ nacin в
pre_get_posts
VS.WP_Query()
? Должен ли я использоватьpre_get_posts
для всего сейчас? - Когда я хочу изменить цикл на странице шаблона, скажем, хочу изменить страницу архива таксономии, удалить
if have_posts : while have_posts : the_post
часть и написать свою собственнуюWP_Query()
? Или мне изменить вывод, используяpre_get_posts
в моем файле functions.php?
ТЛ; др
Правила tl; dr, которые я хотел бы извлечь из этого:
- Никогда не используйте
query_posts
больше - При выполнении нескольких запросов на одной странице используйте
WP_Query()
- При изменении цикла сделайте это __________________.
Спасибо за любую мудрость
Терри
PS: я видел и читал: когда вы должны использовать WP_Query против query_posts () против get_posts ()? Который добавляет другое измерение - get_posts
. Но не имеет дело pre_get_posts
вообще.
Ответы:
Вы правы сказать:
pre_get_posts
pre_get_posts
это фильтр, для изменения любого запроса. Чаще всего он используется для изменения только «основного запроса»:(Я бы также проверил, что
is_admin()
возвращает false - хотя это может быть избыточно.). Основной запрос появляется в ваших шаблонах как:Если вам когда-нибудь понадобится редактировать этот цикл - используйте
pre_get_posts
. т.е. если вы склонны использоватьquery_posts()
- используйтеpre_get_posts
вместо этого.WP_Query
Основной запрос является важным примером
WP_Query object
. WordPress использует его, чтобы решить, например, какой шаблон использовать, и все аргументы, передаваемые в URL (например, разбиение на страницы), все направляются в этот экземплярWP_Query
объекта.Для вторичных циклов (например, в боковых панелях или списках «связанных сообщений») вы захотите создать свой отдельный экземпляр
WP_Query
объекта. НапримерОбратите внимание
wp_reset_postdata();
- это потому, что вторичный цикл переопределит глобальную$post
переменную, которая идентифицирует «текущий пост». Это по существу сбрасывает это на$post
мы.get_posts ()
По сути, это оболочка для отдельного экземпляра
WP_Query
объекта. Это возвращает массив почтовых объектов. Методы, использованные в приведенном выше цикле, больше не доступны для вас. Это не «цикл», просто массив объектов post.В ответ на ваши вопросы
pre_get_posts
чтобы изменить ваш основной запрос. Используйте отдельныйWP_Query
объект (метод 2) для вторичных циклов на страницах шаблона.pre_get_posts
.источник
get_posts()
это более эффективно.get_posts()
для основного запроса - для вторичных запросов.Есть два разных контекста для циклов:
Проблема в
query_posts()
том, что это вторичный цикл, который пытается быть основным и с треском проваливается. Таким образом, забудьте, что он существует.Чтобы изменить основной цикл
query_posts()
pre_get_posts
фильтр с$query->is_main_query()
проверкойrequest
фильтр (немного слишком грубый, так что выше лучше)Запустить вторичный цикл
Используйте
new WP_Query
илиget_posts()
которые в значительной степени взаимозаменяемы (последний является тонкой оберткой для первого).Помыть
Используйте,
wp_reset_query()
если вы использовалиquery_posts()
или перепутали с global$wp_query
напрямую - так вам почти никогда не понадобится.Используйте,
wp_reset_postdata()
если вы использовалиthe_post()
илиsetup_postdata()
или перепутали с глобальным$post
и нужно восстановить начальное состояние пост-связанных вещей.источник
wp_reset_postdata()
Существуют законные сценарии использования
query_posts($query)
, например:Вы хотите отобразить список сообщений или сообщений пользовательского типа на странице (используя шаблон страницы)
Вы хотите, чтобы эти посты работали
Теперь, почему вы хотите отобразить его на странице вместо использования шаблона архива?
Это более интуитивно понятно для администратора (вашего клиента?) - они могут видеть страницу в «Страницах»
Это лучше для добавления его в меню (без страницы, они должны были бы добавить URL непосредственно)
Если вы хотите отобразить дополнительный контент (текст, миниатюру поста или любой другой мета контент) в шаблоне, вы можете легко получить его со страницы (и все это имеет больше смысла и для клиента). Посмотрите, использовали ли вы шаблон архива, вам нужно либо жестко закодировать дополнительный контент, либо использовать, например, параметры темы / плагина (что делает его менее понятным для клиента)
Вот упрощенный пример кода (который будет на вашем шаблоне страницы - например, page-page-of-posts.php):
Теперь, чтобы быть совершенно ясным, мы могли бы избегать использования
query_posts()
здесь и использоватьWP_Query
вместо этого - вот так:Но зачем нам это делать, когда у нас есть такая приятная маленькая функция?
источник
Я изменяю запрос WordPress из functions.php:
источник
Просто чтобы наметить некоторые улучшения в принятом ответе, так как WordPress развивался с течением времени, и некоторые вещи изменились (пять лет спустя):
На самом деле это хук действия. Не фильтр, и это повлияет на любой запрос.
На самом деле, это тоже не так. Функция
have_posts
выполняет итерациюglobal $wp_query
объекта, который не связан только с основным запросом.global $wp_query;
может быть изменен и с помощью вторичных запросов.На самом деле, в настоящее время
WP_Query
это класс, поэтому у нас есть экземпляр класса.В заключение: в то время, когда @StephenHarris писал, скорее всего, все это было правдой, но со временем все изменилось в WordPress.
источник
get_posts
возвращает массив объектов post, а неWP_Query
объекта, так что это действительно правильно. иWP_Query
всегда был классом, экземпляром класса = объекта.