Wordpress: from url to template file

When you access a url like https://myprogrammingnotes.com/category/uncategorized of a WordPress site, which file does WordPress use to serve the reply? Do not think there is a file called  uncategorized that is put in the directory of category under the home directory of your site. No, as a dynamic website, WordPress does not use files and directories to reflect the path of a url as static sites do.

There is only one file: the index.php in the root directory of your website, that is analogous to the static webpage. The resources represented by other urls are mainly stored in database and retrieved/served  on the fly. index.php takes over all urls, (1)loads many .php files which (2)parse the urls to form a set of query parameters, and query the database using the query parameters. The query result is one or multiple posts, which are used by (3)template files to display. The three steps are in wp-blog-header.php:

if ( !isset($wp_did_header) ) {

  $wp_did_header = true;

  // step1: Load the WordPress library.
  require_once( dirname(__FILE__) . '/wp-load.php' );

  // step2: Set up the WordPress query.
  wp();

  //step3:  Load the theme template.
  require_once( ABSPATH . WPINC . '/template-loader.php' );

}

The key is in the wp() function which brings you into this piece of code:

public function main($query_args = '') {
  $this->init();
  $this->parse_request($query_args);
  $this->send_headers();
  $this->query_posts();
  $this->handle_404();
  $this->register_globals();

  /**
   * Fires once the WordPress environment has been set up.
   *
   * @since 2.1.0
   *
   * @param WP &$this Current WordPress environment instance (passed by reference).
   */
  do_action_ref_array( 'wp', array( &$this ) );
}

This is a member function of class WP in class-wp.php.

The parse_request function will load the rewrite rules(the rewrite_rules option in wp_options table) from database, match url against each rule, if found, form the query parameters. For example,  there is such a rule as:

category/(.+?)/?$=>index.php?category_name=$matches[1]

Our uri “category/uncategorized” is just matched against it(the pattern before =>), so we get the query(the string after =>):  “index.php?category_name=$matches[1]”. The characters before the “?” will be removed to get “category_name=$matches[1]”. And we will use the matched value in $matches[1], i.e., “uncategorized” to replace the “$matches[1]” to get the final query “category_name=uncategorized”, which also goes to the member variable query_vars of class WP,i.e., query_vars[“category_name”]=”uncategorized”.

The query_posts function will use the parameters in query_vars to execute the sql query, which is done in get_posts of class WP_Query. Every taxonomy such as category or post_tag has a query var which is used to search the database. The parse_tax_query function of WP_Query will load all taxonomies and see which one has the query var as specified by query_vars . In this case, it finds the category taxonomy has the matched  query var: category_name. So, the following tax_query of  WP_Query is constructed:

[“taxonomy”=”category”,”field”=>”slug”,”terms”=>”uncategorized”]

and is_category of WP_Query  is set to true. Since it is now determined not to query a single post but a taxonomy, tax_query->get_sql is called to form the final sql. Using the slug of the  taxonomy “uncategorized”, we can look up the term_taxonomy_id of the category. The final sql is :

SELECT SQL_CALC_FOUND_ROWS  wp_posts.ID FROM wp_posts  LEFT JOIN wp_term_relationships ON (wp_posts.ID = wp_term_relationships.object_id) WHERE 1=1  AND (    wp_term_relationships.term_taxonomy_id IN (1) ) AND wp_posts.post_type = 'post' AND (wp_posts.post_status = 'publish') GROUP BY wp_posts.ID ORDER BY wp_posts.post_date DESC LIMIT 0, 10

 

Now, execute this sql to get the post ids that belong to the category: “uncategorized”, then call get_post with the ids as the parameter to get the whole posts.

$this->posts = array_map( 'get_post', $this->posts );

Now, the the content of the requested url(the posts belong to the “uncategorized” category) has been retrieved, it is time to load a template file to display it.

require_once( ABSPATH . WPINC . '/template-loader.php' ); //in wp-blog-header.php

But which template file to use? This actually includes two questions:1) which theme to use? 2) which template file under that theme to use? We have decided the current query is a query for a category, and we have even gotten the information for the  “uncategorized” category. The candidate template files(see get_category_template in template.php) now include “category-{$category->slug}.php”, “category-{$category->term_id}.php”, ‘category.php’. But we cannot find these files in active theme directory. Fortunately, the current query is not only for a category, but also for archive. In get_archive_template, we will look for another candidate template file ‘archive.php’ in active theme directory,  and this time we succeed. Now, we will load ‘archive.php’ to display the content(a list of  posts).

archive.php basically has the following construct:

get_header();
if ( have_posts() ) :
  while ( have_posts() ) : 
    the_post();
    get_template_part( 'content', get_post_format() );
 endwhile;
endif;
get_footer();

Note that only get_header, get_template_part, and get_footer actually output. get_template_part will find and load content.php in active theme’s directory to show the content of every post in the archive.

References:

https://www.wpbeginner.com/wp-tutorials/how-wordpress-actually-works-behind-the-scenes-infographic/

https://tomjn.com/2013/04/19/how-wordpress-gets-from-url-to-template/

 

 

Did you like this?
Tip admin with Cryptocurrency

Donate Bitcoin to admin

Scan to Donate Bitcoin to admin
Scan the QR code or copy the address below into your wallet to send some bitcoin:

Donate Bitcoin Cash to admin

Scan to Donate Bitcoin Cash to admin
Scan the QR code or copy the address below into your wallet to send bitcoin:

Donate Ethereum to admin

Scan to Donate Ethereum to admin
Scan the QR code or copy the address below into your wallet to send some Ether:

Donate Litecoin to admin

Scan to Donate Litecoin to admin
Scan the QR code or copy the address below into your wallet to send some Litecoin:

Donate Monero to admin

Scan to Donate Monero to admin
Scan the QR code or copy the address below into your wallet to send some Monero:

Donate ZCash to admin

Scan to Donate ZCash to admin
Scan the QR code or copy the address below into your wallet to send some ZCash:

Leave a Reply