4

I'm wondering when does WordPress initiate its main query which sets the global $wp_query and enable us to use has_posts() and the_post() functions. If I create a page using archive template, how does it know how to set its query?

I'm looking at the archive.php in one of the WordPress default themes. They have an archive page but it just calls get_header() and has_posts(), so that means the query is already set. So WordPress routes the url to use the custom post type param in the URL?

If I choose to make custom archive pages, where do I modify the main query? In the new archive template file?

TurtleTread
  • 303
  • 3
  • 11

2 Answers2

3

After plugins and theme functions are loaded, WordPress parses the incoming request into query variables, by going through the list of rewrite rules to find a pattern that matches the request.

There are a number of default rules for the built in types- pages, various archives, single views, pagination, feeds. You can add your own rules or endpoints manually, or register new content types which can auto-generate all those rules for your custom content.

Once the request is converted to query variables, the query is run. In many cases, the results of the query are what determine which template gets loaded.

Then of course the template is loaded, and everything is good.

So that said, there are a number of actions and filters available to let you modify things at every step. To see a more detailed view of the process and what some of those things are, have a look at the Action Reference.

The simplest and most common method is the pre_get_posts action. This exposes the query variables and lets you modify things before the query is run. See WP_Query for a reference of query vars.

If that doesn't satisfy your needs, have a look at the request filter, which allows more radical query manipulation, as it runs directly after query var extraction, before WordPress has made any decisions about the type of request that's happening.

Milo
  • 79,016
  • 4
  • 128
  • 170
2

User Rarst has a very famous answer where he lays out the load process. Looking at this graph whenever wp-blog-header.php gets loaded it calls function wp() which sets up many of WordPress globals like $post and $wp_query. ( Secondary Reference by User Gmazzap )

That's the technical side of things but it looks like the core of your questions is creating your own custom archive pages. WordPress has a Template Hierarchy which allows you to create custom archives for things like Custom Post Types.

Another common way to modify the main query is to use a Hook in your functions.php file called pre_get_posts. This will let you modify the query object before WordPress actually pings to database to get the information which makes it very easy to modify The Loop with different settings. An example could look like this which would modify The Loop to show 20 posts instead of the default 10:

function wpse_265733( $query ) {

    // Don't run on admin
    if( $query->is_admin ) {
        return;
    }

    // Run only on the blog page
    if( is_home() ) {
        $query->set( 'posts_per_page', 20 );    // Set posts per page to 20.
    }

}
add_action( 'pre_get_posts', 'wpse_265733' );
Howdy_McGee
  • 20,901
  • 24
  • 91
  • 177