@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 );
  • Вопрос задан
  • 2698 просмотров
Решения вопроса 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 на запрос можно прямо выполнить, чтобы об эффективности говорить. На небольших таблицах это будет однозначно работать быстро.
Ответ написан
Ваш ответ на вопрос

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

Войти через центр авторизации
Похожие вопросы