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 の settings | Claude Codeに任せやすいか任せやすい(機械的に写せる) |
| 色・フォントの指定(CSS) | ブロックテーマ側theme.json の styles と settings のプリセット | Claude Codeに任せやすいか一部任せられる |
header.php / footer.php | ブロックテーマ側parts/header.html / parts/footer.html | Claude Codeに任せやすいか構造は任せられる、見た目は人が確認 |
index.php / single.php など | ブロックテーマ側templates/index.html / templates/singular.html など | Claude Codeに任せやすいか同上 |
ページテンプレート(Template Name: コメント) | ブロックテーマ側カスタムテンプレート + theme.json の customTemplates | Claude Codeに任せやすいか任せられる |
| テーマ内の機能(ショートコード、投稿タイプ) | ブロックテーマ側プラグインへ分離 | Claude Codeに任せやすいか設計判断が要る |
最後の行は、変換の話からは外れて見えますが重要です。WordPressのテーマハンドブックは、テーマが表示を、プラグインが機能を担うのが望ましいとしています。サイトに欠かせない機能をテーマに入れると、テーマを変えたときに失われるためです。ブロックテーマへ移す機会に、functions.php に溜まった機能コードをプラグイン側へ出す判断も入ってきます。
全部変換するか、ハイブリッドで止めるか
最初に決めるのは到達点です。theme.json はクラシックテーマにもブロックテーマにも使えるファイルです。クラシックテーマが theme.json やテンプレートパーツといったブロック関連の機能を取り入れた状態は、コミュニティでハイブリッドテーマと呼ばれています。公式の分類ではなく、実体はクラシックテーマのままです。
到達点は次の3段階で考えると指示が書きやすくなります。
theme.jsonを足すだけ。PHPテンプレートはそのまま(ハイブリッド)- 一部のテンプレートパーツだけHTML化する
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 planCLAUDE.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_support | theme.json の設定 |
|---|---|
editor-color-palette | theme.json の設定settings.color.palette に色の配列 |
editor-font-sizes | theme.json の設定settings.typography.fontSizes にサイズの配列 |
editor-gradient-presets | theme.json の設定settings.color.gradients にグラデーションの配列 |
disable-custom-colors | theme.json の設定settings.color.custom を false |
disable-custom-font-sizes | theme.json の設定settings.typography.customFontSize を false |
disable-custom-gradients | theme.json の設定settings.color.customGradient を false |
custom-line-height | theme.json の設定settings.typography.lineHeight を true |
custom-spacing | theme.json の設定settings.spacing.padding を true |
appearance-tools | theme.json の設定settings.appearanceTools を true |
link-color | theme.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
header と footer を parts にする
header.phpとfooter.phpの静的な部分をparts/header.htmlとparts/footer.htmlにします。ブロックテーマではhtmlやbody、headのタグをテーマ側で出力しません。WordPressが自動で出力し、メタ情報やスタイル、スクリプトも自動で追加します。wp_head()やwp_footer()に相当する呼び出しを、HTML側へ探して移そうとしないよう注意が必要です。 - 2
index.html を置く
最小の
templates/index.htmlを作ります。ヘッダー・本文・フッターの枠だけで構いません。置いた時点でブロックテーマとして扱われるため、作業ツリーの上で確認します。 - 3
singular / archive / 404 を足す
投稿・固定ページ用、一覧用、404用を順に足します。ファイル名はテンプレート階層に沿って決めます。例えばホーム用は
home.htmlです。 - 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: 管理画面で確かめる
ここまでで、ファイルの変換は終わりです。確認は人が行います。
Appearance > Editorを開き、TemplatesとPatternsの一覧に、置いたテンプレートとパーツが現れるか見る- 主要なページ(トップ、投稿、固定ページ、一覧、404)の表示を変換前と比べる
- 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 の追加だけに置けば、表示崩れの確認も段階的に進められます。
参照した一次ソース
この記事の記述は、次の一次ソースと照合しています。更新時に参照先が変わった場合は一覧も更新します。
- code.claude.com/docs/en/common-workflows
- developer.wordpress.org/themes/getting-started/what-is-a-theme
- developer.wordpress.org/themes/global-settings-and-styles/introduction-to-theme-js…
- developer.wordpress.org/themes/templates/templates
- developer.wordpress.org/themes/templates/template-parts
- developer.wordpress.org/block-editor/how-to-guides/themes/theme-json