How does WordPress load templates?

The short answer:

– go see https://codex.wordpress.org/Template_Hierarchy

However, here’s a worked-out example.

I have a page called News with the slug “news”.  Here’s how WordPress loads the necessary page:

1. Apache runs your root /index.php file

2. This require’s

/wp-blog-header.php

3. wp-blog-header then:

require_once’s wp-load.php

runs wp() and

require_once’s template-loader.php

4. template-loader.php does a few checks and then runs a huge if, elseif:

if ( defined('WP_USE_THEMES') && WP_USE_THEMES ) :
   $template = false;
   if     ( is_404()            && $template = get_404_template()            ) :
   elseif ( is_search()         && $template = get_search_template()         ) :
   elseif ( is_front_page()     && $template = get_front_page_template()     ) :
   elseif ( is_home()           && $template = get_home_template()           ) :
   elseif ( is_post_type_archive() && $template = get_post_type_archive_template() ) :
   elseif ( is_tax()            && $template = get_taxonomy_template()       ) :
   elseif ( is_attachment()     && $template = get_attachment_template()     ) :
      remove_filter('the_content', 'prepend_attachment');
   elseif ( is_single()         && $template = get_single_template()         ) :
   elseif ( is_page()           && $template = get_page_template()           ) :
   elseif ( is_category()       && $template = get_category_template()       ) :
   elseif ( is_tag()            && $template = get_tag_template()            ) :
   elseif ( is_author()         && $template = get_author_template()         ) :
   elseif ( is_date()           && $template = get_date_template()           ) :
   elseif ( is_archive()        && $template = get_archive_template()        ) :
   elseif ( is_comments_popup() && $template = get_comments_popup_template() ) :
   elseif ( is_paged()          && $template = get_paged_template()          ) :
   else :
      $template = get_index_template();
   endif;

Lovely!

It turns out that the example given sets $template to ‘wp-content/themes/<theme name>/page-news.php’.

How does it do that? Well, if we search for the function get_page_templates() it turns out there are 3 occurrences in the WordPress code (in wp-admin/includes/theme.php and in various wp-includes files – class-wp-theme.php, template.php).

So, which one is it using?

The answer:

wp-includes/template.php which returns the value here:

$template = get_page_template_slug();

Where is get_page_template_slug() defined?

In wp-includes/post-template.php. This works out the post using the post_id.

$post = get_post( $post_id );

Then it works out the template using get_post_meta() (which is defined in post.php).

get_post_meta simply returns the result of another function get_metadata which is defined in meta.php.

The full code:

$post = get_post( $post_id );
if ( ! $post || 'page' != $post->post_type )
   return false;
$template = get_post_meta( $post->ID, '_wp_page_template', true );
if ( ! $template || 'default' == $template )
   return '';
return $template;

In meta.php > get_metadata it checks $meta_key. It cycles through a bunch of values in $meta_cache until it gets to $meta_key = ‘_wp_mf_page_template’.

The code:

if ( isset($meta_cache[$meta_key]) ) {
   if ( $single )
      return maybe_unserialize( $meta_cache[$meta_key][0] );

cycles through the $meta_cache values just to decide the template! I had 343 values!

I literally gave up here as, whilst I spotted a $meta_key = “_wp_page_template” it continued to cycle through the $meta_cache values. Without wasting more time on this I can only assume it found the value here.

 

 

 

 

Leave a Reply

Your email address will not be published. Required fields are marked *