WordPress 模板加載的核心函數(shù)是load_template ,該函數(shù)的作用是加載主題所需的模板文件,并把展示 WordPress 內(nèi)容需要的全局變量傳入這些文件中,用來顯示主題。該函數(shù)的核心代碼如下,注意代碼中的 global, 引入了全局變量,這就是為什么可以直接在主循環(huán)中使用全局變量的原因。
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 函數(shù) –?load_template 的高級封裝
該函數(shù)使用 locate_template 實現(xiàn)模板文件加載,相當(dāng)于是 locate_template 的一個封裝,看起來比較多余,但其實這在很大程度上方便了開發(fā)者來加載模板。該函數(shù)通過一個簡單的判斷,實現(xiàn)了一個容錯機制,如果指定了特殊的模板,就加載特殊的模板,如果沒有指定,就加載默認(rèn)的模板。
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 函數(shù) – 支持?jǐn)U展的模板加載
很多人會想當(dāng)然,get_header 是 get_template_part 的一個更高級的函數(shù),看了代碼,我們會發(fā)現(xiàn),事實并不是這樣的,get_header 只是一個hook,返回的是一個名為 $templates 的數(shù)組。我們來看一下 get_header 函數(shù)的源代碼。
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');
}
該函數(shù)默認(rèn)包含 header.php 到頁面中,并支持傳入一個字符串來指定特殊的 header 文件,用來實現(xiàn)在不同的頁面顯示不同的頁面頭部信息。如 get_header('home'),引用的就是 header-home.php。
后面的 get_footer 和 get_sidebar 函數(shù)類似,就不多說了。
使用 get_template_part('header') ,get_template_part('header') 同樣可以加載模板,看起來也符合 WordPress 的主題規(guī)范,但是其實這是不對的,因為缺少了 do_action( 'get_header', $name ); 這個hook,會導(dǎo)致一些插件的兼容性問題。
模板加載的優(yōu)先級及使用方法
get_template_part 函數(shù)可以優(yōu)先加載指定的模板文件,如果指定的模板文件不存在,則再加載默認(rèn)文件。如:
get_template_part('content', 'product')
上面的函數(shù)會優(yōu)先加載 content-product.php 文件,如果該文件不存在,就加載默認(rèn)的 content.php 文件。
為什么不直接使用 PHP 的文件包含?
在回答這個問題之前,我們可以從反面思考一個這個問題,為什么不直接能使用 PHP 的文件包含?事實上,使用 PHP 的文件包含也可以達到同樣的目的,我就見過一個設(shè)計很不錯的開發(fā)者使用 include 函數(shù)來實現(xiàn)模板加載,可是 PHP 的文件包含沒有容錯機制,不能實現(xiàn) WordPress 模板加載需要的優(yōu)先級需求。


