Index: src/wp-includes/general-template.php
===================================================================
--- src/wp-includes/general-template.php	(revision 42379)
+++ src/wp-includes/general-template.php	(working copy)
@@ -7,6 +7,40 @@
  */
 
 /**
+ * Get a template part's template hierarchy.
+ *
+ * For the $name parameter, if the file is called "{slug}-special.php" then specify
+ * "special".
+ *
+ * @param string $slug The slug name for the generic template.
+ * @param string $name The name of the specialised template.
+ * @return string[] Template part's template hierarchy.
+ */
+function get_template_part_hierarchy( $slug, $name = null ) {
+	$templates      = array();
+	$formatted_name = (string) $name;
+	if ( '' !== $formatted_name ) {
+		$templates[] = "{$slug}-{$formatted_name}.php";
+	}
+
+	$templates[] = "{$slug}.php";
+
+	/**
+	 * Filters the template part template hierarchy.
+	 *
+	 * The dynamic portion of the hook name, `$slug`, refers to the slug name
+	 * for the generic template part.
+	 *
+	 * @param string[]    $templates The template part template hierarchy.
+	 * @param string      $slug The slug name for the generic template.
+	 * @param string|null $name The name of the specialised template.
+	 */
+	$templates = apply_filters( "template_part_{$slug}_template_hierarchy", $templates, $slug, $name );
+
+	return $templates;
+}
+
+/**
  * Load header template.
  *
  * Includes the header template for a theme or if a name is specified then a
@@ -30,14 +64,8 @@
 	 */
 	do_action( 'get_header', $name );
 
-	$templates = array();
-	$name      = (string) $name;
-	if ( '' !== $name ) {
-		$templates[] = "header-{$name}.php";
-	}
+	$templates = get_template_part_hierarchy( 'header', $name );
 
-	$templates[] = 'header.php';
-
 	locate_template( $templates, true );
 }
 
@@ -65,14 +93,8 @@
 	 */
 	do_action( 'get_footer', $name );
 
-	$templates = array();
-	$name      = (string) $name;
-	if ( '' !== $name ) {
-		$templates[] = "footer-{$name}.php";
-	}
+	$templates = get_template_part_hierarchy( 'footer', $name );
 
-	$templates[] = 'footer.php';
-
 	locate_template( $templates, true );
 }
 
@@ -100,14 +122,8 @@
 	 */
 	do_action( 'get_sidebar', $name );
 
-	$templates = array();
-	$name      = (string) $name;
-	if ( '' !== $name ) {
-		$templates[] = "sidebar-{$name}.php";
-	}
+	$templates = get_template_part_hierarchy( 'sidebar', $name );
 
-	$templates[] = 'sidebar.php';
-
 	locate_template( $templates, true );
 }
 
@@ -142,18 +158,12 @@
 	 * @since 3.0.0
 	 *
 	 * @param string      $slug The slug name for the generic template.
-	 * @param string|null $name The name of the specialized template.
+	 * @param string|null $name The name of the specialised template.
 	 */
 	do_action( "get_template_part_{$slug}", $slug, $name );
 
-	$templates = array();
-	$name      = (string) $name;
-	if ( '' !== $name ) {
-		$templates[] = "{$slug}-{$name}.php";
-	}
+	$templates = get_template_part_hierarchy( $slug, $name );
 
-	$templates[] = "{$slug}.php";
-
 	locate_template( $templates, true, false );
 }
 
@@ -202,7 +212,8 @@
 	 */
 	$format = apply_filters( 'search_form_format', $format );
 
-	$search_form_template = locate_template( 'searchform.php' );
+	$template_hierarchy   = get_template_part_hierarchy( 'searchform' );
+	$search_form_template = locate_template( $template_hierarchy );
 	if ( '' != $search_form_template ) {
 		ob_start();
 		require( $search_form_template );
