Your browser doesn't support the features required by impress.js, so you are presented with a simplified version of this presentation.

For the best experience please use the latest Chrome, Safari or Firefox browser.

Use a spacebar or arrow keys to navigate

From URL to Query

Erick Hitter

Design Engineer @ Automattic

@ethitter

About Me

Assumptions we'll operate under

The Premise

 

In Short...

Magic

Seriously though

 

 

WordPress contains a number of classes that work together with the help of some procedural glue.

Getting started: index.php

With Pretty Permalinks, requests that don't correspond to actual files on the server are sent to index.php.

Not much going on here:

 

<?php
/**
 * Front to the WordPress application. This file doesn't do anything, but loads
 * wp-blog-header.php which does and tells WordPress to load the theme.
 *
 * @package WordPress
 */

/**
 * Tells WordPress to load the WordPress theme and output it.
 *
 * @var bool
 */
define('WP_USE_THEMES', true);

/** Loads the WordPress Environment and Template */
require('./wp-blog-header.php');

wp-blog-header.php

Not much here either, but what's here is important!

 

<?php
/**
 * Loads the WordPress environment and template.
 *
 * @package WordPress
 */

if ( !isset($wp_did_header) ) {

	$wp_did_header = true;

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

	wp();

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

}

In conclusion…

 

 

You caught those three highlighted lines, right?

 

So we can go home now?

 

 

:)

What do I mean?

Remember the premises?

 

<?php
// Ever wonder what process WordPress undertakes when someone visits your site?
require_once( dirname(__FILE__) . '/wp-load.php' );

// Or how it translates that nice permalink to the database query that ultimately
// delivers the content your visitors requested?
wp();

// Or what it takes to load the appropriate template from your site's theme?
require_once( ABSPATH . WPINC . '/template-loader.php' );

wp-load.php

You'll be shocked to learn that this file starts the process of loading WordPress.

 

But how?

 

Loads wp-config.php, which in turn loads wp-settings.php.

wp-settings.php

Alot happens in here.

wp-settings.php

Up to now, we've mostly been loading additional files, defining constants, and calling an occasional function.

In other words, lots of glue, nothing to stick together, yet.

 

Now, these classes (and more) are instantiated into their global variables.

Actions in wp-settings.php

Their location impacts their use, because only parts of WP are initialized when they fire.

 

So where are we now?

 

 

Now what?

Let's find some posts!

At this point, we're back in wp-blog-header.php.

 

<?php
/**
 * Loads the WordPress environment and template.
 *
 * @package WordPress
 */

if ( !isset($wp_did_header) ) {

	$wp_did_header = true;

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

	wp();

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

}

wp()

Short function name, big responsibilities.

After all, it:

WP::parse_request()

This utilizes WP_Rewrite's rules, which are nothing more than regular expressions.

 

The rules are looped through until a match is found.

The request filter and parse_request action both fire. Both can be used to change the query WP runs next.

 

If a match is found, we have query variables for WP_Query.

If not, we're headed to the homepage.

And now, we query

Using WP_Query and the query variables already determined, WP goes to the database.

Before running the query, the pre_get_posts action fires, providing another opportunity to modify the query.

After running the query, WP sets its conditional tags.

 

Since this is the main query, both $wp_query and $wp_the_query are populated with the query object.

Otherwise, this is no different than using new WP_Query or get_posts().

Now what?

  1. Send some HTTP headers.
  2. Set some global variables.
  3. Fire the wp action.
  4. Carry on.

At this point, WordPress is loaded, queries have run, and it's time to show something to the user.

Home stretch!

Yet again, we're back in wp-blog-header.php.

 

<?php
/**
 * Loads the WordPress environment and template.
 *
 * @package WordPress
 */

if ( !isset($wp_did_header) ) {

	$wp_did_header = true;

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

	wp();

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

}

Welcome to the Template Loader

We have a query, we have a theme, let's put the two together!

 

When WordPress loaded the active theme back in wp-settings.php, it gathered intel about the theme, such as what templates it contains.

Now, it's time to choose the right template for the query.

Template Hierarchy

But how?

Using the known templates in the active theme, WordPress uses its conditional tags to determine which template to use.

 

After determining the template to use, WordPress fires the template_include filter.

 

Finally, WordPress loads the template file, and the theme takes over.

Questions?

Slides are available at https://ethitter.com/.

Check Twitter for a link as well: @ethitter.