Index: wp-includes/template-loader.php
===================================================================
--- wp-includes/template-loader.php	(revision 14019)
+++ wp-includes/template-loader.php	(working copy)
@@ -18,29 +18,40 @@
 	return;
 endif;
 
-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_tax()            && $template = get_taxonomy_template()       ) :
-	elseif ( is_home()           && $template = get_home_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();
+/**
+ * Locates and loads the template for current page ($wp_query).
+ * 
+ * @since 3.1.0
+ */
+function template_loader() {
+	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_tax()            && $template = get_taxonomy_template()       ) :
+		elseif ( is_home()           && $template = get_home_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;
+		if ( $template = apply_filters( 'template_include', $template ) )
+			include( $template );
+		return;
 	endif;
-	if ( $template = apply_filters( 'template_include', $template ) )
-		include( $template );
-	return;
-endif;
+}
 
+update_template_hierarchy();
+template_loader();
+return;
+
 ?>
\ No newline at end of file
Index: wp-includes/theme.php
===================================================================
--- wp-includes/theme.php	(revision 14019)
+++ wp-includes/theme.php	(working copy)
@@ -989,6 +989,8 @@
  * @return string The template filename if one is located.
  */
 function locate_template($template_names, $load = false) {
+	$template_names = apply_filters('locate_template', $template_names);
+	
 	if ( !is_array($template_names) )
 		return '';
 
@@ -1030,6 +1032,68 @@
 }
 
 /**
+ * Creates a global variable that contains the template hierarchy for the current page.
+ *
+ * Calling update_template_hierarchy() will recalculate the template hierarchy for $wp_query.
+ *
+ * @uses template_loader() Calculates the template hierarchy.
+ * @since 3.1.0
+ */
+function update_template_hierarchy() {
+	global $wp_template_hierarchy;
+	
+	add_filter('locate_template', '_record_template_hierarchy');
+	add_filter('template_include', '_prevent_template_include');
+	$wp_template_hierarchy = array();
+	template_loader();
+	remove_filter('locate_template', '_record_template_hierarchy');
+	remove_filter('template_include', '_prevent_template_include');
+	$wp_template_hierarchy = call_user_func_array('array_merge', $wp_template_hierarchy);
+}
+
+/**
+ * Returns the template hierarchy for the current page.
+ *
+ * @since 3.1.0
+ * 
+ * @return array
+ */
+function get_template_hierarchy() {
+	global $wp_template_hierarchy;
+	return $wp_template_hierarchy;
+}
+
+/**
+ * Private function to modify locate_template() when updating the 
+ * template hierarchy.
+ * 
+ * Records $template_names in $wp_template_hierarchy, then returns false
+ * which causes locate_template() to fail.
+ * 
+ * @since 3.1.0
+ * @access private
+ * 
+ * @param array $template_names Template files to look for in locate_template.
+ * @return array
+ */
+function _record_template_hierarchy( $template_names ) {
+	global $wp_template_hierarchy;
+	$wp_template_hierarchy[] = $template_names;
+	return false;
+}
+
+/**
+ * Private function to prevent including the template when updating the
+ * template hierarchy.
+ * 
+ * @since 3.1.0
+ * @access private
+ * 
+ * @return boolean
+ */
+function _prevent_template_include(){ return false; }
+
+/**
  * Display localized stylesheet link element.
  *
  * @since 2.1.0
Index: wp-includes/general-template.php
===================================================================
--- wp-includes/general-template.php	(revision 14019)
+++ wp-includes/general-template.php	(working copy)
@@ -126,6 +126,35 @@
 }
 
 /**
+ * Load a template from a folder based upon the best match from the template hierarchy.
+ *
+ * Makes it easy for a theme to reuse sections of code in a easy to overload way
+ * for child themes.
+ * 
+ * Includes a template from a folder within a theme based upon the most specific
+ * match from the template hierarchy. If the folder contains no matching files
+ * then no template will be included.
+ *
+ * @uses get_template_hierarchy() To build template file names.
+ * @uses locate_template() To search for template files.
+ * @since 3.1.0
+ *
+ * @param string $folder The name of the folder to be searched.
+ * @return string The file path to the loaded file. The empty string if no file was found.
+ */
+function get_template_module( $folder ) {
+	$template_hierarchy = get_template_hierarchy();
+	$template_names = array();
+	foreach( $template_hierarchy as $template_name ) {
+		$template_names[] = $folder . '/' . $template_name;
+	}
+	$located = locate_template($template_names);
+	if( $located )
+		include( $located );
+	return $located;
+}
+
+/**
  * Display search form.
  *
  * Will first attempt to locate the searchform.php file in either the child or
