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-thumbnailsresponsive-embedseditor-styleshtml5(コメントフォーム・検索フォームなど)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は自分で読み込む
関連記事: