wordpress queries - the right way

49
WordPress Queries -the right way #wpmelb Anthony Hortin @maddisondesigns

Upload: anthony-hortin

Post on 08-May-2015

3.524 views

Category:

Art & Photos


2 download

DESCRIPTION

This is a presentation for the November WordPress Melbourne meetup. It shows how to modify your main WordPress query the right way, using the pre_get_posts hook, rather than using query_posts() or even WP_Query().

TRANSCRIPT

Page 1: WordPress Queries - the right way

WordPress Queries-the right way

#wpmelbAnthony Hortin

@maddisondesigns

Page 2: WordPress Queries - the right way

How you’re probably querying

query_posts()

get_posts()

new WP_Query()

Page 3: WordPress Queries - the right way

You’re doing it wrong!

Page 4: WordPress Queries - the right way

if ( have_posts() ) :

while ( have_posts() ) :

the_post();

endwhile;

endif;

The Loop

Page 5: WordPress Queries - the right way

if ( have_posts() ) // Determines if there’s anything to iterate while ( have_posts() ) :

the_post();

endwhile;

endif;

The Loop

Page 6: WordPress Queries - the right way

if ( have_posts() )

while ( have_posts() ) : // Sets up globals & continues iteration the_post();

endwhile;

endif;

The Loop

Page 7: WordPress Queries - the right way

Anatomy of a WordPress Page

The Main Query

Page 8: WordPress Queries - the right way

// Loads the WordPress bootstrap// ie. Sets the ABSPATH constant.// Loads the wp-config.php file etc.

require_once( dirname(__FILE__) . '/wp-load.php' );

wp();

// Decide which template files to load// ie. archive.php, index.php etc

require_once( ABSPATH . WPINC . '/template-loader.php' );

wp-blog-header.php

Page 9: WordPress Queries - the right way

// Loads the WordPress bootstrap// ie. Sets the ABSPATH constant.// Loads the wp-config.php file etc.

require_once( dirname(__FILE__) . '/wp-load.php' );

wp();

// Decide which template files to load// ie. archive.php, index.php etc

require_once( ABSPATH . WPINC . '/template-loader.php' );

wp-blog-header.php

Page 10: WordPress Queries - the right way

// Loads the WordPress bootstrap// ie. Sets the ABSPATH constant.// Loads the wp-config.php file etc.

require_once( dirname(__FILE__) . '/wp-load.php' );

wp();

// Decide which template files to load// ie. archive.php, index.php etc

require_once( ABSPATH . WPINC . '/template-loader.php' );

wp-blog-header.php

Page 11: WordPress Queries - the right way

// Loads the WordPress bootstrap// ie. Sets the ABSPATH constant.// Loads the wp-config.php file etc.

require_once( dirname(__FILE__) . '/wp-load.php' );

// Does ALL THE THINGS!

wp();

// Decide which template files to load// ie. archive.php, index.php etc

require_once( ABSPATH . WPINC . '/template-loader.php' );

wp-blog-header.php

Page 12: WordPress Queries - the right way

What is wp()?

wp();

- Parses the URL & runs it through WP_Rewrite

- Sets up query variables for WP_Query

- Runs the query

Page 13: WordPress Queries - the right way

What is wp()?

wp();

- Parses the URL & runs it through WP_Rewrite

- Sets up query variables for WP_Query

- Runs the query

Page 14: WordPress Queries - the right way

What is wp()?

wp();

- Parses the URL & runs it through WP_Rewrite

- Sets up query variables for WP_Query

- Runs the query

Page 15: WordPress Queries - the right way

What is wp()?

wp();

- Parses the URL & runs it through WP_Rewrite

- Sets up query variables for WP_Query

- Runs the query

Page 16: WordPress Queries - the right way

So, what does this mean?

Page 17: WordPress Queries - the right way

It means...

Before the theme is even loaded,

WordPress already has your Posts!

Page 18: WordPress Queries - the right way

Mind == Blown!

Page 19: WordPress Queries - the right way

In the bootstrap

$wp_the_query = new WP_Query();

$wp_query =& $wp_the_query;

Page 20: WordPress Queries - the right way

In the bootstrap

// Holds the real main query.// It should never be modified

$wp_the_query

// A live reference to the main query

$wp_query

Page 21: WordPress Queries - the right way

In the bootstrap

// Holds the real main query.// It should never be modified

$wp_the_query

// A live reference to the main query

$wp_query

Page 22: WordPress Queries - the right way

Back to our queries...

Page 23: WordPress Queries - the right way

query_posts()

get_posts()

new WP_Query()

All three create new WP_Query objects

Page 24: WordPress Queries - the right way

query_posts()goes one step further though

Page 25: WordPress Queries - the right way

query_posts()

function &query_posts($query) {

unset($GLOBALS['wp_query']);

$GLOBALS['wp_query'] = new WP_Query();

return $GLOBALS['wp_query']->query($query);

}

Page 26: WordPress Queries - the right way

query_posts()

function &query_posts($query) { // Destroys the Global $wp_query variable! unset($GLOBALS['wp_query']);

$GLOBALS['wp_query'] = new WP_Query();

return $GLOBALS['wp_query']->query($query);

}

Page 27: WordPress Queries - the right way

query_posts()

function &query_posts($query) {

unset($GLOBALS['wp_query']); // Creates new $wp_query variable $GLOBALS['wp_query'] = new WP_Query();

return $GLOBALS['wp_query']->query($query);

}

Page 28: WordPress Queries - the right way

I’m sure you’ve all done this...

get_header();

query_posts( 'cat=-1,-2,-3' );

while( have_posts() ) :

the_post();

endwhile;

wp_reset_query();

get_footer();

Page 29: WordPress Queries - the right way

That’s running 2* queries!

Page 30: WordPress Queries - the right way

It’s running the query WordPress

thinks you want.

It’s then running your new query

you actually want.

That’s running 2* queries!

Page 31: WordPress Queries - the right way

In actual fact, WP_Querydoesn’t just run one query.It runs four!

So, that means your template

is actually running eight queries!

*

Page 32: WordPress Queries - the right way

Don’t forget to reset

// Restores the $wp_query reference to $wp_the_query

// Resets the globals

wp_reset_query();

// Resets the globals

wp_reset_postdata();

Page 33: WordPress Queries - the right way

There’s a better way

Page 34: WordPress Queries - the right way

Say hello to pre_get_posts

[From the Codex]

The pre_get_posts action gives developers access to the $query object by reference.(any changes you make to $query are made directly to the original object)

Page 35: WordPress Queries - the right way

Say hello to pre_get_posts

What this means is we can change our main query before it’s run

Page 36: WordPress Queries - the right way

pre_get_posts

pre_get_posts fires for every post query:

— get_posts()— new WP_Query()— Sidebar widgets— Admin screen queries— Everything!

Page 37: WordPress Queries - the right way

How do we use it?

Page 38: WordPress Queries - the right way

function my_pre_get_posts( $query ) {

// Check if the main query and home and not admin

if ( $query->is_main_query() && is_home() && !is_admin() ) {

// Display only posts that belong to a certain Category

$query->set( 'category_name', 'fatuity' );

// Display only 3 posts per page

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

return;

}

}

// Add our function to the pre_get_posts hook

add_action( 'pre_get_posts', 'my_pre_get_posts' );

In functions.php[example 1]

Page 39: WordPress Queries - the right way

function my_pre_get_posts( $query ) {

// Check if the main query and home and not admin

if ( $query->is_main_query() && is_home() && !is_admin() ) {

// Display only posts that belong to a certain Category

$query->set( 'category_name', 'fatuity' );

// Display only 3 posts per page

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

return;

}

}

// Add our function to the pre_get_posts hook

add_action( 'pre_get_posts', 'my_pre_get_posts' );

In functions.php[example 1]

Page 40: WordPress Queries - the right way

function my_pre_get_posts( $query ) {

// Check if the main query and home and not admin

if ( $query->is_main_query() && is_home() && !is_admin() ) {

// Display only posts that belong to a certain Category

$query->set( 'category_name', 'fatuity' );

// Display only 3 posts per page

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

return;

}

}

// Add our function to the pre_get_posts hook

add_action( 'pre_get_posts', 'my_pre_get_posts' );

In functions.php[example 1]

Page 41: WordPress Queries - the right way

function my_pre_get_posts( $query ) {

// Check if the main query and home and not admin

if ( $query->is_main_query() && is_home() && !is_admin() ) {

// Display only posts that belong to a certain Category

$query->set( 'category_name', 'fatuity' );

// Display only 3 posts per page

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

return;

}

}

// Add our function to the pre_get_posts hook

add_action( 'pre_get_posts', 'my_pre_get_posts' );

In functions.php[example 1]

Page 42: WordPress Queries - the right way

In functions.php[example 1]function my_pre_get_posts( $query ) {

// Check if the main query and home and not admin

if ( $query->is_main_query() && is_home() && !is_admin() ) {

// Display only posts that belong to a certain Category

$query->set( 'category_name', 'fatuity' );

// Display only 3 posts per page

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

return;

}

}

// Add our function to the pre_get_posts hook

add_action( 'pre_get_posts', 'my_pre_get_posts' );

Page 43: WordPress Queries - the right way

In functions.php[example 2]function my_pre_get_posts( $query ) {

// Check if the main query and movie CPT archive and not admin

if($query->is_main_query() && is_post_type_archive('movie') && !is_admin()){

// Display only posts from a certain taxonomies

$query->set( 'tax_query', array( array( 'taxonomy' => 'genre', 'field' => 'slug', 'terms' => array ( 'fantasy', 'sci-fi' ) ) ) );

return; }

}

// Add our function to the pre_get_posts hook

add_action( 'pre_get_posts', 'my_pre_get_posts' );

Page 44: WordPress Queries - the right way

In functions.php[example 2]function my_pre_get_posts( $query ) {

// Check if the main query and movie CPT archive and not admin

if($query->is_main_query() && is_post_type_archive('movie') && !is_admin()){

// Display only posts from a certain taxonomies

$query->set( 'tax_query', array( array( 'taxonomy' => 'genre', 'field' => 'slug', 'terms' => array ( 'fantasy', 'sci-fi' ) ) ) );

return; }

}

// Add our function to the pre_get_posts hook

add_action( 'pre_get_posts', 'my_pre_get_posts' );

Page 45: WordPress Queries - the right way

In functions.php[example 2]function my_pre_get_posts( $query ) {

// Check if the main query and movie CPT archive and not admin

if($query->is_main_query() && is_post_type_archive('movie') && !is_admin()){

// Display only posts from a certain taxonomies

$query->set( 'tax_query', array( array( 'taxonomy' => 'genre', 'field' => 'slug', 'terms' => array ( 'fantasy', 'sci-fi' ) ) ) );

return; }

}

// Add our function to the pre_get_posts hook

add_action( 'pre_get_posts', 'my_pre_get_posts' );

Page 46: WordPress Queries - the right way

In functions.php[example 2]function my_pre_get_posts( $query ) {

// Check if the main query and movie CPT archive and not admin

if($query->is_main_query() && is_post_type_archive('movie') && !is_admin()){

// Display only posts from a certain taxonomies

$query->set( 'tax_query', array( array( 'taxonomy' => 'genre', 'field' => 'slug', 'terms' => array ( 'fantasy', 'sci-fi' ) ) ) );

return; }

}

// Add our function to the pre_get_posts hook

add_action( 'pre_get_posts', 'my_pre_get_posts' );

Page 47: WordPress Queries - the right way

Remember...

Do:— Use pre_get_posts— Check if it’s the main query by using is_main_query()— Check it’s not an admin query by using is_admin()— Check for specific templates using is_home(), etc..— Set up your query using same parameters as WP_Query()

Don’t:— Use query_posts()unless you have a very good reason AND you use wp_reset_query()

( if you really need a secondary query, use new WP_Query() )

Page 48: WordPress Queries - the right way

References

// You Don’t Know Query - Andrew Nacinhttp://wordpress.tv/2012/06/15/andrew-nacin-wp_query

http://www.slideshare.net/andrewnacin/you-dont-know-query-wordcamp-portland-2011

// Make sense of WP Query functionshttp://bit.ly/wpsequery

// Querying Posts Without query_postshttp://developer.wordpress.com/2012/05/14/querying-posts-without-query_posts

// pre_get_posts on the WordPress Codexhttp://codex.wordpress.org/Plugin_API/Action_Reference/pre_get_posts

// Example code on Githubhttps://github.com/maddisondesigns/wpmelb-nov

Page 49: WordPress Queries - the right way

That’s all folks!☺

Thanks! Questions?