Claude Media
Claude Codeでブロックテーマに変換 — functions.phpをtheme.jsonへ写す

Claude Codeでブロックテーマに変換 — functions.phpをtheme.jsonへ写す

WordPressのクラシックテーマをブロックテーマへ移す作業をClaude Codeに任せる手順。add_theme_supportをtheme.jsonへ写し、PHPテンプレートをtemplates/*.htmlに分解します。

クラシックテーマのブロックテーマ化は、一度に全部をClaude Codeへ投げると失敗しやすい作業です。functions.php の設定は機械的に写せますが、header.php や single.php の分解は見た目の確認が欠かせないからです。

この記事は作業を3つに割ります。add_theme_support を theme.json へ写す工程、PHPテンプレートを templates/*.html と parts/*.html に置き換える工程、WordPressの管理画面で確かめる工程です。前の2つはClaude Codeに任せやすく、最後の1つは人が見ます。

テーマを一から作る話はClaude CodeのBuild with WordPressプラグインでテーマを作るにあります。ここでは、すでに動いているクラシックテーマを壊さずに移す側を扱います。

変換で何が何に置き換わるか

ブロックテーマとクラシックテーマの違いは、テンプレートの書き方と設定の置き場所にあります。クラシックテーマはPHPベースのテンプレートで、ブロックテーマはブロックマークアップを含むHTMLファイルです。ブロックテーマで使うテンプレートは templates フォルダー、部品は parts フォルダーに置きます。

対応は次のように整理できます。

クラシックテーマ側ブロックテーマ側Claude Codeに任せやすいか
add_theme_support の各種宣言ブロックテーマ側theme.json の settingsClaude Codeに任せやすいか任せやすい(機械的に写せる)
色・フォントの指定(CSS)ブロックテーマ側theme.json の styles と settings のプリセットClaude Codeに任せやすいか一部任せられる
header.php / footer.phpブロックテーマ側parts/header.html / parts/footer.htmlClaude Codeに任せやすいか構造は任せられる、見た目は人が確認
index.php / single.php などブロックテーマ側templates/index.html / templates/singular.html などClaude Codeに任せやすいか同上
ページテンプレート(Template Name: コメント)ブロックテーマ側カスタムテンプレート + theme.json の customTemplatesClaude Codeに任せやすいか任せられる
テーマ内の機能(ショートコード、投稿タイプ)ブロックテーマ側プラグインへ分離Claude Codeに任せやすいか設計判断が要る

最後の行は、変換の話からは外れて見えますが重要です。WordPressのテーマハンドブックは、テーマが表示を、プラグインが機能を担うのが望ましいとしています。サイトに欠かせない機能をテーマに入れると、テーマを変えたときに失われるためです。ブロックテーマへ移す機会に、functions.php に溜まった機能コードをプラグイン側へ出す判断も入ってきます。

全部変換するか、ハイブリッドで止めるか

最初に決めるのは到達点です。theme.json はクラシックテーマにもブロックテーマにも使えるファイルです。クラシックテーマが theme.json やテンプレートパーツといったブロック関連の機能を取り入れた状態は、コミュニティでハイブリッドテーマと呼ばれています。公式の分類ではなく、実体はクラシックテーマのままです。

到達点は次の3段階で考えると指示が書きやすくなります。

  1. theme.json を足すだけ。PHPテンプレートはそのまま(ハイブリッド)
  2. 一部のテンプレートパーツだけHTML化する
  3. templates/index.html を置き、ブロックテーマとして動かす

index.html は、ブロックテーマに必須の唯一のテンプレートです。このファイルがあることで、WordPressはそのテーマをブロックテーマと判断します。つまり3段階目に進む瞬間は、index.html を置いた時点です。ここから先、PHPのテンプレートは使われなくなります。

最初は1段階目で止め、表示崩れがないことを確認してから進めると、戻しやすくなります。

Claude Codeに渡す前の準備

変更を隔離する

変換は多数のファイルを同時に触るので、作業用のブランチで行います。Claude Codeには、gitの作業ツリーを分けて並列セッションを動かす --worktree オプションがあります。リポジトリにコミットが1つ以上ある必要があります。

claude --worktree block-theme-migration

さらに、最初の棚卸しは編集を伴わないほうが安全です。計画モードでは、Claudeがファイルを読んで計画を示すだけで、承認するまで編集しません。次のコマンドで始めるか、セッション中に Shift+Tab を押して切り替えます。

claude --permission-mode plan

CLAUDE.mdに変換の規約を書く

方針をCLAUDE.mdに置くと、セッションを跨いでも指示がぶれません。例えば次のような断片です。

# テーマ変換の方針
- 対象はクラシックテーマ wp-content/themes/my-theme
- 変換先は同じディレクトリ内のブロックテーマ構成(templates/ と parts/)
- 設定は functions.php から theme.json へ写す。写した add_theme_support は
  動作確認が済むまで削除しない
- ブロックマークアップを手で新規設計しない。複雑なテンプレートは
  Site Editor で作った Code Editor の出力を貼る前提で、空の枠だけ用意する
- PHP のロジック(WP_Query のループ内の条件分岐など)は変換対象から外し、
  一覧にして報告する
- 1 回の作業で触るテンプレートは 3 ファイルまで

最後の2つが肝心です。テーマのハンドブックは、ブロックテンプレートを手書きするより、ブロックエディターで組んだものをコードエディターで開いて貼る進め方を前提にしています。ブロックのJSON設定を覚えるのは難しく、間違えるとサイトが壊れるためです。Claude Codeにも同じ線引きを渡すと、事故が減ります。

手順1: 現状を棚卸しさせる

計画モードのまま、次のように依頼します。

wp-content/themes/my-theme を読み、ブロックテーマ化のための棚卸しをして。
編集はしない。次の表を作って。
1. functions.php の add_theme_support / register_* 呼び出しの一覧
2. 使われているテンプレートファイルと、各ファイルが読み込む部品(get_header 等)
3. PHP のロジックを含み、HTML だけに置き換えられないテンプレート
4. テーマ内に入っている「機能」(ショートコード、投稿タイプ登録など)

出力のうち、4つ目の項目が前述のプラグイン分離の候補です。3つ目は、変換できない箇所の一覧になります。これを先に人が見ておくと、後で「ここだけ表示が違う」と驚かずに済みます。

手順2: add_theme_supportをtheme.jsonへ写す

ここが最も機械的に写せる工程です。theme.json のガイドには、add_theme_support と theme.json の設定の対応表が載っています。主なものを抜き出します。

add_theme_supporttheme.json の設定
editor-color-palettetheme.json の設定settings.color.palette に色の配列
editor-font-sizestheme.json の設定settings.typography.fontSizes にサイズの配列
editor-gradient-presetstheme.json の設定settings.color.gradients にグラデーションの配列
disable-custom-colorstheme.json の設定settings.color.custom を false
disable-custom-font-sizestheme.json の設定settings.typography.customFontSize を false
disable-custom-gradientstheme.json の設定settings.color.customGradient を false
custom-line-heighttheme.json の設定settings.typography.lineHeight を true
custom-spacingtheme.json の設定settings.spacing.padding を true
appearance-toolstheme.json の設定settings.appearanceTools を true
link-colortheme.json の設定settings.color.link を true

theme.json に設定があれば、同じ項目の add_theme_support の宣言より優先されます。つまり、先に theme.json を置いても、functions.php と矛盾して二重に効く心配はありません。また、theme.json のプリセットは、WordPressが色やフォントサイズのCSSクラスとカスタムプロパティを自動で生成します。functions.php に書いていた手動の出力は、写した後で不要になる場合があります。

次のように指示します。

棚卸しの1を元に、theme.json を新規作成して。
- 先頭は "version": 2 と $schema
- add_theme_support の項目は、公式の対応表どおりの設定キーへ写す
- 写し先に迷う項目は、写さずに一覧で報告する
- functions.php は変更しない

例えば、functions.php に次のような宣言があったとします(値は説明用の例です)。

add_theme_support( 'editor-color-palette', array(
    array( 'name' => 'Base',     'slug' => 'base',     'color' => '#ffffff' ),
    array( 'name' => 'Contrast', 'slug' => 'contrast', 'color' => '#000000' ),
) );
add_theme_support( 'disable-custom-colors' );
add_theme_support( 'custom-line-height' );

対応表に沿うと、theme.json は次の形になります。

{
	"$schema": "https://schemas.wp.org/trunk/theme.json",
	"version": 2,
	"settings": {
		"color": {
			"custom": false,
			"palette": [
				{ "color": "#ffffff", "name": "Base", "slug": "base" },
				{ "color": "#000000", "name": "Contrast", "slug": "contrast" }
			]
		},
		"typography": {
			"lineHeight": true
		}
	}
}

palette の各要素は color と name と slug が必須です。slug はCSSのカスタムプロパティやクラス名の元になります。サイトの背景に base、文字色に contrast を使うのが、デフォルトテーマ由来の事実上の標準です。プラグインが色を参照するときの共通の足がかりにもなります。

色やフォントのCSSはstylesへ

settings は「選べる選択肢」を決める場所で、実際の見た目は styles に書きます。ハンドブックは、標準の機能は styles で指定することを勧めています。ユーザーが管理画面のStylesから変更したときに、CSSの詳細度の衝突が起きないためです。

{
	"version": 2,
	"styles": {
		"color": {
			"background": "var(--wp--preset--color--base)",
			"text": "var(--wp--preset--color--contrast)"
		}
	}
}

既存の style.css にある body の色指定をここへ移すのが一例です。ただし、style.css の全部を theme.json に移す必要はありません。styles で表現できる標準の機能から移し、複雑なセレクタのCSSは残すのが無理のない進め方です。

手順3: PHPテンプレートをHTMLに分解する

次は templates/ と parts/ です。指示は、最も単純なものから1つずつ与えます。

手順

テンプレート分解の順番

  1. 1

    header と footer を parts にする

    header.php と footer.php の静的な部分を parts/header.html と parts/footer.html にします。ブロックテーマでは html や body 、head のタグをテーマ側で出力しません。WordPressが自動で出力し、メタ情報やスタイル、スクリプトも自動で追加します。wp_head() や wp_footer() に相当する呼び出しを、HTML側へ探して移そうとしないよう注意が必要です。

  2. 2

    index.html を置く

    最小の templates/index.html を作ります。ヘッダー・本文・フッターの枠だけで構いません。置いた時点でブロックテーマとして扱われるため、作業ツリーの上で確認します。

  3. 3

    singular / archive / 404 を足す

    投稿・固定ページ用、一覧用、404用を順に足します。ファイル名はテンプレート階層に沿って決めます。例えばホーム用は home.html です。

  4. 4

    カスタムテンプレートを移す

    Template Name: コメントで作っていたページテンプレートは、ブロックテーマではカスタムテンプレートに当たります。ファイル名は自由ですが、標準テンプレートの名前と重ならないようにします。

テンプレートの中身は、ブロックマークアップです。公式の例では、アーカイブ用のテンプレートは次のように、ヘッダー部品と本文の枠とフッター部品を並べるだけの形になります。

<!-- wp:template-part {"slug":"header","tagName":"header"} /-->
 
<!-- wp:group {"tagName":"main","layout":{"type":"constrained"}} -->
<main class="wp-block-group">
	<!-- wp:template-part {"slug":"loop","align":"full"} /-->
</main>
<!-- /wp:group -->
 
<!-- wp:template-part {"slug":"footer","tagName":"footer"} /-->

Claude Codeにはこの種の「枠」を作らせ、中身の細かいブロックは管理画面で組む運用が安全です。次の指示がその例です。

single.php を読み、templates/singular.html の枠を作って。
- header と footer は template-part ブロックで呼ぶ
- 本文領域は main の group ブロックにする
- the_title / the_content 相当は、どのブロックに当たるかをコメントで列挙するだけ。
  マークアップは書かない

投稿タイトルや本文のブロックを、Site Editorで置いてCode Editorで貼り直す作業は、人の手になります。この分担にしておけば、Claude Codeが存在しないブロックの属性を作り出す事故を避けられます。

theme.jsonに登録する

テンプレートパーツは、theme.json に登録するのが望ましいとされています。登録すると、Site Editorに翻訳可能な名前つきで現れるためです。area に header か footer を指定すると、エディター内でも対応する見た目で扱われます。

{
	"version": 2,
	"templateParts": [
		{ "name": "header", "title": "Header", "area": "header" },
		{ "name": "footer", "title": "Footer", "area": "footer" }
	],
	"customTemplates": [
		{
			"name": "landing",
			"title": "Landing Page",
			"postTypes": [ "page" ]
		}
	]
}

customTemplates の name と title は必須です。postTypes を省略すると、固定ページだけに適用されます。

手順4: 管理画面で確かめる

ここまでで、ファイルの変換は終わりです。確認は人が行います。

  1. Appearance > Editor を開き、TemplatesとPatternsの一覧に、置いたテンプレートとパーツが現れるか見る
  2. 主要なページ(トップ、投稿、固定ページ、一覧、404)の表示を変換前と比べる
  3. Stylesの画面で、theme.json の色やフォントサイズが選択肢に出るか見る

確認用の環境を wp-env で立てる方法はClaude CodeでGutenbergブロックを作るにまとめています。Claude Codeに画面を見せられない作業なので、スクリーンショットを貼って「この部分が崩れている」と指示する形になります。

落とし穴

管理画面で保存したテンプレートが、ファイルより優先される

WordPressはテンプレートを探すとき、データベースに保存されたユーザーのテンプレート、子テーマの templates フォルダー、テーマの templates フォルダーの順に見ます。Site Editorで一度保存すると、templates/*.html を直しても反映されません。テーマをほかのサイトへ配るなら、エディターで組んだブロックマークアップを該当ファイルに貼り直す必要があります。確認中にファイルの変更が見えないときは、まずこの優先順位を疑います。

変換後に残る作業

  • functions.php に残る機能コードを、プラグインへ出すか決める
  • 写し終えた add_theme_support を削除する(動作確認の後)
  • PHPのコーディング規約チェックはphpcsのhookに任せ、変換の度に走らせる
  • 不要になった header.php などのPHPテンプレートを、別コミットで削除する

PHPテンプレートの削除を別コミットにするのは、templates/index.html を外せばクラシックテーマとして扱われる状態へ戻せるようにするためです。

この作業をClaude Codeに任せる範囲

一般的なリファクタリングの手順は、公式ドキュメントでも「古いコードを洗い出す、改善案を出させる、挙動を保って適用する、テストで検証する」の4ステップで示されています。その要点は「小さく、テストできる単位で進める」ことです。テーマの変換にそのまま当てはめると、次のようになります。

  • 洗い出し: 手順1の棚卸し
  • 改善案: 手順2の対応表づくり
  • 適用: テンプレート1〜3ファイルずつの分解
  • 検証: 手順4の目視確認(自動テストが無いため、人が受け持つ)

テーマの表示にはテストコードがないことが多いので、4つ目が最も弱い点です。比較対象として、変換前のスクリーンショットを主要ページ分だけ保存しておくと、変換後に差分を指摘させやすくなります。

まとめ

add_theme_support から theme.json への写しは、対応表がある機械的な作業なので、Claude Codeに任せて問題の少ない部分です。テンプレートの分解は、枠までをClaude Code、細かいブロックは管理画面という分担が現実的です。最初の到達点を theme.json の追加だけに置けば、表示崩れの確認も段階的に進められます。

参照した一次ソース

この記事の記述は、次の一次ソースと照合しています。更新時に参照先が変わった場合は一覧も更新します。

  1. code.claude.com/docs/en/common-workflows
  2. developer.wordpress.org/themes/getting-started/what-is-a-theme
  3. developer.wordpress.org/themes/global-settings-and-styles/introduction-to-theme-js…
  4. developer.wordpress.org/themes/templates/templates
  5. developer.wordpress.org/themes/templates/template-parts
  6. developer.wordpress.org/block-editor/how-to-guides/themes/theme-json
この記事を共有:XはてブLinkedIn