load_template 和 get_template_part – WordPress 的模板加载,更高级的文件包含

WordPress 模板加载的核心函数是load_template ,该函数的作用是加载主题所需的模板文件,并把展示 WordPress 内容需要的全局变量传入这些文件中,用来显示主题。该函数的核心代码如下,注意代码中的 global, 引入了全局变量,这就是为什么可以直接在主循环中使用全局变量的原因。

function load_template( $_template_file, $require_once = true ) {
	global $posts, $post, $wp_did_header, $wp_query, $wp_rewrite, $wpdb, $wp_version, $wp, $id, $comment, $user_ID;

	if ( is_array( $wp_query->query_vars ) ) {
		extract( $wp_query->query_vars, EXTR_SKIP );
	}

	if ( isset( $s ) ) {
		$s = esc_attr( $s );
	}

	if ( $require_once ) {
		require_once( $_template_file );
	} else {
		require( $_template_file );
	}
}

get_template_part 函数 – load_template 的高级封装
该函数使用 locate_template 实现模板文件加载,相当于是 locate_template 的一个封装,看起来比较多余,但其实这在很大程度上方便了开发者来加载模板。该函数通过一个简单的判断,实现了一个容错机制,如果指定了特殊的模板,就加载特殊的模板,如果没有指定,就加载默认的模板。

function get_template_part( $slug, $name = null ) {
	/**
	 * Fires before the specified template part file is loaded.
	 *
	 * The dynamic portion of the hook name, `$slug`, refers to the slug name
	 * for the generic template part.
	 *
	 * @since 3.0.0
	 *
	 * @param string $slug The slug name for the generic template.
	 * @param string $name The name of the specialized template.
	 */
	do_action( "get_template_part_{$slug}", $slug, $name );

	$templates = array();
	$name = (string) $name;
	if ( '' !== $name )
		$templates[] = "{$slug}-{$name}.php";

	$templates[] = "{$slug}.php";

	locate_template($templates, true, false);
}

get_header 函数 – 支持扩展的模板加载
很多人会想当然,get_header 是 get_template_part 的一个更高级的函数,看了代码,我们会发现,事实并不是这样的,get_header 只是一个hook,返回的是一个名为 $templates 的数组。我们来看一下 get_header 函数的源代码。

function get_header( $name = null ) {
	/**
	 * Fires before the header template file is loaded.
	 *
	 * The hook allows a specific header template file to be used in place of the
	 * default header template file. If your file is called header-new.php,
	 * you would specify the filename in the hook as get_header( 'new' ).
	 *
	 * @since 2.1.0
	 * @since 2.8.0 $name parameter added.
	 *
	 * @param string $name Name of the specific header file to use.
	 */
	do_action( 'get_header', $name );

	$templates = array();
	$name = (string) $name;
	if ( '' !== $name )
		$templates[] = "header-{$name}.php";

	$templates[] = 'header.php';

	// Backward compat code will be removed in a future release
	if ('' == locate_template($templates, true))
		load_template( ABSPATH . WPINC . '/theme-compat/header.php');
}

该函数默认包含 header.php 到页面中,并支持传入一个字符串来指定特殊的 header 文件,用来实现在不同的页面显示不同的页面头部信息。如 get_header(‘home’),引用的就是 header-home.php。
后面的 get_footer 和 get_sidebar 函数类似,就不多说了。
使用 get_template_part(‘header’) ,get_template_part(‘header’) 同样可以加载模板,看起来也符合 WordPress 的主题规范,但是其实这是不对的,因为缺少了 do_action( ‘get_header’, $name ); 这个hook,会导致一些插件的兼容性问题。
模板加载的优先级及使用方法
get_template_part 函数可以优先加载指定的模板文件,如果指定的模板文件不存在,则再加载默认文件。如:

get_template_part('content', 'product')

上面的函数会优先加载 content-product.php 文件,如果该文件不存在,就加载默认的 content.php 文件。
为什么不直接使用 PHP 的文件包含?
在回答这个问题之前,我们可以从反面思考一个这个问题,为什么不直接能使用 PHP 的文件包含?事实上,使用 PHP 的文件包含也可以达到同样的目的,我就见过一个设计很不错的开发者使用 include 函数来实现模板加载,可是 PHP 的文件包含没有容错机制,不能实现 WordPress 模板加载需要的优先级需求。

声明:本站资源绿色无后门无广告,可放心下载。如无特殊说明或标注,均为本站原创发布,转载请注明出处!