2026年6月28日

2026年6月28日

WordPressのクラシックテーマをブロックテーマに移行する手順|テンプレート・theme.json・ウィジェット

自作(または自社で保守している)クラシックテーマを、サイトエディターで編集できるブロックテーマに移す手順を説明します。内容は2026年10月時点のWordPressを前提にしています。

既存のクラシックテーマは、いきなり作り直さずに段階的に移すこともできます。どちらの進め方でも、作業はステージング環境で行い、本番に切り替える前に表示とURLを確認してください。

クラシックテーマとブロックテーマの違い

項目 クラシックテーマ ブロックテーマ
テンプレート index.php・single.php などのPHPファイル templates/index.html などのHTMLファイル(ブロックのマークアップ)
ヘッダー・フッター header.php・footer.php parts/header.html・parts/footer.html(テンプレートパーツ)
色・フォント・余白 style.css とカスタマイザー theme.json と、管理画面の「外観」→「エディター」の「スタイル」
メニュー 「外観」→「メニュー」 ナビゲーションブロック
ウィジェット 「外観」→「ウィジェット」 テンプレートやテンプレートパーツに直接ブロックを置く

WordPressは、テーマに templates/index.html があるとブロックテーマとして扱います。最小構成は style.css(テーマ情報のヘッダー)と templates/index.html で、通常は theme.json も置きます。

ステップ1:移行前の準備と現状の把握

WP-CLIが使える環境では、次のコマンドで現状を確認します。

# 有効なテーマを確認する
wp theme list --status=active

# データベースのバックアップを取る
wp db export backup-before-migration.sql

# ウィジェットエリア(サイドバー)の一覧
wp sidebar list

# 特定のウィジェットエリアに置かれているウィジェット(sidebar-1 は上の一覧のIDに置き換える)
wp widget list sidebar-1 --fields=name,id,options

# クラシックメニューの一覧
wp menu list

あわせて、次の点を書き出しておきます。

  • テーマが持っているテンプレートファイル(single.php・page.php・archive.php・404.php など)と、それぞれの表示内容
  • functions.php の add_theme_support()、register_nav_menus()、register_sidebar()、独自のショートコードやフック
  • カスタマイザーで設定している項目(ロゴ、色、「追加CSS」の内容など)

ステップ2:進め方を決める

段階的に移す(クラシックテーマのまま一部をブロック化)

クラシックテーマのままでも、次のことができます。

  • theme.json を追加して、色・フォントサイズのプリセットやコンテンツ幅をブロックエディターに反映する
  • add_theme_support( 'block-template-parts' ); を追加して、テンプレートパーツ(parts/ のHTML)を管理画面で編集できるようにする
  • add_theme_support( 'block-templates' ); で、ブロックで作ったテンプレートを個別の投稿・固定ページに使う(theme.json があるクラシックテーマでは自動で有効になります)

テンプレートパーツは、PHPのテンプレートから block_template_part( 'header' ); で読み込めます。ヘッダーだけ先にブロック化し、本文部分はPHPのまま残す、といった移し方ができます。

新しいブロックテーマとして作り直す

テンプレートの数が少ない場合や、デザインを見直す場合は、ブロックテーマを新しく作り、最後に切り替えるほうが早いことがあります。「Create Block Theme」プラグイン(WordPress.orgの公式プラグインディレクトリにあります)を使うと、空のブロックテーマの作成や、サイトエディターで変更した内容をテーマのファイルに書き出すことができます。

以下の手順は、どちらの進め方でも使う変換の方法です。

ステップ3:header.php をテンプレートパーツに置き換える

クラシックテーマの header.php の例です。

<?php
// 移行前:header.php のヘッダー部分
?>
<header id="site-header">
	<div class="site-branding">
		<?php the_custom_logo(); ?>
		<h1 class="site-title">
			<a href="<?php echo esc_url( home_url( '/' ) ); ?>"><?php bloginfo( 'name' ); ?></a>
		</h1>
	</div>
	<nav>
		<?php wp_nav_menu( array( 'theme_location' => 'primary' ) ); ?>
	</nav>
</header>

ブロックテーマでは、同じ内容を parts/header.html にブロックのマークアップで書きます。ロゴ・サイトのタイトル・メニューは、それぞれ「サイトロゴ」「サイトのタイトル」「ナビゲーション」ブロックに置き換えます。

<!-- wp:group {"style":{"spacing":{"padding":{"top":"1rem","bottom":"1rem"}}},"layout":{"type":"flex","justifyContent":"space-between"}} -->
<div class="wp-block-group" style="padding-top:1rem;padding-bottom:1rem">
<!-- wp:site-logo {"width":120} /-->
<!-- wp:site-title {"level":1} /-->
<!-- wp:navigation {"overlayMenu":"mobile"} /-->
</div>
<!-- /wp:group -->

<header> 要素は、テンプレートからこのパーツを読み込むときに tagName で指定します(次のステップ)。パーツの中でも header を指定すると、<header> が二重になります。

手で書くより、サイトエディターでブロックを並べてから、ブロックの「⋮」メニューの「コピー」やコードエディターでマークアップを取り出すほうが、記述の誤りを防げます。ブロックのマークアップがブロックの保存形式と一致しないと、エディターで「このブロックには、想定されていないか無効なコンテンツが含まれています」と表示されます。

ステップ4:index.php をHTMLテンプレートに置き換える

クラシックテーマの index.php の例です。

<?php
// 移行前:index.php
get_header();
if ( have_posts() ) :
	while ( have_posts() ) :
		the_post();
		get_template_part( 'template-parts/content' );
	endwhile;
	the_posts_pagination();
endif;
get_footer();

ブロックテーマでは templates/index.html に書きます。ループは「クエリーループ」ブロックに置き換え、inherit: true でそのページの本来のクエリー(アーカイブなら、そのアーカイブの投稿)を使います。

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

<!-- wp:group {"tagName":"main","layout":{"type":"constrained"}} -->
<main class="wp-block-group">
<!-- wp:query {"query":{"inherit":true}} -->
<div class="wp-block-query">
<!-- wp:post-template -->
<!-- wp:post-title {"isLink":true} /-->
<!-- wp:post-date /-->
<!-- wp:post-excerpt /-->
<!-- /wp:post-template -->

<!-- wp:query-pagination -->
<!-- wp:query-pagination-previous /-->
<!-- wp:query-pagination-numbers /-->
<!-- wp:query-pagination-next /-->
<!-- /wp:query-pagination -->
</div>
<!-- /wp:query -->
</main>
<!-- /wp:group -->

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

single.php は templates/single.html、page.php は templates/page.html、archive.php は templates/archive.html、404.php は templates/404.html のように、テンプレート階層の名前はそのままで拡張子が .html になります。個別の投稿のテンプレートでは、本文を「コンテンツ」ブロック(<!-- wp:post-content /-->)で表示します。

ステップ5:CSSの色・フォントを theme.json に移す

移行前の style.css の例です。

/* 移行前:style.css の色とフォントの指定 */
:root {
	--color-primary: #0073aa;
	--color-text: #1d2327;
	--font-base: "Noto Sans JP", sans-serif;
}
body {
	font-family: var(--font-base);
	font-size: 16px;
	color: var(--color-text);
}
a {
	color: var(--color-primary);
}

同じ指定を、テーマのフォルダ直下の theme.json に書きます。JSONにはコメントを書けないため、説明はファイルの外に残してください。

{
	"$schema": "https://schemas.wp.org/trunk/theme.json",
	"version": 3,
	"settings": {
		"color": {
			"palette": [
				{ "slug": "primary", "color": "#0073aa", "name": "Primary" },
				{ "slug": "text", "color": "#1d2327", "name": "Text" }
			],
			"defaultPalette": false
		},
		"typography": {
			"fontFamilies": [
				{
					"fontFamily": "\"Noto Sans JP\", sans-serif",
					"slug": "base",
					"name": "Base"
				}
			],
			"defaultFontSizes": false
		},
		"layout": {
			"contentSize": "760px",
			"wideSize": "1200px"
		}
	},
	"styles": {
		"color": {
			"text": "var(--wp--preset--color--text)"
		},
		"typography": {
			"fontFamily": "var(--wp--preset--font-family--base)",
			"fontSize": "1rem"
		},
		"elements": {
			"link": {
				"color": {
					"text": "var(--wp--preset--color--primary)"
				}
			}
		}
	}
}

settings で定義した色は --wp--preset--color--primary のようなCSS変数として出力され、エディターの色の選択肢にも表示されます。"defaultPalette": false と "defaultFontSizes": false は、WordPress標準の色・文字サイズの選択肢を隠す設定です。"Noto Sans JP" は名前を指定しているだけなので、フォントのファイルは別に読み込むか、利用者の端末にあるフォントを使います。

theme.json に移せない細かいCSS(特定のクラスの装飾など)は、style.css に残して読み込みます(ステップ8)。

ステップ6:メニューをナビゲーションブロックに移す

クラシックメニューは、ブロックテーマに切り替えてもデータとして残っています。サイトエディターでヘッダーのナビゲーションブロックを選び、ブロックのメニュー選択から「クラシックメニューをインポート」を選ぶと、既存のメニューをナビゲーションブロックのメニューとして取り込めます。

取り込んだメニューは、それ以降はクラシックメニューとは別のデータとして管理されます。クラシックメニュー側を変更しても、ナビゲーションブロックには反映されません。

ステップ7:ウィジェットの内容をブロックに置き直す

ウィジェットは、投稿(wp_block などの投稿タイプ)ではなく、wp_options テーブルのオプションとして保存されています。どのウィジェットエリアに何が置かれているかは sidebars_widgets に、各ウィジェットの設定は widget_text や widget_block(ブロックのウィジェット)などのオプションに入っています。

ブロックテーマには「外観」→「ウィジェット」の画面がなく、dynamic_sidebar() も使わないため、ブロックテーマに切り替えるとウィジェットは表示されなくなります。データは残りますが、自動では移りません。切り替える前に、ステップ1の wp widget list の結果や画面で内容を控え、テンプレートやテンプレートパーツに同じ内容のブロックを置いてください。

フッターにウィジェットを置いていた場合の parts/footer.html の例です。

<!-- wp:group {"layout":{"type":"constrained"}} -->
<div class="wp-block-group">
<!-- wp:columns -->
<div class="wp-block-columns">
<!-- wp:column -->
<div class="wp-block-column">
<!-- wp:site-title {"level":0} /-->
<!-- wp:site-tagline /-->
</div>
<!-- /wp:column -->

<!-- wp:column -->
<div class="wp-block-column">
<!-- wp:latest-posts {"postsToShow":5} /-->
</div>
<!-- /wp:column -->
</div>
<!-- /wp:columns -->
</div>
<!-- /wp:group -->

よく使われるウィジェットは、「最新の投稿」「カテゴリー」「アーカイブ」「検索」「カスタムHTML」などのブロックに置き換えられます。プラグインが提供していたウィジェットは、そのプラグインがブロックを用意しているかを確認します。

ステップ8:functions.php を整理する

ブロックテーマでは、WordPressが次のテーマサポートを自動で有効にします(wp-includes/theme.php の _add_default_theme_supports())。

  • post-thumbnails
  • responsive-embeds
  • editor-styles
  • html5(コメントフォーム・検索フォームなど)
  • automatic-feed-links

そのため、これらの add_theme_support() は削除できます。一方、ブロックテーマは style.css を自動では読み込まないため、残したCSSは自分で読み込みます。

<?php
// 移行後の functions.php の例
add_action( 'after_setup_theme', function () {
	// エディターにも style.css を読み込む(editor-styles は自動で有効)
	add_editor_style( 'style.css' );
} );

// サイトの表示側に style.css を読み込む
add_action( 'wp_enqueue_scripts', function () {
	wp_enqueue_style(
		'my-theme-style',
		get_stylesheet_uri(),
		array(),
		wp_get_theme()->get( 'Version' )
	);
} );

次のものは、ブロックテーマでは不要になります。

  • register_sidebar() と、テンプレートの dynamic_sidebar()
  • get_header()・get_footer()・get_sidebar() を使うPHPテンプレート
  • add_theme_support( 'customize-selective-refresh-widgets' )
  • カスタマイザー用の設定(customize_register で追加した項目)。ブロックテーマでは、色やフォントは「外観」→「エディター」の「スタイル」で変更します

register_nav_menus() は、クラシックメニューを取り込むまでは残しておいてもかまいません。独自のショートコード、カスタム投稿タイプ、フックなど、表示の仕組みと関係のない処理は、そのまま使えます(テーマから切り離してプラグインに移すことも検討してください)。

ステップ9:切り替えた後に確認すること

  • トップページ、個別の投稿、固定ページ、カテゴリー・タグのアーカイブ、検索結果、404ページがそれぞれ想定どおりに表示されるか
  • <title>、メタディスクリプション、OGP、構造化データなど、SEOプラグインやテーマが出していた <head> の出力が変わっていないか(ブロックテーマでも wp_head() は自動で実行されます)
  • wp_head・wp_footer 以外のテーマ独自のフック(例:get_header を前提にしたプラグインの処理)に依存した機能がないか
  • カスタマイザーの「追加CSS」に書いていたCSSが反映されているか(反映されない場合は、サイトエディターの「スタイル」の追加CSSか style.css に移す)

まとめ

  • ブロックテーマは templates/index.html があるテーマ。PHPテンプレートは同じ名前の .html テンプレートに置き換える
  • ヘッダー・フッターは parts/ のテンプレートパーツにし、<header> などの要素はテンプレートパーツブロックの tagName で指定する
  • 色・フォント・幅は theme.json に移す。JSONにコメントは書けない
  • メニューはナビゲーションブロックの「クラシックメニューをインポート」で取り込む
  • ウィジェットは wp_options に残るが表示されなくなるため、内容を控えてブロックで置き直す
  • post-thumbnails などは自動で有効になる。style.css は自分で読み込む

関連記事:

お気軽にご相談ください

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