Мы большие поклонники класса WP_Query: мы используем его на многих клиентских сайтах для запроса к БД и вывода контента.

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

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

Смотрите также:

Процесс делится на три этапа:

  • Создание дочерней темы и файла шаблона
  • Создание части шаблона для контента цикла
  • Создание наших циклов

Начнём!

Что вам понадобится

Для дальнейшей работы вам понадобятся:

  • Админ доступ к WordPress
  • Редактор кода
  • Записи на вашем сайте с присвоенными множественными рубриками — мы используем WordPress theme unit test data
  • Установленная тему Twenty Sixteen на вашем сайте
  • Установленная и активированная дочерняя тему Twenty Sixteen

Необязательно использовать именно тему Twenty Sixteen, вы можете использовать этот метод для вашей собственной темы, но мы будем показывать вам всё именно не её примере.

Создание дочерней темы

Сначала давайте создадим дочернюю тему Twenty Sixteen. Мы делаем это, поскольку не хотим редактировать саму тему. Создайте новую пустую папку в директории wp-content/themes. Нашу мы назовём tutsplus-one-query-two-loops.

В этой папке создайте файл с названием style.css и добавьте в него код:

/*
Theme Name:     Tutsplus One Query Multiple Loops
Theme URI:      http://.tutsplus.com/tutorials/how-to-code-multiple-loops-while-only-querying-the-database-once--cms-25703
Description:    Theme to support Tutorial on running multiple loops while querying the database just once. Child theme for the Twenty Sixteen theme.
Author:         Rachel McCollin
Author URI:     http://rachelmccollin.co.uk/
Template:       twentysixteen
Version:        1.0
*/
 
@import url("../twentysixteen/style.css");

Теперь сохраните этот файл и активируйте новую тему.

Следующим шагом будет создание файла шаблона для рубрик, с которыми мы будем работать. Сделайте копию файла archive.php из Twenty Sixteen в вашей новой теме. Не переместите, а скопируйте. Переименуйте файл в category.php. Теперь это файл шаблона рубрик на вашем сайте.

Создание нового файла шаблона

Первым шагом будет настройка нового файла шаблона в нашей теме, которая будет содержать отредактированную версию цикла из Twenty Sixteen. В папке вашей темы создайте подпапку с названием includes, где нужно создать новый файл, названный loop-category.php.

Теперь откройте файл template-parts/content.php из темы Twenty Sixteen и найдите такой код (большая часть файла):

<article id="post-<?php the_ID(); ?>" <?php post_class(); ?>>
    <header class="entry-header">
        <?php if ( is_sticky() && is_home() && ! is_paged() ) : ?>
            <span class="sticky-post"><?php _e( 'Featured', 'twentysixteen' ); ?></span>
        <?php endif; ?>
 
        <?php the_title( sprintf( '<h2 class="entry-title"><a href="%s" rel="bookmark">', esc_url( get_permalink() ) ), '</a></h2>' ); ?>
    </header><!-- .entry-header -->
 
    <?php twentysixteen_excerpt(); ?>
 
    <?php twentysixteen_post_thumbnail(); ?>
 
    <div class="entry-content">
        <?php
            /* translators: %s: Name of current post */
            the_content( sprintf(
                __( 'Continue reading<span class="screen-reader-text"> "%s"</span>', 'twentysixteen' ),
                get_the_title()
            ) );
 
            wp_link_pages( array(
                'before'      => '<div class="page-links"><span class="page-links-title">' . __( 'Pages:', 'twentysixteen' ) . '</span>',
                'after'       => '</div>',
                'link_before' => '<span>',
                'link_after'  => '</span>',
                'pagelink'    => '<span class="screen-reader-text">' . __( 'Page', 'twentysixteen' ) . ' </span>%',
                'separator'   => '<span class="screen-reader-text">, </span>',
            ) );
        ?>
    </div><!-- .entry-content -->
 
    <footer class="entry-footer">
        <?php twentysixteen_entry_meta(); ?>
        <?php
            edit_post_link(
                sprintf(
                    /* translators: %s: Name of current post */
                    __( 'Edit<span class="screen-reader-text"> "%s"</span>', 'twentysixteen' ),
                    get_the_title()
                ),
                '<span class="edit-link">',
                '</span>'
            );
        ?>
    </footer><!-- .entry-footer -->
</article><!-- #post-## -->

Скопируйте его в свой новый файл.

Редактирование шаблона

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

В вашем новом файле loop-category.php найдите этот код и удалите его:

<div class="entry-content">
    <?php
        /* translators: %s: Name of current post */
        the_content( sprintf(
            __( 'Continue reading<span class="screen-reader-text"> "%s"</span>', 'twentysixteen' ),
            get_the_title()
        ) );
 
        wp_link_pages( array(
            'before'      => '<div class="page-links"><span class="page-links-title">' . __( 'Pages:', 'twentysixteen' ) . '</span>',
            'after'       => '</div>',
            'link_before' => '<span>',
            'link_after'  => '</span>',
            'pagelink'    => '<span class="screen-reader-text">' . __( 'Page', 'twentysixteen' ) . ' </span>%',
            'separator'   => '<span class="screen-reader-text">, </span>',
        ) );
    ?>
</div><!-- .entry-content -->

Следующим шагом будет замена функции twenty_sixteen_excerpt() на стандартную функцию the_excerpt(), поскольку версия Twenty Sixteen не содержит ссылку на всю запись.

Найдите эту строчку:

<?php twenty_sixteen_excerpt(); ?>

Замените её на эту:

<?php the_excerpt(); ?>

Нам также необходимо сделать несколько поправок в тегах заголовка. В шаблоне исправьте строку:

<?php the_title( sprintf( '<h2 class="entry-title"><a href="%s" rel="bookmark">', esc_url( get_permalink() ) ), '</a></h2>' ); ?>

Измените тэг h2 на h3:

<?php the_title( sprintf( '<h3 class="entry-title"><a href="%s" rel="bookmark">', esc_url( get_permalink() ) ), '</a></h3>' ); ?>

Сохраните ваш файл шаблона. А теперь давайте вернёмся к вашему файлу category.php и продолжим работу там.

Создание наших циклов

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

В файле category.php найдите такой код:

get_template_part( 'template-parts/content', get_post_format() );

Удалите его.

Приступим к созданию циклов.

В этом примере мы перечислим все записи с тэгом 'content', используя условный тэг has_tag().

Это значит, что нам нужно запустить 3 цикла:

  • Первый проверяет, отобразил ли запрос записи по этому тэгу
  • Если да, то второй цикл выводит записи с этим тэгом
  • А третий выводит записи без этого тэга

Между циклами мы будем использовать rewind_posts() для перемотки записей без повторной отправки запроса: мы всё еще используем базовый запрос.

Первый цикл: поиск записей

В файле category.php найдите начало цикла:

while ( have_posts() ) : the_post();

Над этой строчкой определите новую переменную с названием $count:

$count = 0;

Вставьте этот код в цикл:

// check if there are any posts with the '' tag
$tag = 'content';
if ( has_tag( $tag ) ) {
    $count +=1;
}

Это проверит ваши записи на наличие тэга 'content', и если да, то добавит 1.

Ваш цикл будет похож на этот:

// Check for posts in the first loop.
$count = 0;
while ( have_posts() ) : the_post();
 
// check if there are any posts with the '' tag
$tag = 'content';
if ( has_tag( $tag ) ) {
    $count +=1;
}
     
endwhile;

Второй цикл: вывод записей с тэгом

Следующим шагом будет запуск цикла для вывода записей с тэгом, но только если такие есть. Если значение $count больше 0.

Добавьте такой код под вашим первым циклом:

if ( $count > 0 ) {
                     
    rewind_posts();
 
    echo '<h2>Posts tagged with ' . $tag . '</h2>';
 
     
    while ( have_posts() ) : the_post();
     
    if ( has_tag( $tag ) ) {            
        get_template_part( 'includes/loop', 'category');    
    }
     
    // End the loop.
    endwhile;
     
}

С его помощью мы проверяем больше ли $count чем 0. При положительном ответе записи перематываются, а цикл запускается снова. Он проверяет каждую запись, и если у записи есть нужный нам тэг, то вызывается шаблон, который мы создали.

Третий цикл: выводит остальные записи

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

Под вашим вторим циклом добавьте этот код:

rewind_posts();
         
 
// Second Loop - posts not with the 'content' tag
while ( have_posts() ) : the_post();
         
    if ( !has_tag( $tag ) ) {           
        get_template_part( 'includes/loop', 'category');    
    }
         
// End the loop.
endwhile; ?>

Он перемотает записи и запустит цикл снова. Он проверит записи на отсутствие тэга 'content' и выведет их с помощью части шаблона.

Результат

А сейчас проведите тест страницы архива рубрики на вашем сайте.

Если вы используете WordPress test unit data, как и мы, то вы увидите, что в рубрике «Markup» есть записи с тэгом 'content'. Это страница архива рубрики для рубрики «Markup» на нашем сайте:

Выводы

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

Важно: Не используйте query_posts() для изменения базового запроса. Это замедлит ваш сайт, как при использовании множественных запросов.

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

Источник: code.tutsplus.com

Вам понравился материал?

Лучшие темы от Tesla Themes:

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

Такой e-mail уже зарегистрирован. Воспользуйтесь формой входа или введите другой.

Вы ввели некорректные логин или пароль

Извините, для комментирования необходимо войти.

1 комментарий

сначала новые
по рейтингу сначала новые по хронологии

Разве have_posts() не перематывает цикл назад автоматически по окончанию прохода по циклу?

public function have_posts() {
if ( $this->current_post + 1 post_count ) {
return true;
} elseif ( $this->current_post + 1 == $this->post_count && $this->post_count > 0 ) {
/**
* Fires once the loop has ended.
*
* @since 2.0.0
*
* @param WP_Query &$this The WP_Query instance (passed by reference).
*/
do_action_ref_array( 'loop_end', array( &$this ) );
// Do some cleaning up after the loop
$this->rewind_posts();
}

$this->in_the_loop = false;
return false;
}