68
Всё, что нужно знать о WP_Query Сергей Бирюков WordCamp Russia 2014

Everything You Need to Know About WP_Query, WordCamp Russia 2014

Embed Size (px)

DESCRIPTION

http://2014.russia.wordcamp.org/

Citation preview

Page 1: Everything You Need to Know About WP_Query, WordCamp Russia 2014

Всё, что нужно знать о WP_Query

Сергей Бирюков

WordCamp Russia 2014

Page 2: Everything You Need to Know About WP_Query, WordCamp Russia 2014

Обо мне

Сергей Бирюков● Разработчик ядра WordPress

http://core.trac.wordpress.org● Локализатор WP в России

http://ru.wordpress.org

http://sergeybiryukov.ru@flash_usb

Page 3: Everything You Need to Know About WP_Query, WordCamp Russia 2014

Что мы знаем о WP_Query?

Page 4: Everything You Need to Know About WP_Query, WordCamp Russia 2014

Условные теги

is_author(), is_category(), is_home() и т. д.

Page 5: Everything You Need to Know About WP_Query, WordCamp Russia 2014

Кто сталкивался с query_posts()?

Page 6: Everything You Need to Know About WP_Query, WordCamp Russia 2014

Способы получения записей

● query_posts()● new WP_Query()● get_posts()

Page 7: Everything You Need to Know About WP_Query, WordCamp Russia 2014

Цикл WordPress

while ( have_posts() ) :

the_post();

endwhile;

Page 8: Everything You Need to Know About WP_Query, WordCamp Russia 2014

Вторичный цикл

$query = new WP_Query( … );

while ( $query->have_posts() ) :

$query->the_post();

endwhile;

Page 9: Everything You Need to Know About WP_Query, WordCamp Russia 2014

Массив записей

$result = get_posts( … );

foreach ( $result as $post_obj ) {

...

}

Page 10: Everything You Need to Know About WP_Query, WordCamp Russia 2014

Что мы не знаем?

Page 11: Everything You Need to Know About WP_Query, WordCamp Russia 2014

У каждого объекта запроса есть методы

is_author() — то же самое, что $wp_query->is_author().

Page 12: Everything You Need to Know About WP_Query, WordCamp Russia 2014

function is_author() {

global $wp_query;

return $wp_query->is_author();

}

Page 13: Everything You Need to Know About WP_Query, WordCamp Russia 2014

Обычный цикл

while ( have_posts() ) :

the_post();

if ( is_author() )

echo 'Страница автора';

endwhile;

Page 14: Everything You Need to Know About WP_Query, WordCamp Russia 2014

Обычный цикл

while ( have_posts() ) :

the_post();

if ( $wp_query->is_author() )

echo 'Страница автора';

endwhile;

Page 15: Everything You Need to Know About WP_Query, WordCamp Russia 2014

Вторичный цикл

$query = new WP_Query( … );

while ( $query->have_posts() ) :

$query->the_post();

if ( $query->is_author() )

echo 'Страница автора.';

endwhile;

Page 16: Everything You Need to Know About WP_Query, WordCamp Russia 2014

Вторичный цикл

$query = new WP_Query( … );

while ( $query->have_posts() ) :

$query->the_post();

if ( $query->is_author() )

echo 'Страница автора.';

endwhile;

Page 17: Everything You Need to Know About WP_Query, WordCamp Russia 2014

Вторичный цикл

$query = new WP_Query( … );

while ( $query->have_posts() ) :

$query->the_post();

if ( $query->is_author() )

echo 'Страница автора.';

endwhile;

Page 18: Everything You Need to Know About WP_Query, WordCamp Russia 2014

Если мы создаём новый объект:

$my_query = new WP_Query( $query );

то можем вызывать его методы:

while ( $my_query->have_posts() ) :

$my_query->the_post();

endwhile;

wp_reset_postdata();

Page 19: Everything You Need to Know About WP_Query, WordCamp Russia 2014

● Зачем нужны wp_reset_postdata() и wp_reset_query()?● Что насчёт query_posts()?● Как изменить запрос?● Как изменить основной запрос?

Page 20: Everything You Need to Know About WP_Query, WordCamp Russia 2014

Что такое основной запрос,и почему это важно?

Page 21: Everything You Need to Know About WP_Query, WordCamp Russia 2014

wp-blog-header.php

// Загружаем окружение WordPress

require './wp-load.php';

// Определяем, какие файлы шаблонов подключить

require WPINC . '/template-loader.php';

Page 22: Everything You Need to Know About WP_Query, WordCamp Russia 2014

Что происходит при загрузке?

$wp_the_query = new WP_Query();

$wp_query =& $wp_the_query;

Page 23: Everything You Need to Know About WP_Query, WordCamp Russia 2014

Немного о ссылках в PHP

$a = 4;

$b =& $a;

$b = 2;

var_dump( $a ); // int(2)

$a = 6;

var_dump( $b ); // int(6)

Page 24: Everything You Need to Know About WP_Query, WordCamp Russia 2014

● Основной запрос хранится в $wp_the_query.● Его копия хранится в $wp_query.

Page 25: Everything You Need to Know About WP_Query, WordCamp Russia 2014

wp-blog-header.php

// Загружаем окружение WordPress

require './wp-load.php';

// Определяем, какие файлы шаблонов подключить

require WPINC . '/template-loader.php';

Page 26: Everything You Need to Know About WP_Query, WordCamp Russia 2014

wp-blog-header.php

// Загружаем окружение WordPress

require './wp-load.php';

// Всё происходит здесь

wp();

// Определяем, какие файлы шаблонов подключить

require WPINC . '/template-loader.php';

Page 27: Everything You Need to Know About WP_Query, WordCamp Russia 2014

Что делает вызов wp()?

function wp( $query_vars = '' ) {

global $wp;

$wp->main( $query_vars );

}

Page 28: Everything You Need to Know About WP_Query, WordCamp Russia 2014

Что это было?!

Page 29: Everything You Need to Know About WP_Query, WordCamp Russia 2014

При загрузке

$wp = new WP();

Есть функция wp() и класс WP.

Page 30: Everything You Need to Know About WP_Query, WordCamp Russia 2014

class WP {

function main() {

$this->init();

$this->parse_request();

$this->send_headers();

$this->query_posts();

$this->handle_404();

$this->register_globals();

...

Page 31: Everything You Need to Know About WP_Query, WordCamp Russia 2014

class WP {

function main() {

$this->init();

$this->parse_request();

$this->send_headers();

$this->query_posts();

$this->handle_404();

$this->register_globals();

...

Page 32: Everything You Need to Know About WP_Query, WordCamp Russia 2014

WP::parse_request()● Разбирает URL с помощью WP_Rewrite● Задаёт переменные запроса для WP_Query

WP::query_posts() {

global $wp_the_query;

$wp_the_query->query( $this->query_vars );

}

Page 33: Everything You Need to Know About WP_Query, WordCamp Russia 2014

SELECT SQL_CALC_FOUND_ROWS

wp_posts.*

FROM wp_posts

WHERE 1=1

AND wp_posts.post_type = 'post'

AND wp_posts.post_status = 'publish'

ORDER BY wp_posts.post_date DESC

LIMIT 0, 10

Page 34: Everything You Need to Know About WP_Query, WordCamp Russia 2014

wp-blog-header.php

// Загружаем окружение WordPress

require './wp-load.php';

// Определяем, какие записи нужны, затем запрашиваем их

wp();

// Загружаем тему оформления

require WPINC . '/template-loader.php';

Page 35: Everything You Need to Know About WP_Query, WordCamp Russia 2014

Когда загружается тема оформления,мы уже получили записи.

Page 36: Everything You Need to Know About WP_Query, WordCamp Russia 2014

Тогда зачем делать так?

query_posts( 'author=-5' );

get_header();

while ( have_posts() ) :

the_post();

endwhile;

get_footer();

Page 37: Everything You Need to Know About WP_Query, WordCamp Russia 2014

Получается в два раза больше запросов!

● Первый, который WordPress сделал по умолчанию.● Второй, который мы будем использовать.

Page 38: Everything You Need to Know About WP_Query, WordCamp Russia 2014

* В общем случае WP_Query выполняетне один запрос, а четыре.

Page 39: Everything You Need to Know About WP_Query, WordCamp Russia 2014

1. Получаем записи:SELECTSQL_CALC_FOUND_ROWS …FROM wp_posts LIMIT 0, 10

2. Сколько найдено записей?SELECT FOUND_ROWS()

3. Получаем метаданные для этих записей.

4. Получаем элементы таксономий для этих записей.

Page 40: Everything You Need to Know About WP_Query, WordCamp Russia 2014

(Эти запросы можно выборочно отключить...)

$my_query = new WP_Query( array(

'no_found_rows' => true,

'update_post_meta_cache' => false,

'update_post_term_cache' => false,

) );

Page 41: Everything You Need to Know About WP_Query, WordCamp Russia 2014

Запрос неиспользуемых данныхснижает производительность.

Page 42: Everything You Need to Know About WP_Query, WordCamp Russia 2014

Другие проблемы query_posts()

Page 43: Everything You Need to Know About WP_Query, WordCamp Russia 2014

Не работает постраничная навигация

Параметры навигации WordPress вычисляетдля основного запроса, а не дополнительного.

Page 44: Everything You Need to Know About WP_Query, WordCamp Russia 2014

query_posts( array(

'author' => -5,

'posts_per_page' => 25,

) );

Этот код проблематичен.

Page 45: Everything You Need to Know About WP_Query, WordCamp Russia 2014

Переопределяются глобальные переменные

Это может нарушить работу виджетов, комментариев и т.д.

Page 46: Everything You Need to Know About WP_Query, WordCamp Russia 2014

query_posts() — это плохо

Согласимся?

Page 47: Everything You Need to Know About WP_Query, WordCamp Russia 2014

Действие pre_get_posts

class WP_Query {

function get_posts() {

$this->parse_query();

// Ура!

do_action_ref_array( 'pre_get_posts', array( &$this ) );

Page 48: Everything You Need to Know About WP_Query, WordCamp Russia 2014

function alter_my_home_query( $query ) {

if ( $query->is_home() )

$query->set( 'author', '-5' );

}

add_action( 'pre_get_posts', 'alter_my_home_query' );

Page 49: Everything You Need to Know About WP_Query, WordCamp Russia 2014

Здесь начинаются сложности.

Page 50: Everything You Need to Know About WP_Query, WordCamp Russia 2014

'pre_get_posts' выполняетсядля каждого запроса

● get_posts()● new WP_Query● Виджет последних записей, установленный клиентом без

вашего ведома.● И т.д.

Page 51: Everything You Need to Know About WP_Query, WordCamp Russia 2014

Как изменить только основной запрос?

Page 52: Everything You Need to Know About WP_Query, WordCamp Russia 2014

Триумфальное возвращение $wp_the_query

Page 53: Everything You Need to Know About WP_Query, WordCamp Russia 2014

Метод WP_Query::is_main_query()

class WP_Query {

function is_main_query() {

global $wp_the_query;

return $wp_the_query === $this;

}

Page 54: Everything You Need to Know About WP_Query, WordCamp Russia 2014

Только главный запрос!

function alter_my_home_query( $query ) {

if ( $query->is_home() && $query->is_main_query() )

$query->set( 'author', '-5' );

}

add_action( 'pre_get_posts', 'alter_my_home_query' );

Page 55: Everything You Need to Know About WP_Query, WordCamp Russia 2014

function alter_my_home_query( $query ) {

if ( is_admin() || ! $query->is_main_query() )

return;

if ( $query->is_home() )

$query->set( 'author', '-5' );

}

add_action( 'pre_get_posts', 'alter_my_home_query' );

Page 56: Everything You Need to Know About WP_Query, WordCamp Russia 2014

Как работает WP_Query::is_main_query()?

● $wp_the_query никогда не меняется и всегда содержит основной запрос.

● В $wp_query хранится ссылка на $wp_the_query, если только не используется query_posts().

● Не путать с функцией is_main_query().

Page 57: Everything You Need to Know About WP_Query, WordCamp Russia 2014

query_posts( 'author=-5' );

while ( have_posts() ) :

the_post();

endwhile;

wp_reset_query();

Page 58: Everything You Need to Know About WP_Query, WordCamp Russia 2014

query_posts( 'author=-5' );

while ( have_posts() ) :

the_post();

endwhile;

wp_reset_query();

Page 59: Everything You Need to Know About WP_Query, WordCamp Russia 2014

function query_posts( $query ) {

// Убираем ссылку на $wp_the_query

unset( $wp_query );

$wp_query =& new WP_Query( $query );

return $wp_query;

}

Page 60: Everything You Need to Know About WP_Query, WordCamp Russia 2014

query_posts( 'author=-5' );

while ( have_posts() ) :

the_post();

endwhile;

wp_reset_query();

Page 61: Everything You Need to Know About WP_Query, WordCamp Russia 2014

function wp_reset_query() {

// Восстанавливаем ссылку на $wp_the_query

unset( $wp_query );

$wp_query =& $wp_the_query;

// Восстанавливаем глобальные переменные

wp_reset_postdata();

}

Page 62: Everything You Need to Know About WP_Query, WordCamp Russia 2014

● Вызываете the_post()?wp_reset_query() восстановит $wp_query и глобальные переменные.

● Вызываете $my_query->the_post()?wp_reset_postdata() восстановит глобальные переменные.

Page 63: Everything You Need to Know About WP_Query, WordCamp Russia 2014

Как быть с шаблонами страниц?

Page 64: Everything You Need to Know About WP_Query, WordCamp Russia 2014

/* Template: My Template */

query_posts( $query_string . '&author=-5&posts_per_page=25' );

get_header();

while ( have_posts() ) :

the_post();

endwhile;

Page 65: Everything You Need to Know About WP_Query, WordCamp Russia 2014

function alter_my_template( $query ) {

if ( ! $query->is_main_query() )

return;

if ( ! is_page_template( 'my-template.php' ) )

return;

$query->set( 'author', '-5' );

$query->set( 'posts_per_page', 25 );

}

add_action( 'pre_get_posts', 'alter_my_template' );

Page 66: Everything You Need to Know About WP_Query, WordCamp Russia 2014

Выводы

● У каждого объекта WP_Query есть методы, соответствующие глобальным условным тегам.

● Глобальные условные теги используют $wp_query — основной или текущий запрос.

● $wp_query — это основной запрос, если не используется query_posts(). Восстанавливайте его с помощью wp_reset_query().

Page 67: Everything You Need to Know About WP_Query, WordCamp Russia 2014

В заключение

● 'pre_get_posts' — мощный и гибкий инструмент (при правильном использовании).

● Всегда проверяйте с помощью $query->is_main_query(), что меняете именно основной запрос.

Page 68: Everything You Need to Know About WP_Query, WordCamp Russia 2014

http://sergeybiryukov.ru

@flash_usb

Спасибо! Вопросы?