Более эффективный запрос для отображения записей в той же подкатегории?

30 окт. 2014 г., 16:04:12
Просмотры: 297
Голосов: 0

[РЕДАКТИРОВАНИЕ: Смотрите мой комментарий ниже, возможно, я был введен в заблуждение кэшированием Chrome более ранней версии этого кода. Теперь он работает достаточно быстро. Оставляю вопрос на случай, если у кого-то есть более эффективное решение.]

Многие публиковали подобный код для отображения "связанных записей" в сайдбаре, и я адаптировал его в виде шорткода. Он работает, но загрузка занимает 1-2 секунды на локальном сервере. Я могу добавить кэширование через transient, но учитывая, что это запрос для каждого типа записи, это не сильно поможет (как я думаю). Есть ли более эффективный способ написать этот код?

// ШОРТКОД ДЛЯ ОТОБРАЖЕНИЯ СВЯЗАННЫХ ЗАПИСЕЙ В САЙДБАРЕ
// Показывает записи из той же подкатегории, что и текущая запись
// использование: [related_posts posts="5"]
add_shortcode( 'related_posts', 'mkm_related_posts_shortcode' );
function mkm_related_posts_shortcode( $atts ) {
    ob_start();

    $current_post_id = get_queried_object_id();

    // определяем атрибуты и их значения по умолчанию
    extract( shortcode_atts( array (
        'type' => 'post',
        'order' => 'asc',
        'orderby' => 'menu_order',
        'posts' => '3',
    ), $atts ) );

    $categories = get_the_category($current_post_id);
    if ($categories) {
        $category_ids = array();

        foreach($categories as $individual_category) {
            // ищем только текущие подкатегории
            if ( $individual_category->parent !== 0 ) {
                $category_ids[] = $individual_category->term_id;
            }
        }
    }

        $options = array(
            'post_type' => $type,
            'order' => $order,
            'orderby' => $orderby,
            'posts_per_page' => $posts,
            'category__in' => $category_ids,
            'post__not_in' => array($current_post_id),
        );

        $related_query = new WP_Query( $options );

    $output = '';
    // запускаем цикл на основе запроса
    if ( $related_query->have_posts() ) { 
        $alttext = the_title_attribute('echo=0');
        $output .= '<ul>';
        while ( $related_query->have_posts() ) { 
            $related_query->the_post(); 
            $output .= '<li>';
            $output .= '<h5 class="related-title"><a href="' . get_permalink() . '">' . get_the_title() . '</a></h5>';

            if( has_post_thumbnail($related_query->post->ID) ) { 
                $output .= '<a href="' . get_permalink() . '">' . get_the_post_thumbnail($related_query->post->ID, 'tiny-thumb', array( 'alt' =>  $alttext )) . '</a>';
            }

            $output .= '</li>';
        } 
        $output .= '</ul>';
    }

    ob_get_clean();
    wp_reset_postdata();
    return $output;
}

Спасибо!

Michelle
Michelle
3.46K
Комментарии

Где именно вы используете это?

Pieter Goosen Pieter Goosen
30 окт. 2014 г. 16:43:03

Ок, вау! Код был в "плагине", по сути мои шорткоды скопированы в файл plugin.php, чтобы они не находились в functions.php. Когда я увидел ваш вопрос, я попробовал переместить код в functions.php, и, кажется, всё стало работать намного быстрее (Debug Queries всё ещё показывал тот же результат, но сайдбар теперь загружается мгновенно). Вернул обратно в плагин - и так же, всё работает быстрее. Возможно, меня ввело в заблуждение кэширование Chrome более ранней версии, которая выдавала PHP-уведомления?? (Если вы спрашиваете, где я вызываю шорткод, то это в виджете TinyMCE от Black Studio в сайдбаре страницы отдельного поста.)

Michelle Michelle
30 окт. 2014 г. 17:29:07

Создание виджета вместо использования шорткода для этой функциональности было бы полезным.

Nicolai Grossherr Nicolai Grossherr
30 окт. 2014 г. 17:41:36

Я соглашусь с @ialocin здесь.

Pieter Goosen Pieter Goosen
30 окт. 2014 г. 17:44:22

Кстати, я не вижу причин, почему нельзя/не стоит использовать transient здесь. Единственное, в чем нужно убедиться: что transient идентифицируются по типу записи(ей) и обновляются соответствующим образом - так что это вполне реализуемо, но требует некоторой работы.

Nicolai Grossherr Nicolai Grossherr
30 окт. 2014 г. 17:49:47

@ialocin Мой клиент не уверен, хочет ли он это в сайдбаре или после контента записи, поэтому используется шорткод. Из любопытства: в чем преимущество виджета? Будет ли он отображаться быстрее, чем шорткод?

Michelle Michelle
30 окт. 2014 г. 18:11:27

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

Nicolai Grossherr Nicolai Grossherr
30 окт. 2014 г. 19:04:54
Показать остальные 2 комментариев