Задать вопрос
@nezzard

Правильно ли организована моя лента для Wordpress?

Добрый день, нужно организовать Мою ленту на wordpress, правильно ли будет выводить записи с помощью WP_query() указав перечень всех tags и author на кого подписан? Если допустим тегов будет 20 и авторов 10, долго ли будет обрабатываться такой запрос?
Например
// WP_Query arguments
$args = array (
	'tag_id'                 => '1,10,15,2,30,31,32,35,89,55,120,140,150,4',
	'author'                 => '1,2,3,50,150,140,35',
	'posts_per_page'         => '10',
	'orderby'                => 'date',
);

// The Query
$query = new WP_Query( $args );
  • Вопрос задан
  • 2706 просмотров
Подписаться 2 Оценить Комментировать
Решения вопроса 1
HeadOnFire
@HeadOnFire
PHP, Laravel & WordPress Evangelist
Внимательно читайте документацию и best practices в блогах опытных разработчиков. На русском языке действительно качественной информации по WordPress очень мало. Читайте хотя бы Константина Ковшенина (блог на английском, блог на русском).

1. Никогда не используйте query_posts. Это неэффективно - данная функция заменяет основной запрос (Main Query), но выполняется ПОСЛЕ него. То есть, выполняет запрос к БД повторно, уже с новыми аргументами. Кроме того, практически гарантированно вылезут проблемы с постраничной навигацией. И не забывайте, что все дополнительные данные (виджеты с категориями, последними постами и комментами и т.д.) будут продолжать пытаться использовать данные из основного запроса, а данная функция глобальные переменные заменит, большая часть template tags будет выдавать совершенно неожиданные вещи. Бардак обеспечен. При использовании этой функции нужно не забывать в нужных местах вставлять wp_reset_query(), с чем точно запутаетесь. Данную функцию можно использовать только в одном случае - вызывать ДО основного loop, чтобы изменить параметры запроса. В этом случае WordPress проигнорирует те параметры, которые получит в запросе (GET / ваш урл), и будет использовать те, которые ему передать через query_posts. Но для этих задач есть более правильные решения.

2. Функция get_posts() предназначена для получения небольших, конкретных списков постов мимо основного Loop. Когда не нужна постраничная навигация и все дополнительное добро. Например, под статьей вывести список 5 последних статей из этого раздела. Или в боковой колонке вывести 10 статей, помеченных тем же тегом, что основная статья.

3. Если КРОМЕ основного запроса нужно сделать еще один, используйте новый loop:

$myquery = new WP_Query( $args );
if( $myquery->have_posts() ) :
    while( $myquery->have_posts() ) : $myquery->the_post();
    ...
    endwhile;
endif;

Например, есть раздел "События", и этот раздел - не обычные posts, а custom post type 'event'. И нам в ленте надо вывести не в обычном виде, а 2 блока - первый это ближайшие события (по дате от сегодня и в будущее), второй - прошедшие события (по дате от сегодня и в прошлое). Первый блок выводим модифицированным основным запросом (см. дальше про модификацию основного запроса), второй - нашим новым лупом.

3. Если нужно модифицировать основной запрос, и все что с ним связано (глобальные переменные и т.д.), единственно правильный способ - через хук pre_get_posts. Использовать надо в файле functions.php

add_action( 'pre_get_posts', 'my_function' );
function my_function( $query ) {
    // здесь можно (и нужно) использовать conditional проверки 
    // и модифицировать запросы для разных страниц и исловий, 
    // все в одной фукнции.
    if( $query->is_archive() && $query->is_main_query() ) :
        $query->set(
            'tag_id'                  => '1,10,15,2,30,31,32,35,89,55,120,140,150,4',
	    'author'                 => '1,2,3,50,150,140,35',
	    'posts_per_page'   => '10',
	    'orderby'                => 'date',
        );
    endif;
}

Данный способ не плодит дополнительных запросов, модифицирует напрямую основной запрос, при этом остается возможность модифицировать его дополнителньо из других мест (например, из плагинов - тот же WPML или Polylang для мультиязычной подддержки), не вызывает никаких проблем с постраничной навигацией, правильно устанавливает все глобальные переменные, отчего все дополнительные плюшки (виджеты, последние комменты и посты, меню и прочее) работают корректно.
Ответ написан
Пригласить эксперта
Ответы на вопрос 2
andreybold
@andreybold
Сам не долго занимаюсь wordpress'ом, но насколько я смог понять, то да, массив составлен правильно. Насчёт скорости сказать точно трудно, зависит от кол-ва самих постов, но не думаю что при 10-50 постах будет очень сильно тормозить. Только если сам сервер слабый.
И такой вопрос, а почему вы не хотите использовать query_posts() или скажем get_posts()?
Ответ написан
AlexPTS
@AlexPTS
Full stack веб разработчик
query_posts() и get_posts() внутри работают с WP_query объектом. В этом году про некоторые тонкости выборки и отличия был доклад на wordCamp 2014. В сети доступно видео, можно найти.

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

Войдите, чтобы написать ответ

Похожие вопросы