Статьи

Освоение WP_Query: использование цикла

Как я уже WP_Query во введении к этой серии, класс WP_Query имеет четыре основных элемента:

  • аргументы для запроса, используя параметры, которые будут подробно рассмотрены в этой серии
  • сам запрос
  • цикл, который будет выводить содержимое публикации, заголовки или все, что вы хотите отобразить
  • завершение: закрытие тегов if и while и сброс данных поста

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

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

Итак, цикл идет после вашего запроса и использует три тега:

  • if( $query->have_posts() ) проверяет, есть ли сообщения.
  • while( $query->have_posts() ) повторяет цикл для каждого сообщения, пока есть сообщения для извлечения.
  • $query->the_post() обращается к этому конкретному сообщению.

Так вот где цикл помещается в класс WP_Query :

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
<?php
 
$args = array(
    // Arguments for your query.
);
 
// Custom query.
$query = new WP_Query( $args );
 
// Check that we have query results.
if ( $query->have_posts() ) {
 
    // Start looping over the query results.
    while ( $query->have_posts() ) {
 
        $query->the_post();
 
        // Contents of the queried post results go here.
 
    }
 
}
 
// Restore original post data.
wp_reset_postdata();
 
?>

После выполнения цикла все, что осталось сделать, это привести в порядок все, используя wp_reset_postdata() .

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

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
<?php
 
$args = array(
    // Arguments for your query.
);
 
// Custom query.
$query = new WP_Query( $args );
 
// Check that we have query results.
if ( $query->have_posts() ) {
 
    // Start looping over the query results.
    while ( $query->have_posts() ) {
 
        $query->the_post();
 
        ?>
 
        <article id=»post-<?php the_ID(); ?>» <?php post_class( ‘left’ );
            <a href=»<?php the_permalink(); ?>» title=»<?php the_title_attribute(); ?>»>
                <?php post_thumbnail( ‘thumbnail’ );?>
            </a>
            <a href=»<?php the_permalink(); ?>» title=»<?php the_title_attribute(); ?>»>
                <?php the_title();
            </a>
            <?php the_excerpt();
        </article>
 
        <?php
 
    }
 
}
 
// Restore original post data.
wp_reset_postdata();
 
?>

Этот цикл отображает именно то, что я описал выше: рекомендуемое изображение, заголовок и выдержку.

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

Это очень легко обойти, поместив включающий элемент или заголовок внутри тега if :

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
<?php
 
$args = array(
    // Arguments for your query.
);
 
// Custom query.
$query = new WP_Query( $args );
 
// Check that we have query results.
if ( $query->have_posts() ) {
 
     
    echo ‘<section class=»clear»>’;
        echo ‘<h2>’ .
     
        // Start looping over the query results.
        while ( $query->have_posts() ) {
     
            $query->the_post();
     
            ?>
     
            <article id=»post-<?php the_ID(); ?>» <?php post_class( ‘left’ );
                <a href=»<?php the_permalink(); ?>» title=»<?php the_title_attribute(); ?>»>
                    <?php post_thumbnail( ‘thumbnail’ );?>
                </a>
                <a href=»<?php the_permalink(); ?>» title=»<?php the_title_attribute(); ?>»>
                    <?php the_title();
                </a>
                <?php the_excerpt();
            </article>
     
            <?php
     
        }
     
    echo ‘</section>’;
 
}
 
// Restore original post data.
wp_reset_postdata();
 
?>

Здесь вы можете видеть, что я проверил, есть ли какие-либо сообщения, полученные по моему запросу, и если есть, я открыл содержащий элемент и добавил заголовок.

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

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
<?php
 
$args = array(
    ‘category_name’ => ‘category-slug’,
    ‘post_type’ => ‘post’
);
 
// Custom query.
$query = new WP_Query( $args );
 
// Check that we have query results.
if ( $query->have_posts() ) {
 
    echo ‘<ul class=»category posts»>’;
 
        // Start looping over the query results.
        while ( $query->have_posts() ) {
 
            $query->the_post();
 
            ?>
 
            <li <?php post_class( ‘left’ );
                <a href=»<?php the_permalink(); ?>» title=»<?php the_title_attribute(); ?>»>
                    <?php the_title();
                </a>
            </li>
 
            <?php
     
        }
 
    echo ‘</ul>’;
 
}
 
// Restore original post data.
wp_reset_postdata();
 
?>

Это проверяет, получил ли запрос какие-либо сообщения, и если это так, он открывает элемент ul и затем запускает цикл.

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

В этом примере отображается выдержка и рекомендуемое изображение для первого сообщения, а затем только заголовок каждого последующего сообщения:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
<?php
 
// First query arguments.
$args1 = array(
    ‘post_type’ => ‘post’,
    ‘posts_per_page’ => ‘1’
);
 
// First custom query.
$query1 = new WP_Query( $args1 );
 
// Check that we have query results.
if ( $query1->have_posts() ) {
 
    // Start looping over the query results.
    while ( $query1->have_posts() ) {
 
        $query1->the_post();
 
        ?>
 
        <article id=»post-<?php the_ID(); ?>» <?php post_class();
            <a href=»<?php the_permalink(); ?>» title=»<?php the_title_attribute(); ?>»>
                <?php post_thumbnail( ‘thumbnail’ );?>
            </a>
            <a href=»<?php the_permalink(); ?>» title=»<?php the_title_attribute(); ?>»>
                <?php the_title();
            </a>
            <?php the_excerpt();
        </article>
 
        <?php
 
    }
 
}
 
// Restore original post data.
wp_reset_postdata();
 
// Second query arguments.
$args2 = array(
    ‘offset’ => ‘1’,
    ‘post_type’ => ‘post’
);
 
// Second custom query.
$query2 = new WP_Query( $args2 );
 
// Check that we have query results.
if ( $query2->have_posts() ) {
 
    echo ‘<ul class=»more-posts»>’;
     
        // Start looping over the query results.
        while ( $query2->have_posts() ) {
 
            $query2->the_post();
     
            ?>
 
            <li <?php post_class();
                <a href=»<?php the_permalink(); ?>» title=»<?php the_title_attribute(); ?>»>
                    <?php the_title();
                </a>
            </li>
     
            <?php
     
        }
     
    echo ‘</ul>’;
 
}
 
// Restore original post data.
wp_reset_postdata();
 
?>

Я использовал два ключевых аргумента здесь:

  • 'posts_per_page' => '1' , используемый с первым запросом, выводит только самый последний пост.
  • 'offset' = '1' , используемый со вторым запросом, пропускает первое сообщение, гарантируя, что оно не повторяется в списке ниже.
  • Как видно из приведенного выше кода, цикл немного отличается для каждого запроса. Первый выводит рекомендуемое изображение, заголовок и отрывок, а второй проверяет, есть ли в запросе сообщения, и, если да, открывает элемент ul и заключает каждый заголовок сообщения в элемент li и ссылку на его страницу.

Вы также заметите, что я использовал wp_reset_postdata() после обоих циклов. Если бы я этого не сделал, второй цикл все равно вывел бы данные из первого.

Без цикла WP_Query самом деле мало что делает. Цикл — это код, который вы используете для отображения данных, которые WordPress извлек из базы данных на основе аргументов вашего запроса.

Как я продемонстрировал, в цикле есть несколько вариантов. Простой цикл будет просто выводить все сообщения в порядке, который вы указали в аргументах запроса (или по дате в порядке убывания по умолчанию). Если вы разделяете if( $query->have_posts() ) и while( $query->have_posts() ) , вы можете вставить дополнительную разметку вне цикла, но только если ваш запрос вернул данные. И, наконец, указав альтернативные аргументы и используя wp_reset_postdata() после каждого цикла, вы можете использовать WP_Query более одного раза для создания нескольких циклов на своей странице.