locate_template()WP 2.7.0

Retrieve the name of the highest priority template file that exists.

Searches in the STYLESHEETPATH before TEMPLATEPATH and wp-includes/theme-compat so that themes which inherit from a parent theme can just overload one file.

1 time — 0.000039 sec (very fast) | 50000 times — 0.16 sec (very fast) | PHP 7.1.2, WP 4.7.3

No Hooks.

Return

String. The template filename if one is located.

Usage

locate_template( $template_names, $load, $require_once, $args );
$template_names(string|array) (required)
Template file(s) to search for, in order.
$load(true|false)
If true the template file will be loaded if it is found.
Default: false
$require_once(true|false)
Whether to require_once or require. Has no effect if $load is false.
Default: true
$args(array)
Additional arguments passed to the template.
Default: empty array

Examples

0

#1 Check for a file before include it

Let's create the possibility to output page content in some special way if necessary. To do this, create a file content-SLAG_PAGE.php in the theme and use its code instead of the function the_content():

$page_name = $post->post_name;
$locate_template = locate_template( "content-$page_name.php" );

if( $locate_template ) {
	// OK, connect the template file
	require $locate_template;

	// or:
	//get_template_part( 'content', $page_name );
}
else {
	// File not found, load content by default
	the_content();
}
0

#2 Getting the file path

echo locate_template( 'header.php' );

//> /home/example.com/public_html/wp-content/themes/pink/header.php
0

#3 Specify sub-folder

In this function you can specify not only the file name, but also the relative path from the theme root:

locate_template( 'inc/filename.php', true );

This code connect the file filename.php, which is located in the folder inc in the directory of the child theme or parent theme if there is no child theme.

0

#4 User-provided Template path and Directory traversal attacks

Note that locate_template() does not prevent directory traversal attacks, so if you’re passing a user-provided template name to the function, be sure to verify that it’s from one of the three appropriate locations:

  1. active theme directory
  2. parent theme directory
  3. /wp-includes/theme-compat/ directory

Example:

$template = locate_template( $template_filename_from_unsanitized_user_input );

// Only allow templates that are in the active theme directory, parent theme
// directory, or the /wp-includes/theme-compat/ directory (prevent directory 
// traversal attacks).
$template_in_theme_or_parent_theme_or_compat = (
	// Template is in current theme folder.
	0 === strpos( realpath( $template ), realpath( STYLESHEETPATH ) ) ||
	// Template is in current or parent theme folder.
	0 === strpos( realpath( $template ), realpath( TEMPLATEPATH ) ) ||
	// Template is in theme-compat folder.
	0 === strpos( realpath( $template ), realpath( ABSPATH . WPINC . '/theme-compat/' ) )
);

if ( $template_in_theme_or_parent_theme_or_compat ) {
	require_once( $template );
}

Changelog

Since 2.7.0 Introduced.
Since 5.5.0 The $args parameter was added.

Code of locate_template() WP 6.0

function locate_template( $template_names, $load = false, $require_once = true, $args = array() ) {
	$located = '';
	foreach ( (array) $template_names as $template_name ) {
		if ( ! $template_name ) {
			continue;
		}
		if ( file_exists( STYLESHEETPATH . '/' . $template_name ) ) {
			$located = STYLESHEETPATH . '/' . $template_name;
			break;
		} elseif ( file_exists( TEMPLATEPATH . '/' . $template_name ) ) {
			$located = TEMPLATEPATH . '/' . $template_name;
			break;
		} elseif ( file_exists( ABSPATH . WPINC . '/theme-compat/' . $template_name ) ) {
			$located = ABSPATH . WPINC . '/theme-compat/' . $template_name;
			break;
		}
	}

	if ( $load && '' !== $located ) {
		load_template( $located, $require_once, $args );
	}

	return $located;
}