diff --git a/src/wp-includes/template-loader.php b/src/wp-includes/template-loader.php
index 42519a22ad..7eaa56eb4b 100644
--- a/src/wp-includes/template-loader.php
+++ b/src/wp-includes/template-loader.php
@@ -46,45 +46,8 @@ if ( is_robots() ) {
 
 if ( wp_using_themes() ) {
 
-	$tag_templates = array(
-		'is_embed'             => 'get_embed_template',
-		'is_404'               => 'get_404_template',
-		'is_search'            => 'get_search_template',
-		'is_front_page'        => 'get_front_page_template',
-		'is_home'              => 'get_home_template',
-		'is_privacy_policy'    => 'get_privacy_policy_template',
-		'is_post_type_archive' => 'get_post_type_archive_template',
-		'is_tax'               => 'get_taxonomy_template',
-		'is_attachment'        => 'get_attachment_template',
-		'is_single'            => 'get_single_template',
-		'is_page'              => 'get_page_template',
-		'is_singular'          => 'get_singular_template',
-		'is_category'          => 'get_category_template',
-		'is_tag'               => 'get_tag_template',
-		'is_author'            => 'get_author_template',
-		'is_date'              => 'get_date_template',
-		'is_archive'           => 'get_archive_template',
-	);
-	$template      = false;
-
-	// Loop through each of the template conditionals, and find the appropriate template file.
-	foreach ( $tag_templates as $tag => $template_getter ) {
-		if ( call_user_func( $tag ) ) {
-			$template = call_user_func( $template_getter );
-		}
-
-		if ( $template ) {
-			if ( 'is_attachment' === $tag ) {
-				remove_filter( 'the_content', 'prepend_attachment' );
-			}
-
-			break;
-		}
-	}
-
-	if ( ! $template ) {
-		$template = get_index_template();
-	}
+	$template_resolution_algorithm = apply_filters( 'template_resolution_algorithm', 'resolve_template_hierarchy' );
+	$template = call_user_func( $template_resolution_algorithm );
 
 	/**
 	 * Filters the path of the current template before including it.
diff --git a/src/wp-includes/template.php b/src/wp-includes/template.php
index 860cbda179..14faa4a54f 100644
--- a/src/wp-includes/template.php
+++ b/src/wp-includes/template.php
@@ -724,3 +724,53 @@ function load_template( $_template_file, $require_once = true ) {
 		require( $_template_file );
 	}
 }
+
+/**
+ * Determines which theme template to use based on the template hierarchy
+ * algorithm.
+ *
+ * @since 5.3.0
+ */
+function resolve_template_hierarchy () {
+	$tag_templates = array(
+		'is_embed'             => 'get_embed_template',
+		'is_404'               => 'get_404_template',
+		'is_search'            => 'get_search_template',
+		'is_front_page'        => 'get_front_page_template',
+		'is_home'              => 'get_home_template',
+		'is_privacy_policy'    => 'get_privacy_policy_template',
+		'is_post_type_archive' => 'get_post_type_archive_template',
+		'is_tax'               => 'get_taxonomy_template',
+		'is_attachment'        => 'get_attachment_template',
+		'is_single'            => 'get_single_template',
+		'is_page'              => 'get_page_template',
+		'is_singular'          => 'get_singular_template',
+		'is_category'          => 'get_category_template',
+		'is_tag'               => 'get_tag_template',
+		'is_author'            => 'get_author_template',
+		'is_date'              => 'get_date_template',
+		'is_archive'           => 'get_archive_template',
+	);
+	$template = false;
+
+	// Loop through each of the template conditionals, and find the appropriate template file.
+	foreach ( $tag_templates as $tag => $template_getter ) {
+		if ( call_user_func( $tag ) ) {
+			$template = call_user_func( $template_getter );
+		}
+
+		if ( $template ) {
+			if ( 'is_attachment' === $tag ) {
+				remove_filter( 'the_content', 'prepend_attachment' );
+			}
+
+			break;
+		}
+	}
+
+	if ( ! $template ) {
+		$template = get_index_template();
+	}
+
+	return $template;
+}
