SlideShare a Scribd company logo
1 of 66
WordCamp Austin 2012
Chris Olbekson

WordPress Consultant
C3M Digital


@Chris_Olbekson on Twitter
chris@c3mdigital.com



WordCamp Austin 2012
The Query, The Whole
Query, & Nothing But
     $the_query
What is the query?
What is the query?
     The Loop
What is the query?
           The Loop
  while( have_posts() ): the_post();
    the_content();
  endwhile;
What is the query?
   WP_Query class
What is the query?
   $wp_query object
class WP_Query
$wp_query object


The WP Class gives the $wp_query object
information that defines the current
request.
class WP_Query
            $wp_query object

The WP Class gives the $wp_query object
information that defines the current
request.

$wp_query determines the query based on
that information and fetches the
requested posts
class WP_Query

class WP {

   function main() {
       $this->init();
       $this->parse_request();
       $this->query_posts();
       $this->handle_404();
       $this->register_globals()




      $wp_query object
class WP_Query

                   Properties
$query, $query_vars, $posts, $post_count,
$current_post, $queried_object_id, etc...
 Booleans: is_single(), is_category(), is_paged(),
etc...
class WP_Query

                   Methods

init(), parse_query(), set( $query_var, $value ),
have_posts(), rewind_posts() etc...
class WP_Query

Interacting with WP_Query
class WP_Query

      Interacting with WP_Query

Before the loop
Altering the query, filters
class WP_Query

      Interacting with WP_Query

During the loop
Conditionals and template tags,
secondary queries, get_sidebar(), more
secondary queries, get_footer().
How do we Query?
How do we Query?
query_posts() alters the main query
How do we Query?
query_posts() alters the main query

new WP_Query() use for secondary queries
How do we Query?
query_posts() alters the main query

new WP_Query() use for secondary queries
 WP_Query - returns an array of post objects
How do we Query?
query_posts() alters the main query

new WP_Query() use for secondary queries
 WP_Query - returns an array of post objects

get_posts() use for secondary queries
How do we Query?
query_posts() alters the main query

new WP_Query() use for secondary queries
 WP_Query - returns an array of post objects

get_posts() use for secondary queries
 get_posts() - wrapper for a separate instance of WP_Query
 returns an array of post objects
How do we Query?
query_posts() alters the main query

new WP_Query() use for secondary queries
 WP_Query - returns an array of post objects

get_posts() use for secondary queries
 get_posts() - wrapper for a separate instance of WP_Query
 returns an array of post objects


$wpdb->roll your own
How do we Query?
query_posts() alters the main query

new WP_Query() use for secondary queries
 WP_Query - returns an array of post objects

get_posts() use for secondary queries
 get_posts() - wrapper for a separate instance of WP_Query
 returns an array of post objects


$wpdb->roll your own
 $wpdb uses the wpdb class to execute any SQL query on the
 WordPress database
Secondary Loops
Secondary Loops
       new WP_Query()

$my_query = new WP_Query();
while( $my_query->have_posts() ):
    $my_query->the_post();
    // do stuff
 endwhile;
Secondary Loops
            get_posts()
get_posts() uses the WP_Query class to
fetch an array of post objects


$post->post_content, $post->post_title
etc...
Secondary Loops
                        get_posts()

$post = get_posts( array(
    ‘posts_per_page’ => 7
! ! ‘cat’ => -3,
));

!       foreach( $posts as $post ) {
            echo $post->post_title;
            echo apply_filters( ‘the_content’, $post->post_content );
    }
Secondary Loops
                    get_posts()

$post = get_posts( array(
    ‘posts_per_page’ => 7
! ! ‘cat’ => -3,
));


/**
 *
 * To make post template tags ie: the_content()
 * available when using get_posts() call the
 * internal function setup_postdata() with the
 * the $post array as its argument
 *
 */
Secondary Loops
                    get_posts()

$post = get_posts( array(
    ‘posts_per_page’ => 7
! ! ‘cat’ => -3,
));


foreach( $posts as $post ) {
!     setup_postdata( $post );
      the_title();
      the_content();
    }
Secondary Loops
                    get_posts()

$post = get_posts( array(
    ‘posts_per_page’ => 7
! ! ‘cat’ => -3,
));



**/
 *
 * After looping through a separate query,
 * wp_reset_postdata() restores the $post global
 * to the current post in the main query
 *
 */
Secondary Loops
                    get_posts()

$post = get_posts( array(
   ‘posts_per_page’ => 7
! ! ‘cat’ => -3,
));

foreach( $posts as $post ) {
!     setup_postdata( $post );
      the_title();
      the_content();
    }
    wp_reset_postdata();
query_posts()
query_posts()

query_posts() sets up The Loop with
query parameters. It also overrides the
current WordPress Loop.
query_posts()

query_posts( array(
   ‘posts_per_page’ => 7
! ! ‘cat’ => -3,
));

if ( have_posts() ) : while ( have_posts() : the_post();
    the_title();
    the_content();
endwhile; endif;
query_posts()

query_posts( array(
   ‘posts_per_page’ => 7
! ! ‘cat’ => -3,
));

**/
 * If you use query_posts() you HAVE to use
 * wp_reset_query() to restore the $post globals
 *
 */
query_posts()

query_posts( array(
   ‘posts_per_page’ => 7
! ! ‘cat’ => -3,
));

if ( have_posts() ) : while ( have_posts() : the_post();
    the_title();
    the_content();
endwhile; endif; wp_reset_query();
query_posts()
      query_posts() alters destroys the
         global $wp_query variables

/**
 *
 * This will cause WordPress to run the query it
 * thought you wanted and the one you’re actually going
 * to use.
 *
 * breaks widgets
 * pagination breaks
 * conditional tags will not work
 * and more...
 *
 */
When should we use
  query_posts()?
query_posts()

The Problem with query_posts() is that it
is always a secondary loop that tries to
be the main one and fails miserably.
When should we use
  query_posts()?
When should we use
  query_posts()?
NEVER USE query_posts()
When should we use
  query_posts()?
NEVER USE query_posts()

     query_posts()
What if I want to alter
       the query?
pre_get_posts()
pre_get_posts()

pre_get_posts fires every time WordPress
fetches posts from the database.

nav menus, new wp_query, query_posts,
get_posts, that slider plugin your client
installed, everything.
What if I only want to
alter the main query?
is_main_query()
is_main_query()

function alter_query( $query ) {
! if ( $query->is_main_query() && $query->is_home() )
! !     $query->set( ‘cat’, ‘-3’ );
}
add_action( ‘pre_get_posts’, ‘alter_query’ );
What happens when we
    run a query?
What happens when we
     run a query?

WordPress actually runs 4 SQL queries
      every time a query is run
$my_query = new WP_Query();
 while( $my_query->have_posts() ):
   $my_query->the_post();
$my_query = new WP_Query();
  while( $my_query->have_posts() ):
     $my_query->the_post();
1)Gets the posts:
  SELECT SQL_CALC_FOUND_ROWS...
  FROM wp_post LIMIT 0, 10
$my_query = new WP_Query();
  while( $my_query->have_posts() ):
     $my_query->the_post();
1)Gets the posts:
  SELECT SQL_CALC_FOUND_ROWS...
  FROM wp_post LIMIT 0, 10

2)Counts the posts for pagination:
  SELECT FOUND_ROWS()
$my_query = new WP_Query();
  while( $my_query->have_posts() ):
     $my_query->the_post();
1)Gets the posts:
  SELECT SQL_CALC_FOUND_ROWS...
  FROM wp_post LIMIT 0, 10

2)Counts the posts for pagination:
  SELECT FOUND_ROWS()

3)Gets all the metadata:
  SELECT post_id, meta_key, meta_value FROM
  wp_postmeta WHERE post_id IN...
$my_query = new WP_Query();
  while( $my_query->have_posts() ):
     $my_query->the_post();
1)Gets the posts:
  SELECT SQL_CALC_FOUND_ROWS...
  FROM wp_post LIMIT 0, 10

2)Counts the posts for pagination:
  SELECT FOUND_ROWS()

3)Gets all the metadata:
  SELECT post_id, meta_key, meta_value FROM
  wp_postmeta WHERE post_id IN...

4)Gets all the terms
 SELECT… AS… INNER JOIN wp_term_taxonomy
 AS... INNER JOIN wp_term_relationships
 AS... ON... IN...
What if I don’t need
pagination, meta, or
       terms?
What if I don’t need
pagination, meta, or
       terms?
You can selectively turn these off
What if I don’t need
pagination, meta, or
       terms?
  You can selectively turn these off

$my_query = new WP_Query( array(
          ‘no_found_rows’ = true,
          ‘update_post_meta_cache’ => false,
          ‘update_post_term_cache’ => false,
          ) );
<review>
$wp_query is always the main query
if you use query_posts(), $wp_query now holds the query
you just created.
<review>
$wp_query is always the main query
if you use query_posts(), $wp_query now holds the query
you just created.

Use pre_get_posts() when you need to alter the main query.
It’s cleaner the “right” way to do it and your clients and
fellow developers will love you.
<review>
$wp_query is always the main query
if you use query_posts(), $wp_query now holds the query
you just created.

Use pre_get_posts() when you need to alter the main query.
It’s cleaner the “right” way to do it and your clients and
fellow developers will love you.

For secondary queries - custom sliders, sidebars, etc...
use get_posts() or create a new WP_Query
<review>
$wp_query is always the main query
if you use query_posts(), $wp_query now holds the query
you just created.

Use pre_get_posts() when you need to alter the main query.
It’s cleaner the “right” way to do it and your clients and
fellow developers will love you.

For secondary queries - custom sliders, sidebars, etc...
use get_posts() or create a new WP_Query

If you call the_post(), or set_up_postdata() use
wp_reset_postdata(). If you have to use query_posts() use
wp_reset_query().
</review>
questions?

More Related Content

What's hot

50 Laravel Tricks in 50 Minutes
50 Laravel Tricks in 50 Minutes50 Laravel Tricks in 50 Minutes
50 Laravel Tricks in 50 MinutesAzim Kurt
 
Tips of CakePHP and MongoDB - Cakefest2011 ichikaway
Tips of CakePHP and MongoDB - Cakefest2011 ichikaway Tips of CakePHP and MongoDB - Cakefest2011 ichikaway
Tips of CakePHP and MongoDB - Cakefest2011 ichikaway ichikaway
 
The Origin of Lithium
The Origin of LithiumThe Origin of Lithium
The Origin of LithiumNate Abele
 
How else can you write the code in PHP?
How else can you write the code in PHP?How else can you write the code in PHP?
How else can you write the code in PHP?Maksym Hopei
 
Как получить чёрный пояс по WordPress?
Как получить чёрный пояс по WordPress?Как получить чёрный пояс по WordPress?
Как получить чёрный пояс по WordPress?Yevhen Kotelnytskyi
 
Как получить чёрный пояс по WordPress? v2.0
Как получить чёрный пояс по WordPress? v2.0Как получить чёрный пояс по WordPress? v2.0
Как получить чёрный пояс по WordPress? v2.0Yevhen Kotelnytskyi
 
The Zen of Lithium
The Zen of LithiumThe Zen of Lithium
The Zen of LithiumNate Abele
 
PHP 5.3 and Lithium: the most rad php framework
PHP 5.3 and Lithium: the most rad php frameworkPHP 5.3 and Lithium: the most rad php framework
PHP 5.3 and Lithium: the most rad php frameworkG Woo
 
Digital Mayflower - Data Pilgrimage with the Drupal Migrate Module
Digital Mayflower - Data Pilgrimage with the Drupal Migrate ModuleDigital Mayflower - Data Pilgrimage with the Drupal Migrate Module
Digital Mayflower - Data Pilgrimage with the Drupal Migrate ModuleErich Beyrent
 
Lithium: The Framework for People Who Hate Frameworks
Lithium: The Framework for People Who Hate FrameworksLithium: The Framework for People Who Hate Frameworks
Lithium: The Framework for People Who Hate FrameworksNate Abele
 
購物車程式架構簡介
購物車程式架構簡介購物車程式架構簡介
購物車程式架構簡介Jace Ju
 
The History of PHPersistence
The History of PHPersistenceThe History of PHPersistence
The History of PHPersistenceHugo Hamon
 
Database Design Patterns
Database Design PatternsDatabase Design Patterns
Database Design PatternsHugo Hamon
 
Temporary Cache Assistance (Transients API): WordCamp Birmingham 2014
Temporary Cache Assistance (Transients API): WordCamp Birmingham 2014Temporary Cache Assistance (Transients API): WordCamp Birmingham 2014
Temporary Cache Assistance (Transients API): WordCamp Birmingham 2014Cliff Seal
 
Building Lithium Apps
Building Lithium AppsBuilding Lithium Apps
Building Lithium AppsNate Abele
 
Building a Pluggable Plugin
Building a Pluggable PluginBuilding a Pluggable Plugin
Building a Pluggable PluginBrandon Dove
 

What's hot (20)

50 Laravel Tricks in 50 Minutes
50 Laravel Tricks in 50 Minutes50 Laravel Tricks in 50 Minutes
50 Laravel Tricks in 50 Minutes
 
Tips of CakePHP and MongoDB - Cakefest2011 ichikaway
Tips of CakePHP and MongoDB - Cakefest2011 ichikaway Tips of CakePHP and MongoDB - Cakefest2011 ichikaway
Tips of CakePHP and MongoDB - Cakefest2011 ichikaway
 
The Origin of Lithium
The Origin of LithiumThe Origin of Lithium
The Origin of Lithium
 
How else can you write the code in PHP?
How else can you write the code in PHP?How else can you write the code in PHP?
How else can you write the code in PHP?
 
Как получить чёрный пояс по WordPress?
Как получить чёрный пояс по WordPress?Как получить чёрный пояс по WordPress?
Как получить чёрный пояс по WordPress?
 
Как получить чёрный пояс по WordPress? v2.0
Как получить чёрный пояс по WordPress? v2.0Как получить чёрный пояс по WordPress? v2.0
Как получить чёрный пояс по WordPress? v2.0
 
CakeFest 2013 keynote
CakeFest 2013 keynoteCakeFest 2013 keynote
CakeFest 2013 keynote
 
The Zen of Lithium
The Zen of LithiumThe Zen of Lithium
The Zen of Lithium
 
PHP 5.3 and Lithium: the most rad php framework
PHP 5.3 and Lithium: the most rad php frameworkPHP 5.3 and Lithium: the most rad php framework
PHP 5.3 and Lithium: the most rad php framework
 
Digital Mayflower - Data Pilgrimage with the Drupal Migrate Module
Digital Mayflower - Data Pilgrimage with the Drupal Migrate ModuleDigital Mayflower - Data Pilgrimage with the Drupal Migrate Module
Digital Mayflower - Data Pilgrimage with the Drupal Migrate Module
 
Lithium: The Framework for People Who Hate Frameworks
Lithium: The Framework for People Who Hate FrameworksLithium: The Framework for People Who Hate Frameworks
Lithium: The Framework for People Who Hate Frameworks
 
Presentation1
Presentation1Presentation1
Presentation1
 
購物車程式架構簡介
購物車程式架構簡介購物車程式架構簡介
購物車程式架構簡介
 
Separation of concerns - DPC12
Separation of concerns - DPC12Separation of concerns - DPC12
Separation of concerns - DPC12
 
The History of PHPersistence
The History of PHPersistenceThe History of PHPersistence
The History of PHPersistence
 
Database Design Patterns
Database Design PatternsDatabase Design Patterns
Database Design Patterns
 
Temporary Cache Assistance (Transients API): WordCamp Birmingham 2014
Temporary Cache Assistance (Transients API): WordCamp Birmingham 2014Temporary Cache Assistance (Transients API): WordCamp Birmingham 2014
Temporary Cache Assistance (Transients API): WordCamp Birmingham 2014
 
Phactory
PhactoryPhactory
Phactory
 
Building Lithium Apps
Building Lithium AppsBuilding Lithium Apps
Building Lithium Apps
 
Building a Pluggable Plugin
Building a Pluggable PluginBuilding a Pluggable Plugin
Building a Pluggable Plugin
 

Similar to The Query the Whole Query and Nothing but the Query

You Don't Know Query - WordCamp Portland 2011
You Don't Know Query - WordCamp Portland 2011You Don't Know Query - WordCamp Portland 2011
You Don't Know Query - WordCamp Portland 2011andrewnacin
 
You don’t know query - WordCamp UK Edinburgh 2012
You don’t know query - WordCamp UK Edinburgh 2012You don’t know query - WordCamp UK Edinburgh 2012
You don’t know query - WordCamp UK Edinburgh 2012l3rady
 
WordPress London 16 May 2012 - You don’t know query
WordPress London 16 May 2012 - You don’t know queryWordPress London 16 May 2012 - You don’t know query
WordPress London 16 May 2012 - You don’t know queryl3rady
 
You Don't Know Query (WordCamp Netherlands 2012)
You Don't Know Query (WordCamp Netherlands 2012)You Don't Know Query (WordCamp Netherlands 2012)
You Don't Know Query (WordCamp Netherlands 2012)andrewnacin
 
WordPress Queries - the right way
WordPress Queries - the right wayWordPress Queries - the right way
WordPress Queries - the right wayAnthony Hortin
 
WP_Query, pre_get_posts, and eliminating query_posts()
WP_Query, pre_get_posts, and eliminating query_posts()WP_Query, pre_get_posts, and eliminating query_posts()
WP_Query, pre_get_posts, and eliminating query_posts()Erick Hitter
 
[WLDN] Supercharging word press development in 2018
[WLDN] Supercharging word press development in 2018[WLDN] Supercharging word press development in 2018
[WLDN] Supercharging word press development in 2018Adam Tomat
 
Wordpress multiple loops
Wordpress multiple loopsWordpress multiple loops
Wordpress multiple loopsRoman Rus
 
Unit testing with zend framework tek11
Unit testing with zend framework tek11Unit testing with zend framework tek11
Unit testing with zend framework tek11Michelangelo van Dam
 
Unit testing with zend framework PHPBenelux
Unit testing with zend framework PHPBeneluxUnit testing with zend framework PHPBenelux
Unit testing with zend framework PHPBeneluxMichelangelo van Dam
 
WordPress for developers - phpday 2011
WordPress for developers -  phpday 2011WordPress for developers -  phpday 2011
WordPress for developers - phpday 2011Maurizio Pelizzone
 
WordPress as an application framework
WordPress as an application frameworkWordPress as an application framework
WordPress as an application frameworkDustin Filippini
 
Difference between mysql_fetch_array and mysql_fetch_assoc in PHP
Difference between mysql_fetch_array and mysql_fetch_assoc in PHPDifference between mysql_fetch_array and mysql_fetch_assoc in PHP
Difference between mysql_fetch_array and mysql_fetch_assoc in PHPVineet Kumar Saini
 
Working with WP_Query in WordPress
Working with WP_Query in WordPressWorking with WP_Query in WordPress
Working with WP_Query in WordPresstopher1kenobe
 
Getting to The Loop - London Wordpress Meetup July 28th
Getting to The Loop - London Wordpress Meetup  July 28thGetting to The Loop - London Wordpress Meetup  July 28th
Getting to The Loop - London Wordpress Meetup July 28thChris Adams
 
Apostrophe
ApostropheApostrophe
Apostrophetompunk
 
Temporary Cache Assistance (Transients API): WordCamp Phoenix 2014
Temporary Cache Assistance (Transients API): WordCamp Phoenix 2014Temporary Cache Assistance (Transients API): WordCamp Phoenix 2014
Temporary Cache Assistance (Transients API): WordCamp Phoenix 2014Cliff Seal
 

Similar to The Query the Whole Query and Nothing but the Query (20)

You Don't Know Query - WordCamp Portland 2011
You Don't Know Query - WordCamp Portland 2011You Don't Know Query - WordCamp Portland 2011
You Don't Know Query - WordCamp Portland 2011
 
Wp query
Wp queryWp query
Wp query
 
You don’t know query - WordCamp UK Edinburgh 2012
You don’t know query - WordCamp UK Edinburgh 2012You don’t know query - WordCamp UK Edinburgh 2012
You don’t know query - WordCamp UK Edinburgh 2012
 
WordPress London 16 May 2012 - You don’t know query
WordPress London 16 May 2012 - You don’t know queryWordPress London 16 May 2012 - You don’t know query
WordPress London 16 May 2012 - You don’t know query
 
You Don't Know Query (WordCamp Netherlands 2012)
You Don't Know Query (WordCamp Netherlands 2012)You Don't Know Query (WordCamp Netherlands 2012)
You Don't Know Query (WordCamp Netherlands 2012)
 
WordPress Queries - the right way
WordPress Queries - the right wayWordPress Queries - the right way
WordPress Queries - the right way
 
WP_Query, pre_get_posts, and eliminating query_posts()
WP_Query, pre_get_posts, and eliminating query_posts()WP_Query, pre_get_posts, and eliminating query_posts()
WP_Query, pre_get_posts, and eliminating query_posts()
 
[WLDN] Supercharging word press development in 2018
[WLDN] Supercharging word press development in 2018[WLDN] Supercharging word press development in 2018
[WLDN] Supercharging word press development in 2018
 
WP_Query Overview
WP_Query OverviewWP_Query Overview
WP_Query Overview
 
Wordpress multiple loops
Wordpress multiple loopsWordpress multiple loops
Wordpress multiple loops
 
Unit testing zend framework apps
Unit testing zend framework appsUnit testing zend framework apps
Unit testing zend framework apps
 
Unit testing with zend framework tek11
Unit testing with zend framework tek11Unit testing with zend framework tek11
Unit testing with zend framework tek11
 
Unit testing with zend framework PHPBenelux
Unit testing with zend framework PHPBeneluxUnit testing with zend framework PHPBenelux
Unit testing with zend framework PHPBenelux
 
WordPress for developers - phpday 2011
WordPress for developers -  phpday 2011WordPress for developers -  phpday 2011
WordPress for developers - phpday 2011
 
WordPress as an application framework
WordPress as an application frameworkWordPress as an application framework
WordPress as an application framework
 
Difference between mysql_fetch_array and mysql_fetch_assoc in PHP
Difference between mysql_fetch_array and mysql_fetch_assoc in PHPDifference between mysql_fetch_array and mysql_fetch_assoc in PHP
Difference between mysql_fetch_array and mysql_fetch_assoc in PHP
 
Working with WP_Query in WordPress
Working with WP_Query in WordPressWorking with WP_Query in WordPress
Working with WP_Query in WordPress
 
Getting to The Loop - London Wordpress Meetup July 28th
Getting to The Loop - London Wordpress Meetup  July 28thGetting to The Loop - London Wordpress Meetup  July 28th
Getting to The Loop - London Wordpress Meetup July 28th
 
Apostrophe
ApostropheApostrophe
Apostrophe
 
Temporary Cache Assistance (Transients API): WordCamp Phoenix 2014
Temporary Cache Assistance (Transients API): WordCamp Phoenix 2014Temporary Cache Assistance (Transients API): WordCamp Phoenix 2014
Temporary Cache Assistance (Transients API): WordCamp Phoenix 2014
 

More from Chris Olbekson

Magical WordPress Development with Vagrant
Magical WordPress Development with VagrantMagical WordPress Development with Vagrant
Magical WordPress Development with VagrantChris Olbekson
 
Managing themes and server environments with extensible configuration arrays
Managing themes and server environments with extensible configuration arraysManaging themes and server environments with extensible configuration arrays
Managing themes and server environments with extensible configuration arraysChris Olbekson
 
WordPress Houston Meetup - Using WordPress as a CMS
WordPress Houston Meetup - Using WordPress as a CMSWordPress Houston Meetup - Using WordPress as a CMS
WordPress Houston Meetup - Using WordPress as a CMSChris Olbekson
 
Cognac gautier presentation
Cognac gautier   presentationCognac gautier   presentation
Cognac gautier presentationChris Olbekson
 
Theme frameworks & child themes
Theme frameworks & child themesTheme frameworks & child themes
Theme frameworks & child themesChris Olbekson
 
Optimizing WordPress for Performance - WordCamp Houston
Optimizing WordPress for Performance - WordCamp HoustonOptimizing WordPress for Performance - WordCamp Houston
Optimizing WordPress for Performance - WordCamp HoustonChris Olbekson
 

More from Chris Olbekson (6)

Magical WordPress Development with Vagrant
Magical WordPress Development with VagrantMagical WordPress Development with Vagrant
Magical WordPress Development with Vagrant
 
Managing themes and server environments with extensible configuration arrays
Managing themes and server environments with extensible configuration arraysManaging themes and server environments with extensible configuration arrays
Managing themes and server environments with extensible configuration arrays
 
WordPress Houston Meetup - Using WordPress as a CMS
WordPress Houston Meetup - Using WordPress as a CMSWordPress Houston Meetup - Using WordPress as a CMS
WordPress Houston Meetup - Using WordPress as a CMS
 
Cognac gautier presentation
Cognac gautier   presentationCognac gautier   presentation
Cognac gautier presentation
 
Theme frameworks & child themes
Theme frameworks & child themesTheme frameworks & child themes
Theme frameworks & child themes
 
Optimizing WordPress for Performance - WordCamp Houston
Optimizing WordPress for Performance - WordCamp HoustonOptimizing WordPress for Performance - WordCamp Houston
Optimizing WordPress for Performance - WordCamp Houston
 

Recently uploaded

Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)Mark Simos
 
Developer Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQLDeveloper Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQLScyllaDB
 
"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr Bagan"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr BaganFwdays
 
Streamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project SetupStreamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project SetupFlorian Wilhelm
 
Install Stable Diffusion in windows machine
Install Stable Diffusion in windows machineInstall Stable Diffusion in windows machine
Install Stable Diffusion in windows machinePadma Pradeep
 
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024BookNet Canada
 
Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?Mattias Andersson
 
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks..."LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...Fwdays
 
SAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptxSAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptxNavinnSomaal
 
Designing IA for AI - Information Architecture Conference 2024
Designing IA for AI - Information Architecture Conference 2024Designing IA for AI - Information Architecture Conference 2024
Designing IA for AI - Information Architecture Conference 2024Enterprise Knowledge
 
Commit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easyCommit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easyAlfredo García Lavilla
 
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024BookNet Canada
 
My INSURER PTE LTD - Insurtech Innovation Award 2024
My INSURER PTE LTD - Insurtech Innovation Award 2024My INSURER PTE LTD - Insurtech Innovation Award 2024
My INSURER PTE LTD - Insurtech Innovation Award 2024The Digital Insurer
 
Pigging Solutions in Pet Food Manufacturing
Pigging Solutions in Pet Food ManufacturingPigging Solutions in Pet Food Manufacturing
Pigging Solutions in Pet Food ManufacturingPigging Solutions
 
"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii SoldatenkoFwdays
 
Human Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR SystemsHuman Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR SystemsMark Billinghurst
 
Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024Scott Keck-Warren
 
APIForce Zurich 5 April Automation LPDG
APIForce Zurich 5 April  Automation LPDGAPIForce Zurich 5 April  Automation LPDG
APIForce Zurich 5 April Automation LPDGMarianaLemus7
 
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...shyamraj55
 
CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):comworks
 

Recently uploaded (20)

Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
 
Developer Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQLDeveloper Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQL
 
"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr Bagan"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr Bagan
 
Streamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project SetupStreamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project Setup
 
Install Stable Diffusion in windows machine
Install Stable Diffusion in windows machineInstall Stable Diffusion in windows machine
Install Stable Diffusion in windows machine
 
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
 
Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?
 
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks..."LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
 
SAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptxSAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptx
 
Designing IA for AI - Information Architecture Conference 2024
Designing IA for AI - Information Architecture Conference 2024Designing IA for AI - Information Architecture Conference 2024
Designing IA for AI - Information Architecture Conference 2024
 
Commit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easyCommit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easy
 
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
 
My INSURER PTE LTD - Insurtech Innovation Award 2024
My INSURER PTE LTD - Insurtech Innovation Award 2024My INSURER PTE LTD - Insurtech Innovation Award 2024
My INSURER PTE LTD - Insurtech Innovation Award 2024
 
Pigging Solutions in Pet Food Manufacturing
Pigging Solutions in Pet Food ManufacturingPigging Solutions in Pet Food Manufacturing
Pigging Solutions in Pet Food Manufacturing
 
"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko
 
Human Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR SystemsHuman Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR Systems
 
Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024
 
APIForce Zurich 5 April Automation LPDG
APIForce Zurich 5 April  Automation LPDGAPIForce Zurich 5 April  Automation LPDG
APIForce Zurich 5 April Automation LPDG
 
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
 
CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):
 

The Query the Whole Query and Nothing but the Query

  • 2. Chris Olbekson WordPress Consultant C3M Digital @Chris_Olbekson on Twitter chris@c3mdigital.com WordCamp Austin 2012
  • 3. The Query, The Whole Query, & Nothing But $the_query
  • 4. What is the query?
  • 5. What is the query? The Loop
  • 6. What is the query? The Loop while( have_posts() ): the_post(); the_content(); endwhile;
  • 7. What is the query? WP_Query class
  • 8. What is the query? $wp_query object
  • 10. $wp_query object The WP Class gives the $wp_query object information that defines the current request.
  • 11. class WP_Query $wp_query object The WP Class gives the $wp_query object information that defines the current request. $wp_query determines the query based on that information and fetches the requested posts
  • 12. class WP_Query class WP { function main() { $this->init(); $this->parse_request(); $this->query_posts(); $this->handle_404(); $this->register_globals() $wp_query object
  • 13. class WP_Query Properties $query, $query_vars, $posts, $post_count, $current_post, $queried_object_id, etc... Booleans: is_single(), is_category(), is_paged(), etc...
  • 14. class WP_Query Methods init(), parse_query(), set( $query_var, $value ), have_posts(), rewind_posts() etc...
  • 16. class WP_Query Interacting with WP_Query Before the loop Altering the query, filters
  • 17. class WP_Query Interacting with WP_Query During the loop Conditionals and template tags, secondary queries, get_sidebar(), more secondary queries, get_footer().
  • 18. How do we Query?
  • 19. How do we Query? query_posts() alters the main query
  • 20. How do we Query? query_posts() alters the main query new WP_Query() use for secondary queries
  • 21. How do we Query? query_posts() alters the main query new WP_Query() use for secondary queries WP_Query - returns an array of post objects
  • 22. How do we Query? query_posts() alters the main query new WP_Query() use for secondary queries WP_Query - returns an array of post objects get_posts() use for secondary queries
  • 23. How do we Query? query_posts() alters the main query new WP_Query() use for secondary queries WP_Query - returns an array of post objects get_posts() use for secondary queries get_posts() - wrapper for a separate instance of WP_Query returns an array of post objects
  • 24. How do we Query? query_posts() alters the main query new WP_Query() use for secondary queries WP_Query - returns an array of post objects get_posts() use for secondary queries get_posts() - wrapper for a separate instance of WP_Query returns an array of post objects $wpdb->roll your own
  • 25. How do we Query? query_posts() alters the main query new WP_Query() use for secondary queries WP_Query - returns an array of post objects get_posts() use for secondary queries get_posts() - wrapper for a separate instance of WP_Query returns an array of post objects $wpdb->roll your own $wpdb uses the wpdb class to execute any SQL query on the WordPress database
  • 27. Secondary Loops new WP_Query() $my_query = new WP_Query(); while( $my_query->have_posts() ): $my_query->the_post(); // do stuff endwhile;
  • 28. Secondary Loops get_posts() get_posts() uses the WP_Query class to fetch an array of post objects $post->post_content, $post->post_title etc...
  • 29. Secondary Loops get_posts() $post = get_posts( array( ‘posts_per_page’ => 7 ! ! ‘cat’ => -3, )); ! foreach( $posts as $post ) { echo $post->post_title; echo apply_filters( ‘the_content’, $post->post_content ); }
  • 30. Secondary Loops get_posts() $post = get_posts( array( ‘posts_per_page’ => 7 ! ! ‘cat’ => -3, )); /** * * To make post template tags ie: the_content() * available when using get_posts() call the * internal function setup_postdata() with the * the $post array as its argument * */
  • 31. Secondary Loops get_posts() $post = get_posts( array( ‘posts_per_page’ => 7 ! ! ‘cat’ => -3, )); foreach( $posts as $post ) { ! setup_postdata( $post ); the_title(); the_content(); }
  • 32. Secondary Loops get_posts() $post = get_posts( array( ‘posts_per_page’ => 7 ! ! ‘cat’ => -3, )); **/ * * After looping through a separate query, * wp_reset_postdata() restores the $post global * to the current post in the main query * */
  • 33. Secondary Loops get_posts() $post = get_posts( array( ‘posts_per_page’ => 7 ! ! ‘cat’ => -3, )); foreach( $posts as $post ) { ! setup_postdata( $post ); the_title(); the_content(); } wp_reset_postdata();
  • 35. query_posts() query_posts() sets up The Loop with query parameters. It also overrides the current WordPress Loop.
  • 36. query_posts() query_posts( array( ‘posts_per_page’ => 7 ! ! ‘cat’ => -3, )); if ( have_posts() ) : while ( have_posts() : the_post(); the_title(); the_content(); endwhile; endif;
  • 37. query_posts() query_posts( array( ‘posts_per_page’ => 7 ! ! ‘cat’ => -3, )); **/ * If you use query_posts() you HAVE to use * wp_reset_query() to restore the $post globals * */
  • 38. query_posts() query_posts( array( ‘posts_per_page’ => 7 ! ! ‘cat’ => -3, )); if ( have_posts() ) : while ( have_posts() : the_post(); the_title(); the_content(); endwhile; endif; wp_reset_query();
  • 39. query_posts() query_posts() alters destroys the global $wp_query variables /** * * This will cause WordPress to run the query it * thought you wanted and the one you’re actually going * to use. * * breaks widgets * pagination breaks * conditional tags will not work * and more... * */
  • 40. When should we use query_posts()?
  • 41. query_posts() The Problem with query_posts() is that it is always a secondary loop that tries to be the main one and fails miserably.
  • 42. When should we use query_posts()?
  • 43. When should we use query_posts()? NEVER USE query_posts()
  • 44. When should we use query_posts()? NEVER USE query_posts() query_posts()
  • 45. What if I want to alter the query?
  • 47. pre_get_posts() pre_get_posts fires every time WordPress fetches posts from the database. nav menus, new wp_query, query_posts, get_posts, that slider plugin your client installed, everything.
  • 48. What if I only want to alter the main query?
  • 50. is_main_query() function alter_query( $query ) { ! if ( $query->is_main_query() && $query->is_home() ) ! ! $query->set( ‘cat’, ‘-3’ ); } add_action( ‘pre_get_posts’, ‘alter_query’ );
  • 51. What happens when we run a query?
  • 52. What happens when we run a query? WordPress actually runs 4 SQL queries every time a query is run
  • 53. $my_query = new WP_Query(); while( $my_query->have_posts() ): $my_query->the_post();
  • 54. $my_query = new WP_Query(); while( $my_query->have_posts() ): $my_query->the_post(); 1)Gets the posts: SELECT SQL_CALC_FOUND_ROWS... FROM wp_post LIMIT 0, 10
  • 55. $my_query = new WP_Query(); while( $my_query->have_posts() ): $my_query->the_post(); 1)Gets the posts: SELECT SQL_CALC_FOUND_ROWS... FROM wp_post LIMIT 0, 10 2)Counts the posts for pagination: SELECT FOUND_ROWS()
  • 56. $my_query = new WP_Query(); while( $my_query->have_posts() ): $my_query->the_post(); 1)Gets the posts: SELECT SQL_CALC_FOUND_ROWS... FROM wp_post LIMIT 0, 10 2)Counts the posts for pagination: SELECT FOUND_ROWS() 3)Gets all the metadata: SELECT post_id, meta_key, meta_value FROM wp_postmeta WHERE post_id IN...
  • 57. $my_query = new WP_Query(); while( $my_query->have_posts() ): $my_query->the_post(); 1)Gets the posts: SELECT SQL_CALC_FOUND_ROWS... FROM wp_post LIMIT 0, 10 2)Counts the posts for pagination: SELECT FOUND_ROWS() 3)Gets all the metadata: SELECT post_id, meta_key, meta_value FROM wp_postmeta WHERE post_id IN... 4)Gets all the terms SELECT… AS… INNER JOIN wp_term_taxonomy AS... INNER JOIN wp_term_relationships AS... ON... IN...
  • 58. What if I don’t need pagination, meta, or terms?
  • 59. What if I don’t need pagination, meta, or terms? You can selectively turn these off
  • 60. What if I don’t need pagination, meta, or terms? You can selectively turn these off $my_query = new WP_Query( array( ‘no_found_rows’ = true, ‘update_post_meta_cache’ => false, ‘update_post_term_cache’ => false, ) );
  • 61. <review> $wp_query is always the main query if you use query_posts(), $wp_query now holds the query you just created.
  • 62. <review> $wp_query is always the main query if you use query_posts(), $wp_query now holds the query you just created. Use pre_get_posts() when you need to alter the main query. It’s cleaner the “right” way to do it and your clients and fellow developers will love you.
  • 63. <review> $wp_query is always the main query if you use query_posts(), $wp_query now holds the query you just created. Use pre_get_posts() when you need to alter the main query. It’s cleaner the “right” way to do it and your clients and fellow developers will love you. For secondary queries - custom sliders, sidebars, etc... use get_posts() or create a new WP_Query
  • 64. <review> $wp_query is always the main query if you use query_posts(), $wp_query now holds the query you just created. Use pre_get_posts() when you need to alter the main query. It’s cleaner the “right” way to do it and your clients and fellow developers will love you. For secondary queries - custom sliders, sidebars, etc... use get_posts() or create a new WP_Query If you call the_post(), or set_up_postdata() use wp_reset_postdata(). If you have to use query_posts() use wp_reset_query().

Editor's Notes

  1. \n
  2. \n
  3. \n
  4. \n
  5. \n
  6. \n
  7. \n
  8. \n
  9. WP_Query is a class defined in wp-includes/query.php that deals with the intricacies of a request to a WordPress blog. WP class in gives the $wp_query object information defining the current request, and then $wp_query determines what type of query it&apos;s dealing with (possibly a category archive, dated archive, feed, or search), and fetches the requested posts. It retains a lot of information on the request, which can be pulled at a later date.\n
  10. WP_Query is a class defined in wp-includes/query.php that deals with the intricacies of a request to a WordPress blog. The wp-blog-header.php (or the WP class in Version 2.0) gives the $wp_query object information defining the current request, and then $wp_query determines what type of query it&apos;s dealing with (possibly a category archive, dated archive, feed, or search), and fetches the requested posts. It retains a lot of information on the request, which can be pulled at a later date.\n
  11. \n
  12. WP::parse_request()\n- Parses the URL using WP_Rewrite\n- Sets up query variables for WP_Query\n
  13. \n
  14. \n
  15. \n
  16. \n
  17. \n
  18. WP_Query is a class defined in wp-includes/query.php that deals with the intricacies of a request to a WordPress blog. The wp-blog-header.php (or the WP class in Version 2.0) gives the $wp_query object information defining the current request, and then $wp_query determines what type of query it&apos;s dealing with (possibly a category archive, dated archive, feed, or search), and fetches the requested posts. It retains a lot of information on the request, which can be pulled at a later date.\n
  19. WP_Query is a class defined in wp-includes/query.php that deals with the intricacies of a request to a WordPress blog. The wp-blog-header.php (or the WP class in Version 2.0) gives the $wp_query object information defining the current request, and then $wp_query determines what type of query it&apos;s dealing with (possibly a category archive, dated archive, feed, or search), and fetches the requested posts. It retains a lot of information on the request, which can be pulled at a later date.\n
  20. WP_Query is a class defined in wp-includes/query.php that deals with the intricacies of a request to a WordPress blog. The wp-blog-header.php (or the WP class in Version 2.0) gives the $wp_query object information defining the current request, and then $wp_query determines what type of query it&apos;s dealing with (possibly a category archive, dated archive, feed, or search), and fetches the requested posts. It retains a lot of information on the request, which can be pulled at a later date.\n
  21. WP_Query is a class defined in wp-includes/query.php that deals with the intricacies of a request to a WordPress blog. The wp-blog-header.php (or the WP class in Version 2.0) gives the $wp_query object information defining the current request, and then $wp_query determines what type of query it&apos;s dealing with (possibly a category archive, dated archive, feed, or search), and fetches the requested posts. It retains a lot of information on the request, which can be pulled at a later date.\n
  22. WP_Query is a class defined in wp-includes/query.php that deals with the intricacies of a request to a WordPress blog. The wp-blog-header.php (or the WP class in Version 2.0) gives the $wp_query object information defining the current request, and then $wp_query determines what type of query it&apos;s dealing with (possibly a category archive, dated archive, feed, or search), and fetches the requested posts. It retains a lot of information on the request, which can be pulled at a later date.\n
  23. WP_Query is a class defined in wp-includes/query.php that deals with the intricacies of a request to a WordPress blog. The wp-blog-header.php (or the WP class in Version 2.0) gives the $wp_query object information defining the current request, and then $wp_query determines what type of query it&apos;s dealing with (possibly a category archive, dated archive, feed, or search), and fetches the requested posts. It retains a lot of information on the request, which can be pulled at a later date.\n
  24. WP_Query is a class defined in wp-includes/query.php that deals with the intricacies of a request to a WordPress blog. The wp-blog-header.php (or the WP class in Version 2.0) gives the $wp_query object information defining the current request, and then $wp_query determines what type of query it&apos;s dealing with (possibly a category archive, dated archive, feed, or search), and fetches the requested posts. It retains a lot of information on the request, which can be pulled at a later date.\n
  25. WP_Query is a class defined in wp-includes/query.php that deals with the intricacies of a request to a WordPress blog. The wp-blog-header.php (or the WP class in Version 2.0) gives the $wp_query object information defining the current request, and then $wp_query determines what type of query it&apos;s dealing with (possibly a category archive, dated archive, feed, or search), and fetches the requested posts. It retains a lot of information on the request, which can be pulled at a later date.\n
  26. \n
  27. \n
  28. \n
  29. \n
  30. \n
  31. \n
  32. \n
  33. \n
  34. \n
  35. \n
  36. \n
  37. \n
  38. \n
  39. \n
  40. \n
  41. \n
  42. \n
  43. \n
  44. \n
  45. \n
  46. \n
  47. \n
  48. \n
  49. \n
  50. \n
  51. \n
  52. \n
  53. \n
  54. \n
  55. \n
  56. \n
  57. \n
  58. \n
  59. \n
  60. \n
  61. \n
  62. \n
  63. \n
  64. \n
  65. \n
  66. \n