2026年5月30日

2026年5月30日

WordPressのカスタムテンプレートをコードで管理する方法(ブロックテーマ・クラシックテーマ)

WordPress のカスタムテンプレートをコードで管理するには、ブロックテーマなら templates フォルダーの HTML ファイルと theme.json の customTemplates、クラシックテーマなら Template Name を書いた PHP ファイルをテーマに置き、Git などで管理します。注意したいのは、サイトエディターで編集したテンプレートはファイルではなくデータベースに保存され、ファイルより優先されることです。この記事では、テンプレートをファイルとして作る手順、データベース側の変更をファイルに戻す方法、投稿への割り当てをコードで行う方法を説明します。

テンプレートがどこに保存されるかを理解する

コードで管理するうえで、最初に押さえておきたいのが保存場所の違いです。

  • テーマのファイル: ブロックテーマでは templates/ に HTML、parts/ にヘッダーやフッターなどのテンプレートパーツを置きます。クラシックテーマでは PHP ファイルです。
  • データベース: サイトエディターで編集・保存すると、その内容は wp_template(テンプレートパーツは wp_template_part)という投稿タイプとしてデータベースに保存されます。

同じテンプレートがファイルとデータベースの両方にある場合、WordPress はデータベース側を使います。そのため「ファイルを書き換えてデプロイしたのに表示が変わらない」という状況が起こります。コードで管理すると決めたら、本番環境ではサイトエディターでテンプレートを保存しない、という運用ルールを合わせて決めておくのが現実的です。

ブロックテーマでカスタムテンプレートを作る

ブロックテーマで「タイトルを表示しない固定ページ」のテンプレートを作る例です。配布テーマを直接編集すると更新で消えるため、自作テーマか子テーマで作業してください。

まず templates/page-no-title.html を作成します。

<!-- wp:template-part {"slug":"header","tagName":"header"} /-->

<!-- wp:group {"tagName":"main","layout":{"type":"constrained"}} -->
<main class="wp-block-group">
	<!-- wp:post-content {"layout":{"type":"constrained"}} /-->
</main>
<!-- /wp:group -->

<!-- wp:template-part {"slug":"footer","tagName":"footer"} /-->

テンプレートの中身はブロックのマークアップです。手で書くとコメントの属性と HTML の不一致で崩れやすいため、ローカル環境のサイトエディターで組み立て、コードエディター表示に切り替えて中身をコピーすると確実性が上がります。header と footer は、parts/ にある同名のテンプレートパーツを指します。

次に、theme.json の customTemplates に登録します。

{
  "$schema": "https://schemas.wp.org/trunk/theme.json",
  "version": 3,
  "customTemplates": [
    {
      "name": "page-no-title",
      "title": "タイトルなしページ",
      "postTypes": [ "page", "post" ]
    }
  ]
}

name はファイル名から .html を除いたもの、title はエディターのテンプレート選択に表示される名前、postTypes はそのテンプレートを選べる投稿タイプです。postTypes を省略すると固定ページだけが対象になります。カスタム投稿タイプで使う場合は、その投稿タイプ名を追加してください。

customTemplates は、投稿の編集画面で選んで使う「任意のテンプレート」のための仕組みです。single.html や page.html、archive-product.html のように、テンプレート階層のルールで自動的に使われるファイルは登録不要で、ファイル名だけで適用されます。

クラシックテーマでカスタムテンプレートを作る

クラシックテーマでは、PHP ファイルの先頭にコメントでテンプレート名を書きます。

<?php
/**
 * Template Name: 幅広レイアウト
 * Template Post Type: post, page
 */

get_header();
?>
<main id="primary" class="site-main is-wide">
	<?php
	while ( have_posts() ) :
		the_post();
		the_title( '<h1 class="entry-title">', '</h1>' );
		the_content();
	endwhile;
	?>
</main>
<?php
get_footer();

Template Post Type を書かないと固定ページ専用になります。ファイルはテーマ直下のほか、page-templates/ のような1階層下のフォルダーに置いても認識されるので、テンプレートが増えてきたらフォルダーにまとめると見通しがよくなります。

サイトエディターでの変更をファイルに戻す

開発中にサイトエディターで調整した内容は、データベースに入ったままではバージョン管理できません。ファイルに戻す方法は主に2つあります。

  1. コードエディターからコピーする: 該当テンプレートをサイトエディターで開き、コードエディター表示の内容をテーマの HTML ファイルに貼り付けます。少数のテンプレートならこれで十分です。
  2. Create Block Theme プラグインを使う: WordPress.org が公開しているプラグインで、サイトエディターでの変更をテーマのファイルに書き出す機能があります。テンプレートやスタイルの変更をまとめて反映したいときに便利です。

ファイルに書き出したら、データベース側のカスタマイズを消して、ファイルが使われる状態に戻します。サイトエディターのテンプレート一覧で、テーマのテンプレートを編集したものにはリセット(カスタマイズの削除)の操作が表示されるので、それを使います。画面の表記は WordPress のバージョンによって変わることがあります(2026年10月現在)。

どのテンプレートがデータベース側で上書きされているかは、WP-CLI で一覧できます。

wp post list --post_type=wp_template,wp_template_part --fields=ID,post_name,post_status,post_modified

ここに出てくるものが、ファイルより優先されているテンプレートです。以前使っていた別のテーマで保存したものも一覧に含まれるため、どのテーマのものかはサイトエディター側でも確認してください。WP-CLI の wp post delete で削除することもできますが、削除するとサイトエディターでの変更は戻せません。実行前にデータベースのバックアップを取り、ファイルへの書き出しが済んでいることを確かめてください。

投稿へのテンプレート割り当てをコードで行う

どのテンプレートを使うかは、各投稿のメタデータ _wp_page_template に保存されています。大量の投稿に同じテンプレートを割り当てたいときは、WP-CLI で設定できます。

# ブロックテーマ: テンプレート名(name)を指定
wp post meta update 123 _wp_page_template page-no-title

# クラシックテーマ: テーマからのファイルパスを指定
wp post meta update 123 _wp_page_template page-templates/wide.php

PHP から投稿を作るときは、wp_insert_post() の引数に page_template を渡せます。存在しないテンプレート名を指定すると割り当てに失敗するため、テーマ側のファイルを先にデプロイしてから実行します。

「特定の条件のときだけ別のテンプレートを使う」といった、投稿ごとの選択ではない切り替えは、クラシックテーマなら template_include フィルターで書けます。

add_filter( 'template_include', function ( $template ) {
	if ( is_singular( 'event' ) && has_term( 'online', 'event_type' ) ) {
		$custom = locate_template( 'templates-custom/single-event-online.php' );
		if ( $custom ) {
			return $custom;
		}
	}
	return $template;
} );

locate_template() は子テーマ、親テーマの順にファイルを探し、見つからなければ空文字を返します。見つからないときに元の $template を返すようにしておくと、ファイルの置き忘れで真っ白な画面になる事態を防げます。

プラグインからテンプレートを提供する

テーマに依存させたくない場合は、プラグインからブロックテンプレートを登録する register_block_template() が WordPress 6.7 で追加されています。

add_action( 'init', function () {
	register_block_template( 'my-plugin//event-landing', array(
		'title'       => 'イベント告知ページ',
		'description' => 'イベント告知用の固定ページテンプレート',
		'content'     => '<!-- wp:template-part {"slug":"header","tagName":"header"} /--><!-- wp:post-content /--><!-- wp:template-part {"slug":"footer","tagName":"footer"} /-->',
		'post_types'  => array( 'page' ),
	) );
} );

第1引数は プラグイン名//テンプレート名 の形式です。ブロックテーマで使う前提の機能なので、クラシックテーマのサイトでは期待どおりに表示されない点に注意してください。

Gitで管理するときの運用

  • テーマ(または子テーマ)のフォルダーをリポジトリにし、templates/・parts/・theme.json を含めてコミットします。
  • 本番環境では、テンプレートの変更をサイトエディターで保存しない運用にします。誤って保存した場合は、前述の WP-CLI の一覧で気づけるよう、デプロイ後の確認手順に組み込んでおくと安心です。
  • デプロイ後に表示が変わらないときは、データベース側の上書き、ページキャッシュ、CDN のキャッシュの順に確認します。

まとめ

  • ブロックテーマのカスタムテンプレートは templates/ の HTML と theme.json の customTemplates で、クラシックテーマは Template Name を書いた PHP で作ります。
  • サイトエディターで保存したテンプレートはデータベースに入り、ファイルより優先されます。
  • データベース側の変更はファイルに書き出してからリセットし、WP-CLI で上書きの有無を確認します。
  • 割り当ては _wp_page_template で管理でき、条件による切り替えは template_include、プラグインからの提供は register_block_template() を使います。

お気軽にご相談ください

お見積りへ お問い合わせへ
▲