Wp query wordpress

Wordpress цикл на WP_Query

В WordPress шаблонах чаще всего используется стандартный цикл для вывода записей. Стандартный цикл имеет заранее определенные параметры, поэтому с помощью такого цикла можно вывести только определенные записи. Таким образом, использовать стандартный цикл WordPress не всегда удобно.

WordPress цикл на WP_Query()

Если нужно вывести на странице записи, которые совершенно к ней не относятся, то придется создать новый WordPress цикл, и для этого мы сможем использовать класс WP_Query().

Пример: архив произвольного типа записей

Предположим нужно на странице вывести записи произвольного типа. Для этого нам потребуется создать новый шаблон страницы, на которой мы будем использовать новый WordPress цикл на основе WP_Query(). Код будет выглядеть следующим образом:

<?php /* Template Name: Аксессуары для мобильных устройств */ ?>  <?php get_header(); ?>  <div id="container">   <div id="content" role="main">     <h1>Аксессуары для мобильных устройств</h1>     <!-- Начинается цикл -->     <?php      $args = array (      'post_type' => 'acsessuar',      'posts_per_page' => 10,      'paged'=>get_query_var('paged')      );        $acsessuar = new WP_Query($args); ?>     <?php while ( $acsessuar->have_posts() ) : $acsessuar->the_post(); ?>     <div id="post-<?php the_ID(); ?>" <?php post_class(); ?>>  <?php if ( (function_exists('has_post_thumbnail')) && (has_post_thumbnail()) ) : ?>   <a href="<?php the_permalink(); ?>" title="<?php the_title(); ?>" alt=""><?php the_post_thumbnail(array( 234,124)); ?></a>  <?php endif; ?>  <a href="<?php the_permalink() ?>"><?php the_title(); ?></a>  <? the_excerpt(); ?>  </div><!-- post -->  <?php endwhile; ?>    <?php wp_reset_postdata(); ?>      <!-- Заканчивается цикл -->    </div><!-- #content -->   </div><!-- #container -->  <?php get_sidebar(); ?>  <?php get_footer(); ?>

В данном примере вы можете увидеть где начинается новый WordPress цикл, и где он заканчивается. Обращаю ваше внимание на массив $args, который содержит в себе параметры цикла, на основе которых получаются нужные нам записи. Затем создается новый цикл с помощью функции $acsessuar = new WP_Query($args), и если есть посты удовлетворяющие нашим параметрам, то они выводятся на странице.

После нового цикла не забудьте указать <?php wp_reset_postdata(); ?> — это крайне необходимо для того, чтобы сбросить ранее вызванные параметры WP_Query. Данный шаблон в последующем можно применить к любой WordPress странице, тем самым вызвать на этой странице нужные нам записи.

Подобные WordPress циклы на основе WP_Query можно использовать несколько раз на странице. Напомню, что WordPress циклы можно строить также с помощью классов  query_posts и get_posts.

Параметры WP_Query для построения WordPress циклов

Для построения циклов WP_Query необходимо знать некоторые параметры, которые позволят вам построить нужный цикл. Основные параметры WP_Query:

‘post_type’ => », — тип записей

‘posts_per_page’ => 10, — количество выводимых записей на странице

‘category’ => , — вывести посты из данной категории (следует указать ID категории)

Также вы можте использовать множество других параметров для построения циклов. Все параметры для WP_query, get_posts и query_posts идентичны, и вы можете найти их на странице с параметрами WP_query.


About The Author

Hello, I’m Daniel and I make things for the web. I’m the CTO at Kinsta and I write for a number of amazing publications like Smashing Magazine and … More about Daniel

  • Leave a comment
  • 9 min read
  • WordPress, Themes, Techniques (WP)
  • Share on Twitter or LinkedIn

If you’ve been around WordPress for a while you know how difficult it used to be to create post lists based on complex criteria while also conforming to WordPress standards. Over the course of a few years the platform has come a long way. By utilising the power of the WP_Query class, we can lists posts in any way we want.

If you’ve been around WordPress for a while, you’ll know how difficult it used to be to create lists of posts based on complex criteria while also conforming to WordPress’ standards. Over the course of a few years, the platform has come a long way. By using the power of the WP_Query

class, we can lists posts in any way we want.


What Is WP_Query?

The WP_Query class is one of the most important parts of the WordPress codebase. Among other things, it determines the query you need on any given page and pulls posts accordingly. It also saves a lot of information about the requests it makes, which helps a great deal when optimizing pages (and troubleshooting them).

The other role of WP_Query is to enable us to perform complex database queries in a safe, simple and modular manner.

Further Reading on SmashingMag:

  • Powerful WordPress Tips And Tricks
  • Building An Advanced WordPress Search With WP_Query
  • 10 Useful WordPress Loop Hacks
  • Do-It-Yourself Caching Methods With WordPress


Throughout our interactions with this object, we are supplying parameters and using functions to reach our goal. The object’s internals take care of many annoyances, such as protecting against SQL injection attacks and making sure that proper data types are used.


The object abstracts much of the query complexity away so that we don’t have to muck about with the specifics of our database. Because we are using an array to supply our criteria, everything is more self-explanatory. No manual database joins or nested queries are needed — just create an arguments array and instantiate the class!


My favorite of all is modularity. When making raw queries, it is hard to manage those frequently used bits because they are just fragments of SQL code. WP_Query does away with this by using an associative array as an argument. A plethora of goodness ensues: you can merge arguments from different places, run array functions to your heart’s content and manipulate it in ingenious ways.

Getting Started

The “Regular” WordPress Loop

Let’s look at a regular loop first, and then create the same loop using WP_Query. Let’s assume that we’re coding in the category.php file.

<?php  if(have_posts()) :   while(have_posts()) :   the_post();  ?>   <h1><?php the_title() ?></h1>  <div class='post-content'><?php the_content() ?></div>  <?php  endwhile;  else :  ?>   Oops, there are no posts.  <?php  endif; ?>

The Same Loop Using WP_Query

<?php   $args = array('cat' => 4);  $category_posts = new WP_Query($args);   if($category_posts->have_posts()) :   while($category_posts->have_posts()) :   $category_posts->the_post(); ?>   <h1><?php the_title() ?></h1>  <div class='post-content'><?php the_content() ?></div>   <?php  endwhile;  else:  ?>   Oops, there are no posts.  <?php  endif; ?>  

As you can see, there is not much difference at all! Let’s break it down:

  1. Constructing a query On a category page, WordPress already knows that you want to list posts from that category. Because we are constructing a query from scratch using WP_Query, we need to specify this ourselves. We’ll delve a bit deeper into this in a bit.
  2. Instantiating the class and querying for posts By instantiating a class with the constructed argument array, WP_Query will try to pull the posts specified and a load of other details.
  3. Creating a loop You can use all of the usual functions; just be sure to use them as the methods of your object:
    • Instead of have_posts(), use $category_posts->have_posts().
    • Instead of the_post(), use $category_posts->the_post().
  4. Resume business as usual Once you’ve done the above, you can use all of the template tags you’ve come to know and love.

If you look at this in detail, you will find that the global $post object is also available. This means that if you use a custom loop like this within another loop, things can go wrong. Be sure to store the original value of the $post object and restore it after the loop.

<?php  $temp_post = $post; // Storing the object temporarily  $my_query = new WP_Query();  while($my_query->have_posts()) {  // Loop in here  }  $post = $temp_post; // Restore the value of $post to the original ?>

Digging Deeper

The Power of a Good Argument

The ease with which we can create loops is obvious, but what about actually querying for posts? Let me show you a common technique I use when creating sliders for commercial themes.

In many cases, users of your theme will want a great-looking slider, but they might be a bit lazy in creating content. Many users will also want to show future content. Let’s query for upcoming (i.e. unpublished) posts that have an attached featured image.

<?php  $args = array(  'post_status' => 'future',  'meta_query' => array(  array(  'key' => '_thumbnail_id',  'value' => ’,  'compare' => '!='  )  )  );  $slider_posts = new WP_Query($args); ?>  <?php if($slider_posts->have_posts()) : ?>  <div class='slider'>  <?php while($slider_posts->have_posts()) : $slider_posts->the_post() ?>  <div class='slide'>  <?php the_post_thumbnail() ?>  </div>  <?php endwhile ?> </div>  <?php endif ?>  

Short, sweet and utterly understandable — just beautiful. And we’ve just scraped the surface.

Know Your Defaults

You may have noticed that I didn’t specify a number of things in my queries. What about how many posts to list? What about the post’s status in the first query we made?

Default values are supplied for many of the most common arguments. Here are a few that you don’t have to specify, unless you want to change them:

  • posts_per_page Defaults to the value specified in the reading settings for the number of posts to list.
  • post_type Defaults to post.
  • post_status Defaults to publish.

You can find the complete list of parameters in the Codex, of course!

Arrays Are Awesome

In many cases, you will want to specify a number of values that an argument can take. Where it would seem logical, WP_Query usually allows you to use arrays to make your life easier. Here are a few examples:

  • You can use an array for post_status to pull posts from a number of different statuses. Note that you can use the string any to get posts from all statuses.
  • If you use custom post types, you’ll be happy to hear that you can use an array for the value of the post_type parameter as well.
  • For the taxonomy type parameters category__in, tag__in and so on, you can use an array to indicate a multitude of values.

Handling Taxonomies

WP_Query is nice enough to offer a simple way to make advanced taxonomy queries as well. This is especially useful for websites with complex set-ups and for commercial themes with large feature sets. The mechanism used is called tax_query. Let’s look at an example.

Say you have a website all about movies. You store movies in a custom “movie” post type; you have a custom taxonomy for genre, a custom taxonomy for actors, and you use the regular ol’ category to indicate how good a movie is. Let’s find all “Action” movies starring “Bruce Willis” that aren’t “Bad”:

<?php  $args = array(  'post_type' => 'movie',  'tax_query' => array(  'relation' => 'AND',  array(  'taxonomy' => 'category',  'field' => 'slug',  'terms' => array('bad')  'operator' => 'NOT IN'  ),  array(  'taxonomy' => 'genre',  'field' => 'slug',  'terms' => array('action')  ),  array(  'taxonomy' => 'actor',  'field' => 'slug',  'terms' => array('Bruce Willis'),  )  )  ); ?>  

While this hardcoded example would be useful only to people who love Die Hard, it’s not hard to see how an advanced filter can be built that lets users filter through your content in any which way they want.

Learn more about all of the awesome things you can do with the taxonomy parameters in the Codex.

Having Fun With Meta Data

You’ve already seen that WP_Query is great at handling meta data — we used a meta_query in the second example to build a slider from posts that have featured images. Just as with the taxonomy queries, a lot of flexibility is built in here.

We’re currently building a WordPress theme to be used to create a Web page for apartment(s) for rent. We store apartments as a custom post type and use meta data to store the details. With a meta query, we can easily pull in all apartments that can house four or more people, that have a balcony and that are non-smoking.

<?php  $args = array(  'post_type' => 'apartment',  'meta_query' => array(  'relation' => 'AND',  array(  'key' => 'persons',  'value' => '4',  'compare' => '>=',  'type' => 'NUMERIC'  ),  array(  'key' => 'balcony',  'value' => '1',  'type' => 'BINARY',  'compare' => '='  ),  array(  'key' => 'smoking',  'value' => '0',  'type' => 'BINARY',  'compare' => '='  )  )  ); ?>

Again, this is very modular, very understandable. To learn more about the parameters you can use, just visit the “Custom Field Parameters” section in the WP_Query documentation.

Methods And Properties

Once you’ve made a query, you can coax a lot of information out of your object. You can find a full list of “Methods and Properties” in the Codex. Here are the ones I tend to use most:

  • $query Shows you the query string passed to the $wp_query object. This is quite helpful for troubleshooting in some advanced cases.
  • $query_vars Shows an associative array of the arguments you’ve passed. If you do plenty of mixing and matching before passing arguments, this tool could be helpful indeed to check that all is well.
  • $posts Holds the requested posts from the database. I rarely use this property, but it’s good to know that this is where your items come from.
  • $found_posts A handy little thing that shows the total number of found items (without the limit imposed by the posts_per_page argument).

With Great Power Comes Great Responsibility

While WP_Query gives you plenty to play around with, it does have its drawbacks. Many people (my past self included) go nuts when they realize how easy it is to bang out queries all over the place.

Keep in mind that more queries mean more server load. I’ve found that on hosted systems, complex queries can be especially naughty because they eat at your RAM, which is probably your scarcest resource.

Make sure to check out what the default query holds on each page. What’s the sense in creating a new query for the latest posts on the front page if it’s there by default? Use what you can more than once, cache results, and so on.


Вспоминаем, как при помощи WP_Query создаются циклы

Чтобы выделить эту статью среди других частей серии «Изучаем WP_Query», позвольте представить вам маленькое руководство, посвященное созданию циклов в WordPress при помощи класса WP_Query.

Этот процесс никак не отличается от создания обычного цикла. Типичный цикл в WordPress выглядит следующим образом:

А в случае создания цикла при помощи класса WP_Query будет лишь пара отличий:

Давайте обсудим различия этих двух вариантов реализации:

  • Мы выставляем некоторые аргументы для нашего WP_Query;
  • Мы запускаем класс WP_Query;
  • В самое начало функций have_posts() и the_post() добавляем $my_query->. Так они становятся методами класса WP_Query;
  • Затем мы сбрасываем данные $post, чтобы получить данные при помощи основного запроса.

Теперь мы знаем, как создавать циклы при помощи WP_Query. Давайте не будем включать запуск циклов в каждый пример. Но если у вас возникнут проблемы с созданием цикла, то вы всегда можете вернуться к началу статьи.

Пример 1: все записи автора за текущий год

Предположим, что вам необходимо вывести список записей определенного автора, опубликованных в текущем году. Для этого будет достаточно комбинации из двух параметров WP_Query:

Внесите этот запрос в цикл, и все заработает.

Пример 2: получаем свежие записи из категории (за исключением текущей записи)

Вам нужно создать цикл под каждой отдельной записью, и вывести туда список свежих записей из той же категории, но при этом исключить из списка просматриваемую на данный момент запись. Это можно реализовать при помощи параметров ‘cat’ и ‘post__not_in’:

Что касается самого цикла, то я бы рекомендовал вам сделать три или четыре колонки с миниатюрами записей выше заголовков. Такой блок рекомендаций отлично смотрится под записями.

Пример 3: выводим “самые популярные записи”, отсортированные по количеству комментариев

В WordPress отсутствует встроенная функция подсчета просмотров записи, а специализированные плагины серьезно замедляют работу сайтов. Но есть и другой способ определить самые популярные записи: подсчитать комментарии. И в отличие от количества просмотров все данные о комментариях уже есть в базе данных.

WP_Query позволяет без труда отсортировать записи по количеству комментариев:

Теперь вы можете без труда создать собственный шаблон страницы с циклом, который выдает список популярных записей, основываясь на количестве комментариев.

Пример 4: настройка простого слайдера

Я не особый любитель слайдеров, но людям они нравятся, и поэтому я не могу отказывать своим клиентам в этой прихоти. Если им нужен слайдер, я делаю простой запрос при помощи класса WP_Query:

Аргумент ‘cat’ можно использовать для получения слайдов из различных категорий, и это дает возможность использовать сразу несколько слайдеров на странице. Если вы планируете использовать только один слайдер, то можно удалить эту строку кода.

Пример 5: выводим случайную цитату в боковой панели

Если вам нужно выводить случайную цитату в боковой панели при каждом просмотре страницы, то можно воспользоваться следующим кодом для создания типа записи, а также использовать следующий запрос для создания цикла в сайдбаре:

Пример 6: выводим перечень продуктов из определенной ценовой категории

Ниже привожу фрагмент кода, который нужно использовать, если вам нужно вывести элементы пользовательского типа записи «Product», и отфильтровать результаты по значению пользовательского поля «price»:

Пример 7: шорткод для встраивания записей внутри записей

В этом примере я хочу создать шорткод, который позволит встраивать запись в другую запись. В приведенном ниже коде мы создаем функцию shortcode, которая позволяет вставлять записи (или любой произвольный тип записи), а также указать формат отображения: полная версия записи или фрагмент записи:

Пример 8: выводим список запланированных записей (с возможностью показа фрагментов записей)

Почему бы не подогреть интерес посетителей с помощью анонса публикаций на ближайшее время? Вы можете использовать следующую функцию для вывода списка запланированных к публикации записей, а также по желанию отобразить фрагменты записей после заголовков:

Пример 9: запись, опубликованная в этот день в прошлом году

Можно создать специальную функцию, которая бы выводила запись с сегодняшней датой, но только опубликованную ровно год назад:

Пример 10: показываем дочерние страницы текущего поста

Не можете предложить ничего другого, кроме заголовков других страниц в разделах «О нас», «Услуги» или «Портфолио»? Но лучше разместить в них ссылки на дочерние страницы. Можно реализовать это в виде таблицы, состоящей из небольших миниатюр и заголовков под ними.

Давайте посмотрим, какой запрос нужно использовать, чтобы получить необходимый шаблон страницы:

В завершение

Надеюсь, вам понравились сегодняшние примеры. Я специально старался отобрать разные, чтобы показать, насколько широки возможности класса WP_Query!

Если у вас есть другие интересные идеи, то обязательно напишите о них в комментариях! И если вам понравилась сегодняшняя статья, обязательно расскажите о ней своим друзьям!

Перевод статьи “Mastering WP_Query: 10 Useful Examples” был подготовлен дружной командой проекта Сайтостроение от А до Я.


В этой статье я намеренно опущу рассказ о циклах вордпресса (стандартном и двух дополнительных), поскольку информации о них в интернете предостаточно. Я лишь приведу приведу пример цикла на на основе WP_Query, на котором наглядно покажу способы фильтрации и кастомизации постов.

Основные понятия статьи:

  • Цикл WordPress — это цикл, который перебирает массив данных содержащих в себе информацию о каждом посте.
  • WP_Query — класс, позволяющий получать посты из базы данных с необходимыми параметрами.
  • Темплейт — шаблон вывода постов.
  • Фильтрация — изменение вывода постов с заданными параметрами. Можно фильтровать посты по наличию или значению произвольных полей, числа даты, и др.
  • Метаполе — произвольное поле записи.

Пример цикла на основе WP_Query:

Таким способом мы можем получить все записи за все время, и, если их будет очень много, скорее всего уроним сайт. Поэтому мы должны ограничить количество постов для вывода, либо отфильтровать их по заданным параметрам. А для вывода постов, будем использовать темплейт related-posts, который будет лежать в папке templates активной темы.

Параметры фильтрации постов:

  • order — направление сортировки по параметру orderby. Бывает: ASC — по порядку, DESC — в обратном порядке.
  • orderby — сортировка по: none — без сортировки, ID — по ID (номеру поста), author — по id автора (номера автора), title — по загловку, name — по названию поста, date — дате публикации, modified — дате изменения, type — по типу контента, rand — случайный порядок, comment_count — количеству комментариев, meta_value — значению произвольного поля, meta_value_num — значению числового произвольного поля.
  • posts_per_page — количество записей на страницу.
  • meta_query — массив параметров метаполей постов.

Теперь изменим наш цикл, и попробуем вывести 8 последних постов, отсортированных по дате.

Усложним задачу: будем фильтровать посты по наличию поля meta_featured, с выводом 8 постов на страницу. Например: с помощью CMB2 можно создать метаполе типа чекбокс, и выводить на главную только заданные посты.

Более сложный пример: будем фильтровать посты по числовому метаполю meta_votes, с выводом 8 постов на страницу.


Понимание и принципы работы фильтрации постов, дает неограниченный простор к кастомизации вордпресса.


How To Use WP_Query In WordPress

In this WordPress Tutorial, we will have a look at the WP_Query class, which is really the workhorse of fetching post data from your WordPress database. WP_Query gives theme developers complete control over what is sent into “The Loop” as we call it. By mastering WP_Query, one gains the ability to loop over any posts they like and in any theme file where it is deemed needed. With this knowledge you can create custom home pages that might display posts from one category in a given section of the page and posts from another category in a different section of a page. There are so many options available to you with WP_Query. Let’s take a look now.

A Loop Refresher

Let’s take another look at the skeleton of the WordPress Loop as it really is the meat and potatoes of WordPress Theme Development.

In the snippet above we see the WordPress Loop. Basically it says, if there are posts, loop over them all, and if there are no posts, output a message that indicates this. The magic of the loop really happens in that while loop. Anything within the while loop gets repeated once for each post retrieved by the current query. Inside the while loop, you have complete control over how you will output and format the posts. This means you can include any combination of HTML and PHP required to create the effect you are looking for. You choose which parts of the post to include or exclude such as the title, author, the body, and so on. In some cases, maybe you only want to display the title. In others perhaps the title and excerpt will do. Still yet in other scenarios, you may want to display the title and the fully content of each post. You have complete control of this inside that while loop.

Which Posts Are Being Looped Through?

So now that we see how to control the format and output of posts in the while loop, the following question arises. How do we as theme developers control which posts are actually getting looped over? Up until now, we have been at the mercy of what WordPress has decided to loop over. We can now learn how to control this aspect of WordPress.

URL Based Queries

Assuming no custom loop logic has been added to your theme, the default method of how WordPress chooses what posts to loop over are based on the currently active URL or permalink. For example if you visit http://wordpresstutorial.dev/category/php/, then the posts with a category of PHP are fed into the loop. Therefore, only posts which have a category of PHP should be seen on the page. If we test this out, this is exactly what we see.
wp_query by category

It stands to reason then, that if we visit http://wordpresstutorial.dev/category/javascript/ then the category of JavaScript will be fed into the loop and we should only be working with posts that have a category of JavaScript at that point. Once again, we can visit this url and see that this is in fact the case.
wp_query by category via url

So we can see that WordPress does a great job of using the URL to determine which posts to loop over. We only looked at an example of visiting various category URL’s but this also works for archive pages, author pages, tags, and many more. At some point however, you will likely want to be able to specify exactly which posts are being looped over in your theme files by controlling the loop yourself, and not relying on which particular URL is currently active. You can certainly do that, and we will look at how now.

A Custom Homepage

A nice way to demonstrate this technique is to set up a custom homepage where we can choose which posts to display. As we know, by default, WordPress is simply going to display that latest posts on our homepage, regardless of any other aspect about that post. It does not matter the category, tag, or author, WordPress just looks for the most recent posts and displays them as such. Now, we have tutorial based example blog that has a few categories. It might be nice to display one column with a couple recent posts from one category, and another with posts from a different category.

Some Initial Legwork

We first need to tell WordPress that we want to use a static page as the homepage. If this is the case, where will we see all of our posts? We can create a new page, which will act as the main index of blog posts. So we will create a page with the name of ‘Homepage’ and another with the name of ‘All Posts’.

Creating the homepage in the WordPress Dashboard.
creating a custom homepage

Creating a page to display all blog posts.
adding a blog listing page to show all posts

Setting the homepage and all posts page in Settings.
wordpress settings reading

Adding a link to All Post in the main menu.
add a link to all posts in main menu

Ok! We have the legwork out of the way. At this point, we should have the custom text we specified for the homepage when we visit the base URL of http://wordpresstutorial.dev/ and it looks like this is working correctly.
wordpress custom home page

Fear not! You can still view all blog posts on your website. All you have to do is visit http://wordpresstutorial.dev/all-posts/ and this is exactly what we see!
all posts via url wordpress

To be fair, our homepage is pretty lacking right now. As it stands now, the page.php file is responsible for rendering the output of our homepage. In fact, we have many pages in this site. Those are About Us, All Posts, Homepage, Services, and WordPress Example Page. All of these are rendered via page.php. We said we want something custom however for the Homepage. How can we do this?

Introducing front-page.php

When you set a specific page to be the home page on your WordPress site as we did in this tutorial, WordPress is going to look for a file in your theme folder named front-page.php to render that particular page. If it is not present, then WordPress simply uses page.php to handle the rendering. So let’s go ahead and create front-page.php in our theme folder now. We’ll just put some simply text in this file to show that it does in fact power the home page.



So it works! Of course this is pretty silly and doesn’t add a lot of value, so let’s go ahead and put some markup in the front-page.php file. Our goal will be to simply display the navigation menu and the main content. We don’t really want to display the title of the page, since it is simply static content that we are displaying on the homepage.


Let’s also update the homepage in the WordPress editor so it has some more text using this text: “Hi there! This is the homepage of http://wordpresstutorial.dev! This website is awesome! In the WordPress Dashboard, this is a Page, and it is called ‘Homepage’. Any user can go into this page and edit it with the WordPress Editor to make changes to this static content here. We can provide any information about the site we like, right here on this static homepage. A client may like the ability to edit this text easily with no need to dive into any HTML or PHP to do so. Below this static text however, we will have dynamically updated data by leveraging WP_Query.”
easily update static content on homepage

Viewing the homepage has a nice effect now, don’t you think? Again, a non technical person can now easily update this content with no HTML or PHP editing.
check out that homepage

Introducing WP_Query

Now we need to start the process of fetching custom data from the database using WP_Query(). WP_Query() works by passing in various arguments to it based on what you want to retrieve. Let’s say we want to fetch all posts that are of the category of JavaScript. By reading the Category Parameters for WP_Query() we could do something like this:

First, we fetch all posts that have a category_name of javascript. Essentially, this is the slug for the JavaScript category. You can also fetch by category ID if you prefer. Next we var_dump out the contents of what is stored in $javascriptPosts so we can examine. Here is that output in our case:

/home/vagrant/Code/wordpresstutorial/wordpress/wp-content/themes/customtheme/front-page.php:6:  object(WP_Query)[538]   public 'query' =>    array (size=1)   'category_name' => string 'javascript' (length=10)   public 'query_vars' =>    array (size=64)   'category_name' => string 'javascript' (length=10)   'error' => string '' (length=0)   'm' => string '' (length=0)   'p' => int 0   'post_parent' => string '' (length=0)   'subpost' => string '' (length=0)   'subpost_id' => string '' (length=0)   'attachment' => string '' (length=0)   'attachment_id' => int 0   'name' => string '' (length=0)   'static' => string '' (length=0)   'pagename' => string '' (length=0)   'page_id' => int 0   'second' => string '' (length=0)   'minute' => string '' (length=0)   'hour' => string '' (length=0)   'day' => int 0   'monthnum' => int 0   'year' => int 0   'w' => int 0   'tag' => string '' (length=0)   'cat' => int 4   'tag_id' => string '' (length=0)   'author' => string '' (length=0)   'author_name' => string '' (length=0)   'feed' => string '' (length=0)   'tb' => string '' (length=0)   'paged' => int 0   'meta_key' => string '' (length=0)   'meta_value' => string '' (length=0)   'preview' => string '' (length=0)   's' => string '' (length=0)   'sentence' => string '' (length=0)   'title' => string '' (length=0)   'fields' => string '' (length=0)   'menu_order' => string '' (length=0)   'embed' => string '' (length=0)   'category__in' =>    array (size=0)   empty   'category__not_in' =>    array (size=0)   empty   'category__and' =>    array (size=0)   empty   'post__in' =>    array (size=0)   empty   'post__not_in' =>    array (size=0)   empty   'post_name__in' =>    array (size=0)   empty   'tag__in' =>    array (size=0)   empty   'tag__not_in' =>    array (size=0)   empty   'tag__and' =>    array (size=0)   empty   'tag_slug__in' =>    array (size=0)   empty   'tag_slug__and' =>    array (size=0)   empty   'post_parent__in' =>    array (size=0)   empty   'post_parent__not_in' =>    array (size=0)   empty   'author__in' =>    array (size=0)   empty   'author__not_in' =>    array (size=0)   empty   'ignore_sticky_posts' => boolean false   'suppress_filters' => boolean false   'cache_results' => boolean true   'update_post_term_cache' => boolean true   'lazy_load_term_meta' => boolean true   'update_post_meta_cache' => boolean true   'post_type' => string '' (length=0)   'posts_per_page' => int 10   'nopaging' => boolean false   'comments_per_page' => string '50' (length=2)   'no_found_rows' => boolean false   'order' => string 'DESC' (length=4)   public 'tax_query' =>    object(WP_Tax_Query)[540]   public 'queries' =>    array (size=1)   0 =>    array (size=5)   ...   public 'relation' => string 'AND' (length=3)   protected 'table_aliases' =>    array (size=1)   0 => string 'wp_term_relationships' (length=21)   public 'queried_terms' =>    array (size=1)   'category' =>    array (size=2)   ...   public 'primary_table' => string 'wp_posts' (length=8)   public 'primary_id_column' => string 'ID' (length=2)   public 'meta_query' =>    object(WP_Meta_Query)[539]   public 'queries' =>    array (size=0)   empty   public 'relation' => null   public 'meta_table' => null   public 'meta_id_column' => null   public 'primary_table' => null   public 'primary_id_column' => null   protected 'table_aliases' =>    array (size=0)   empty   protected 'clauses' =>    array (size=0)   empty   protected 'has_or_relation' => boolean false   public 'date_query' => boolean false   public 'request' => string 'SELECT SQL_CALC_FOUND_ROWS wp_posts.ID FROM wp_posts LEFT JOIN wp_term_relationships ON (wp_posts.ID = wp_term_relationships.object_id) WHERE 1=1 AND (    wp_term_relationships.term_taxonomy_id IN (4)  ) AND wp_posts.post_type = 'post' AND (wp_posts.post_status = 'publish' OR wp_posts.post_status = 'private') GROUP BY wp_posts.ID ORDER BY wp_posts.post_date DESC LIMIT 0, 10' (length=378)   public 'posts' =>    array (size=2)   0 =>    object(WP_Post)[322]   public 'ID' => int 90   public 'post_author' => string '1' (length=1)   public 'post_date' => string '2017-07-20 16:07:26' (length=19)   public 'post_date_gmt' => string '2017-07-20 16:07:26' (length=19)   public 'post_content' => string 'This is an example JavaScript blog post to add to the various example blog posts in this WordPress Tutorial. We're learning about WordPress, PHP, and JavaScript during this tutorial where we create a WordPress Theme from scratch. This means we have started with 0 lines of code, and have worked our way up to having a functional theme for our WordPress Installation. If you like JavaScript, you'll have a great time customizing behaviors on your WordPress website on the front end and admin dashboard.' (length=504)   public 'post_title' => string 'How To Learn JavaScript' (length=23)   public 'post_excerpt' => string '' (length=0)   public 'post_status' => string 'publish' (length=7)   public 'comment_status' => string 'open' (length=4)   public 'ping_status' => string 'open' (length=4)   public 'post_password' => string '' (length=0)   public 'post_name' => string 'how-to-learn-javascript' (length=23)   public 'to_ping' => string '' (length=0)   public 'pinged' => string '' (length=0)   public 'post_modified' => string '2017-07-20 16:11:04' (length=19)   public 'post_modified_gmt' => string '2017-07-20 16:11:04' (length=19)   public 'post_content_filtered' => string '' (length=0)   public 'post_parent' => int 0   public 'guid' => string 'http://wordpresstutorial.dev/?p=90' (length=34)   public 'menu_order' => int 0   public 'post_type' => string 'post' (length=4)   public 'post_mime_type' => string '' (length=0)   public 'comment_count' => string '0' (length=1)   public 'filter' => string 'raw' (length=3)   1 =>    object(WP_Post)[544]   public 'ID' => int 9   public 'post_author' => string '1' (length=1)   public 'post_date' => string '2017-06-13 15:08:46' (length=19)   public 'post_date_gmt' => string '2017-06-13 15:08:46' (length=19)   public 'post_content' => string 'This is an example JavaScript blog post to add to the various example blog posts in this WordPress Tutorial. We're learning about WordPress, PHP, and JavaScript during this tutorial where we create a WordPress Theme from scratch. This means we have started with 0 lines of code, and have worked our way up to having a functional theme for our WordPress Installation. If you like JavaScript, you'll have a great time customizing behaviors on your WordPress website on the front end and admin dashboard.' (length=506)   public 'post_title' => string 'JavaScript Blog Post' (length=20)   public 'post_excerpt' => string '' (length=0)   public 'post_status' => string 'publish' (length=7)   public 'comment_status' => string 'open' (length=4)   public 'ping_status' => string 'open' (length=4)   public 'post_password' => string '' (length=0)   public 'post_name' => string 'javascript-blog-post' (length=20)   public 'to_ping' => string '' (length=0)   public 'pinged' => string '' (length=0)   public 'post_modified' => string '2017-06-29 17:01:39' (length=19)   public 'post_modified_gmt' => string '2017-06-29 17:01:39' (length=19)   public 'post_content_filtered' => string '' (length=0)   public 'post_parent' => int 0   public 'guid' => string 'http://wordpresstutorial.dev/?p=9' (length=33)   public 'menu_order' => int 0   public 'post_type' => string 'post' (length=4)   public 'post_mime_type' => string '' (length=0)   public 'comment_count' => string '0' (length=1)   public 'filter' => string 'raw' (length=3)   public 'post_count' => int 2   public 'current_post' => int -1   public 'in_the_loop' => boolean false   public 'post' =>    object(WP_Post)[322]   public 'ID' => int 90   public 'post_author' => string '1' (length=1)   public 'post_date' => string '2017-07-20 16:07:26' (length=19)   public 'post_date_gmt' => string '2017-07-20 16:07:26' (length=19)   public 'post_content' => string 'This is an example JavaScript blog post to add to the various example blog posts in this WordPress Tutorial. We're learning about WordPress, PHP, and JavaScript during this tutorial where we create a WordPress Theme from scratch. This means we have started with 0 lines of code, and have worked our way up to having a functional theme for our WordPress Installation. If you like JavaScript, you'll have a great time customizing behaviors on your WordPress website on the front end and admin dashboard.' (length=504)   public 'post_title' => string 'How To Learn JavaScript' (length=23)   public 'post_excerpt' => string '' (length=0)   public 'post_status' => string 'publish' (length=7)   public 'comment_status' => string 'open' (length=4)   public 'ping_status' => string 'open' (length=4)   public 'post_password' => string '' (length=0)   public 'post_name' => string 'how-to-learn-javascript' (length=23)   public 'to_ping' => string '' (length=0)   public 'pinged' => string '' (length=0)   public 'post_modified' => string '2017-07-20 16:11:04' (length=19)   public 'post_modified_gmt' => string '2017-07-20 16:11:04' (length=19)   public 'post_content_filtered' => string '' (length=0)   public 'post_parent' => int 0   public 'guid' => string 'http://wordpresstutorial.dev/?p=90' (length=34)   public 'menu_order' => int 0   public 'post_type' => string 'post' (length=4)   public 'post_mime_type' => string '' (length=0)   public 'comment_count' => string '0' (length=1)   public 'filter' => string 'raw' (length=3)   public 'comment_count' => int 0   public 'current_comment' => int -1   public 'found_posts' => string '2' (length=1)   public 'max_num_pages' => float 1   public 'max_num_comment_pages' => int 0   public 'is_single' => boolean false   public 'is_preview' => boolean false   public 'is_page' => boolean false   public 'is_archive' => boolean true   public 'is_date' => boolean false   public 'is_year' => boolean false   public 'is_month' => boolean false   public 'is_day' => boolean false   public 'is_time' => boolean false   public 'is_author' => boolean false   public 'is_category' => boolean true   public 'is_tag' => boolean false   public 'is_tax' => boolean false   public 'is_search' => boolean false   public 'is_feed' => boolean false   public 'is_comment_feed' => boolean false   public 'is_trackback' => boolean false   public 'is_home' => boolean false   public 'is_404' => boolean false   public 'is_embed' => boolean false   public 'is_paged' => boolean false   public 'is_admin' => boolean false   public 'is_attachment' => boolean false   public 'is_singular' => boolean false   public 'is_robots' => boolean false   public 'is_posts_page' => boolean false   public 'is_post_type_archive' => boolean false   private 'query_vars_hash' => string 'c7f2d38df04d2e63027c41e3c1f384ad' (length=32)   private 'query_vars_changed' => boolean false   public 'thumbnails_cached' => boolean false   private 'stopwords' => null   private 'compat_fields' =>    array (size=2)   0 => string 'query_vars_hash' (length=15)   1 => string 'query_vars_changed' (length=18)   private 'compat_methods' =>    array (size=2)   0 => string 'init_query_flags' (length=16)   1 => string 'parse_tax_query' (length=15)

If you’re quite familiar with PHP, this output makes perfect sense to you. If PHP is not your specialty, this output might look a little bit foreign to you. Not to worry. Basically, what we see here is that we have an Object of type WP_Query. In other words, we instantiated an instance of the WP_Class() and stored it in $javascriptPosts. If this is new to you, be sure to check out our Object Oriented Programming tutorials. We named the variable this way simply to remind us that the posts that are contained in this object have a category of JavaScript. You can name this variable however you like. So let’s see how we might make use of this in our theme files.

So how do we get these custom queries into the Loop?

I’m glad you asked, we will do so right now. Basically, the custom Loops will work the same as the default loop with a few small exceptions. When you make a call to have_posts() and the_post(), you need to do so off of the new object that you have created. So we created a new object in $javascriptPosts, therefore our code would include those calls like so:

Also note that we make use of wp_reset_postdata() as a best practice. It seems trivial, but it is in fact pretty important. The documentation tells us the following:

Use this function to restore the global $post variable of the main query loop after a secondary query loop using new WP_Query. It restores the $post variable to the current post in the main query.

Differences between the main query loop and secondary query loops are:

the main loop is based on the URL request and is processed before templates are loaded
secondary loops are queries (using new WP_Query) in theme template or plugin files

In other words, use this function so that you don’t screw up the default WordPress queries when trying to create custom queries via WP_Query().

What if we wanted to fetch posts in the PHP category? The following query should work quite well:

Putting It All Together

Let’s now clean up our front-page.php file so that we have have our static content at the top, and then our new dynamic content side by side below the static content. We’ll have the main loop at the top of the file which outputs the homepage, then we will make use of our two new custom queries that use WP_Query() to fetch all JavaScript posts and also all PHP posts. We will display them in two columns side by side. Also note that we make use of that get_template_part() function which is so helpful!



The results look pretty cool! We now have a static homepage at the top, that anyone can easily update by simply going into the WordPress Dashboard and editing that page. Below that, we now also have our two sections which display recent posts from two different categories in a magazine like layout. Very cool!
static homepage and custom dynamic content

How To Use WP_Query In WordPress Summary

In this tutorial we learned a lot about WP_Query() and how to use it to fetch custom data that meets our requirements. For our purposes we used WP_Query() to set up a custom magazine like layout on our homepage by fetching posts from one category in a custom WP_Query(), then fetching another set of posts from a different category in a second WP_Query() call. This is literally just the tip of the proverbial iceberg! WP_Query() can accept many more arguments which we will look at in future tutorials. For now, I hope you feel much more comfortable making use of WP_Query() than when we first started.


Использование WP_Query в WordPress

Если Вы работали с WordPress некоторое время, вы должны знать как трудно было раньше создавать списки записей на основе большого количества критериев и в то же время в соответствии со стандартами WordPress. Но за последние нескольких лет платформа прошла долгий путь. И сейчас, с помощью мощного класса WP_Query, мы можем создавать списки сообщений ни в чем себя не ограничивая.

Что такое WP_Query?

Класс WP_Query является одной из важнейших частей в движке WordPress. Среди прочего, он определяет запросы, которые вам необходимы на любой странице и выводит сообщения в соответствии с заданными критериями. Он также сохраняет много информации о запросах которые делает, что помогает при оптимизации страниц (и устранении ошибок).

WP_Query позволяет нам выполнять сложные запросы к базе данных безопасно, просто и модульным способом.


На протяжении всего нашего взаимодействия с этим объектом, мы указываем лишь параметры и используем функции для достижения нашей цели. Внутренние объекты сами заботятся о многих проблемах, таких как защита от SQL-инъекций и проверка использования правильного типа данных.


При использовании этого объекта нам не нужно изучать особенности нашей базы данных. Поскольку мы используем массив, чтобы передавать наши параметры, нет нужды вручную писать запросы с join или вложенные запросы, нужно просто создать массив аргументов и экземпляр класса!


WP_Query позволяет избежать использования SQL-запросов в коде, класс использует ассоциативный массив в качестве аргумента. Это позволяет получить множество преимуществ: вы можете объединить аргументы из разных мест кода, запустить массив функций и управлять ими всевозможными способами.

Итак, начнем!

«Стандартный» цикл в WordPress

Давайте посмотрим вначале на обычный цикл, и затем создадим такой же цикл, используя WP_Query. Давайте предположим, что мы создаем файл category.php для своей темы.

То же цикл, используя WP_Query:

Как вы можете видеть, на первый взгляд нет большой разницы! Давайте рассмотрим его подробнее:

Построение запросов

На странице категории мы хотим получить список сообщений из этой категории. Так как мы строим запрос с нуля, используя WP_Query, мы должны определить это сами. Мы немного углубимся в это чуть позже.

Создание экземпляра класса и запросов для сообщений

С помощью экземпляра класса и массива аргументов, WP_Query будет пытаться получить указанные сообщения.

Создание цикла

Вы можете использовать любые обычные функции, только не забудьте использовать их в качестве методов объекта:

Вместо have_posts(), используйте $category_posts->have_posts().
Вместо the_post(), используйте $category_posts->the_post().

После того как вы сделали всё что указано выше, вы можете использовать любые теги шаблонов, которые мы знаем и любим.

Если вы посмотрите на это подробнее, то вы увидите, что глобальный объект $post также доступен. Это означает, что если вы используете пользовательский цикл, что-нибудь может пойти не так. Обязательно сохраните первоначальное значение объекта $post и восстановите его после цикла.

Идем дальше…

Легкость, с которой мы можем создавать циклы очевидна, но как на самом деле создавать запросы для записей? Позвольте мне показать вам распространенный метод, который часто используют при создании слайдеров в коммерческих темах.

Очень часто пользователи вашей темы хотят видеть на своих сайтах великолепно выглядящие слайдеры, но они могут быть немного ленивы при создании контента. Многие пользователи также хотят показать будущие записи, которые планируется опубликовать. Давайте создадим запрос для получения предстоящих (т.е. неопубликованых) сообщений, которые имеют изображение.

Короткий и совершенно понятный код — просто и красиво.

Значения по умолчанию

Вы, возможно, заметили, что я не уточнил количество необходимых записей в моём запросе. А сколько сообщений в списке? И что за статус поста в первом запросе, который мы сделали?

Значения по умолчанию устанавливаются для многих из наиболее распространенных аргументов. Вот несколько, которые вы не обязаны указывать, если только вы не хотите изменить их:

По умолчанию используется значение, указанное в параметрах сайта о количестве сообщений на странице.

По умолчанию используется post.

По умолчанию используется publish.

Вы можете найти полный список параметров в документации!


Во многих случаях вам нужно будет указать несколько значений, которые может принимать аргумент. И WP_Query позволяет использовать массивы, чтобы сделать вашу жизнь проще. Вот несколько примеров:

Вы можете использовать массив для post_status, чтобы получить сообщения с различными статусами. Обратите внимание, что вы можете использовать строку any, чтобы получить сообщения со всевозможными статусами.

Если вы используете пользовательские типы сообщений, вы будете рады услышать, что вы можете использовать массив для значений параметра post_type также.

Для таксономии параметры типа category__in, tag__in и так далее, вы можете использовать массив для указания множества значений.

Обработка Таксономии

WP_Query достаточно хорош, чтобы предложить простой способ сделать сложные запросы к таксономии. Это особенно полезно для веб-сайтов с сложными  настройками для коммерческих тем и с большим набором функций. Используемый механизм называется tax_query. Давайте посмотрим на примере.

Скажем, у вас есть сайт: Все о кино. Вы храните фильмы в пользовательском типе записей «movies»; у вас также есть тип записей для жанра, пользовательский тип записей для актеров, и вы используете обычную категорию, чтобы указать, насколько хороший фильм. Давайте найдем все фильмы жанра «Action» в главной роли с Брюсом Уиллисом, которые не являются «Bad»:

Хотя это пример с хардкодом, и может быть полезен только для людей, которые любят «Крепкий орешек», но не трудно понять как расширенный фильтр может быть построен, чтобы позволить пользователям фильтровать ваш контент любым образом, как они хотят.

Узнать больше о использовании параметров таксономии можно в соответствующем разделе документации.

Работаем с метаданными

Вы уже видели, что WP_Query отлично справляется с мета-данными — мы использовали meta_query во втором примере, когда строили слайдер с записями, которые имеют изображения.

Представим, что мы создаем тему WordPress, которая будет использоваться для сайта сдающего квартиру(ы) в аренду. Мы будем хранить квартиры в пользовательском типе записей и использовать мета-данные для хранения дополнительной информации. Таким образом, мы можем легко получать, например, все квартиры, которые могут вместить четырех или более человек, или те у которых есть балкон, или только квартиры на сутки с джакузи.

Чтобы узнать больше о параметрах, которые можно использовать, просто зайдите в раздел Custom Field Parameters в документации по WP_Query.

Методы и свойства

Как только Вы сделали запрос, можно вытянуть много информации из Вашего объекта. Вы можете найти полный список «Методов и свойств» в документации. Вот те, которые я предпочитаю использовать чаще всего:

Показывает строку запроса, которая передается в объект $wp_query. Это очень полезно для устранения неполадок в некоторых случаях.

Показывает ассоциативный массив аргументов, которые вы передали. Если вы делаете много смешиваний и сопоставлений перед передачей аргументов, этот инструмент может быть полезным, чтобы проверить, что все передано правильно.

Содержит запрошенные записи из базы данных.

Удобная вещь, которая показывает общее число найденных элементов (без ограничения установленного аргументом posts_per_page).

С большой силой приходит большая ответственность

WP_Query дает вам большие возможности, но у него есть свои недостатки. Многие люди «сходят с ума», когда они понимают, как легко можно вызывать запросы повсюду.

Имейте в виду, что чем больше запросов, тем больше нагрузка на сервер. При создании сложных запросов могут возникнуть проблемы с RAM на хостинге, которая, вероятно, является ограниченным ресурсом у вас.

Убедитесь в том, что запрос по умолчанию выполняется на каждой странице. Какой смысл в создании нового запроса для получения последних сообщений на главной странице, если он там есть по умолчанию? Используйте кэширование результатов, чтобы снизить нагрузку на сервер.

Перевод статьи с http://wp.smashingmagazine.com


You May Also Like

About the Author: admind

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

Этот сайт использует Akismet для борьбы со спамом. Узнайте, как обрабатываются ваши данные комментариев.