WordPressのget_template_part()はどのような仕組みになっているのか?

WordPressで使う上で便利なのがget_template_part()関数ですが、イマイチ使い方を忘れる時があるので、これを機に挙動を調べてみました。

get_template_partの仕組み

<?php get_template_part( $slug, $name ); ?>

get_template_part()は第1引数に読み込みたいテンプレートファイルを指定し、第2引数にテンプレートファイルの名前を指定します。

例えば、以下の様に書いたとき、

<?php get_template_part( 'template-parts/content', 'single' ); ?>

WordPressは最初にtemplate-parts/content-single.phpのファイルが存在しているかを確認し、もしファイルが存在すればそのままファイルを読み込んで処理が終わります。一方で、template-parts/content-single.phpのファイルが存在しない場合は、template-parts/content.phpを読み込みます。

get_template_partのコードを読む

では、具体的な挙動を見たいので、get_template_part()のコードを見ていきます。コードの細かい部分は省略していきますが、詳しくは「WordPress/general-template.php at master · WordPress/WordPress」を見ると良いです。

<?php
function get_template_part( $slug, $name = null ) {
do_action( "get_template_part_{$slug}", $slug, $name );
$templates = array();
$name      = (string) $name;
if ( '' !== $name ) {
$templates[] = "{$slug}-{$name}.php";
}
$templates[] = "{$slug}.php";
do_action( 'get_template_part', $slug, $name, $templates );
locate_template( $templates, true, false );
}

コードを見てみると、$templates配列に第2引数を指定しているファイル名と指定していないファイル名をpushして、最後にlocate_template()`関数に渡してます。

locate_template()関数は、「WordPress/template.php at master · WordPress/WordPress」に書かれています。

<?php
function locate_template( $template_names, $load = false, $require_once = true ) {
$located = '';
foreach ( (array) $template_names as $template_name ) {
if ( ! $template_name ) {
continue;
}
if ( file_exists( STYLESHEETPATH . '/' . $template_name ) ) {
$located = STYLESHEETPATH . '/' . $template_name;
break;
} elseif ( file_exists( TEMPLATEPATH . '/' . $template_name ) ) {
$located = TEMPLATEPATH . '/' . $template_name;
break;
} elseif ( file_exists( ABSPATH . WPINC . '/theme-compat/' . $template_name ) ) {
$located = ABSPATH . WPINC . '/theme-compat/' . $template_name;
break;
}
}
if ( $load && '' != $located ) {
load_template( $located, $require_once );
}
return $located;
}

やっていることは、先ほどファイル名を追加した$templates配列をforeachで回していて、$templatesにテンプレートの絶対パスを付けたファイルが存在するかをチェックしています。

で、最終的に「load_template」のload_template()でファイルをrequireしています。

<?php
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 );
}
}

ReratedPosts

WordPressのapply_filters、do_action、add_filter、add_actionの使い方とか違いとか
WordPressのplugin_basename()とかplugins_url()の使い方のまとめ
WordPressのディレクトリやファイルのパーミッションは何がベストなのか?