 Hey there, and welcome to Learn WordPress. In this tutorial, you're going to learn all about the typical WordPress request lifecycle. You'll learn about the different files that are involved in a typical WordPress request, how they interact with each other, and how the relevant data is queried and finally rendered to the browser. Before you dive into the WordPress request lifecycle, it's important to understand how query strings and permalinks work. A query string is a part of the URL which assigns values to specific parameters. The query string appears at the end of the URL and is indicated by a question mark. For example, the following URL contains a query string. The query string in this example is question mark page ID equals 2. The page ID parameter is assigned the value of 2. A query string can contain multiple parameters, each separated by an ampersand. Typically, a WordPress install has permalinks enabled, which means that the query string is not part of the URL. Instead, the URL is rewritten to look something like this. Either way, the permalink or the query string contains information about the data that needs to be queried. During a typical WordPress request, the query string or permalink will be converted into query variables that WordPress will use to fetch the relevant data. The entry point of any WordPress front-end request is the index.php file. This is the file that will run whenever a request is made to anything not under the wp-admin directory. If permalinks are enabled, the code in the htaccess file will rewrite the request to the index.php file. Here, the wp-use-themes constant is set up, and then the first additional file is required, wp-blog-header. Require is a special PHP statement that will include the contents of the file being required. There is a similar statement in PHP called include. This does the same thing as require. The difference is that using require will throw an error and end execution if the file can't be required. There are also supplementary statements called require once or include once that will only include the file if it's not been included already. The wp-blog-header file sets up the WordPress environment by requiring the wp-load file. It then calls the wp-function, which sets up the WordPress query, and then loads the theme template by requiring the templateloader.php file. The first thing that's defined in wp-load is the abs-path constant, which is used by most plugins as a check to see if the plugin is indeed being run in a WordPress environment. This file then sets up some error reporting levels. After that, it finds and loads the wp-config file, or attempts to redirect to the wp-admin setup-config file to inform the user to create the wp-config file. You'll also note that this code allows the wp-config file to be moved outside of the WordPress directory, which is a common security best practice. By moving the wp-config file outside of the WordPress directory, you can prevent the file from being accessed by a malicious user. The wp-config file is one that you should be familiar with, as it defines the database constants, debugging constants, and any other constants that your WordPress installation might need. Right at the bottom of this file, it then requires the wp-settings file, which sets up the WordPress environment. wp-settings is the file that sets up the WordPress environment. It does quite a lot of work, so this will just be a high level summary of all the things it sets up. First, it sets up some version information. Then it requires all files needed for initialization. Then there are a few functions that set up most default constants. Register is a fatal error handler, if anything goes wrong. Sets things like time zone and fixes server variables. Checks for maintenance mode and checks for debug mode. Next, it requires the core WordPress files needed for the core WordPress functionality. It sets up the database layer and any global database variables, and initializes multi-site if multi-site is enabled. Then if the short init constant is defined and set, it will stop the rest of WordPress being loaded. This is handy if you need to create custom requests which only need the core WordPress functionality, but not things like custom post types or custom taxonomies. It then loads the localization libraries and runs the installer if WordPress is not installed. And then it loads the rest of any WordPress files needed. Eventually, it loads any must-use plugins. These are plugins that WordPress requests must always use and have a special MU plugins directory where they are located. It then loads any network-activated plugins. This is specifically if they are installed on a multi-site. It sets up any specific cookie constants or SSL constants, and then includes a vars.php file which creates any common global variables. Next, it calls two functions which creates the initial taxonomies and custom post types. So this would be page and post post types and any initial taxonomies. This allows these taxonomies and posts to be available to plugins and themes. After that, it registers the theme directory root, and then eventually it loads all the active plugins. You can see it does this by getting any active and valid plugins, looping through them, and then including the main plugin file. After that, it loads pluggable functions. After that, it defines any additional constants which may be required. And then it calls a function which adds magic quotes to any get or post request variables and sets up the request array. Then it creates an instance of the WordPress query object, the WordPress rewrite object, the main WordPress object, the widget factory object, and the user roles object. It then goes ahead and creates any template-related constants and any default text localization domains, creates a locale object, a locale switcher object, and then loads the functions for the active theme, both parent and child themes if necessary. You'll see it does this by getting the active and valid themes, looping through them, and then including the themes functions.php file. It then creates an instance of the wp-site-health object so that it can fire off any cron events, sets up the current user, checks the site's status, and eventually runs the wp-loaded action hook so that any callback functions hooked into that hook can be run. Once the WordPress environment has been set up, the wp function is called. This function determines what needs to be rendered and fetches the relevant data from the database. Inside the function itself, you'll see that it accesses the global wp-wp-query and wp-the-query objects that the settings file created, and then runs the main method on the wp object passing in the query variables. If we go to the main method of the wp-class, you'll see that it runs the init method which calls the wp-getCurrentUser function and sets up the currentUser object. It then runs the wp-passRequest method which passes the request and sets up any query variables based on the request. Inside passRequest, it first matches the request to the rewrite rules and creates the query vars array based on the match rules. If no rewrite rules match, the query vars array is populated based on the request, whether it's a query string or anything else. If the passRequest method returns true, the main method will then query the posts, handle any 404 response, and register any globals. If we dive into query posts, you'll see that it accesses the wp-the-query object, builds the query string, and then queries the data based on the query vars. Inside of buildQueryString, this is where it sets up the query based on permalinks or any query strings or anything else that's been passed. Then looking into the query method of wp-the-query, at first it runs any kind of initialization, passes the arguments, sets the query vars, and then runs the getPosts method. This will then retrieve an array of posts based on the query variables. You'll see it triggers hooks like pre-getPosts so that you can access the query object and make changes should you need to. And then if you scroll through all this code, you will see that it is basically looking for any kind of passed query variables, any parameters, any kind of combinations, and creating the SQL query string that can be run on the database. Eventually, right at the bottom of this function, it returns the current posts array. Going back to the main function of the wp-class, once query posts is run, it'll handle any 404 problems. But this is if no posts are found, it effectively sets any headers for a 404 request. Back to the main method, it'll then send any headers to the browser, and then at last but not least, fire any callbacks hooked into the wp-action hook, passing in the wp-object by reference so that any callbacks can access that object. After all the query data is set up, the template loader is required. This finds and loads the correct template based on the visitor's URL. As you can see, there is a template redirect action hook, which fires before the template is loaded, and allows plugins and themes to interact should they need to. It then checks for certain things. So is a request being made for the robot stock txt file? Is a request being made for the favicon? Is a request being made to an RSS feed? Then perform actions for the RSS feed and exit execution? Or is the request a trackback, in which case include the trackback functionality and exit execution? After that's all checked, it'll loop through each of these template conditionals and find the appropriate template file. You'll see that this is an array of template tags and template functions. Below that, you'll see that it loops through all the tag templates and calls the tag template and then, if a response is true, calls the template getter function to find that template. For example, if the is front page check is run on the current request and it returns true to say yes, this is the front page, it'll call the get front page template function which will go and find the correct template to render for the front page. After that, there is a template include filter that gets fired and then last but not least, the template is included. You'll notice here that it uses the include statement and not require. This means that if that file doesn't exist for whatever reason, the functionality will still continue. If it doesn't find a template file and the current logged in user is an admin user, in other words, they can change themes, it'll then get the theme and report some errors to the admin user. And that's it, the typical WordPress request lifecycle for rendering a postal page. Happy coding!