第2回:Claude CodeでWordPressの簡単なテーマをバイブコーディング実装

はじめに

Miyagi です。昨日は Local by Flywheel で開発環境を構築しました。第2回目にして、今日は"テーマファイル"を作成していきます。とにかく最短で目標達成!細かな付随する知識は後から学習していきます。Claude Code によるWordPress のテーマ開発をバイブコーディング! プロンプトで指示しながら初めての最小テーマの作成を目指します。

目次

 

概要

先に結論を書いておくと、Claude Code のおかげで 10 分もかからず「投稿が表示される動作する簡単なテーマ」が完成しました!!

今日のメインタスクは WordPress Loop の実装でしたが、結果的に記事一覧ページ(index.php)、記事詳細ページ(single.php)、そして動作確認用の記事まで作成できました。プロンプトで AI に指示するだけで、ここまで簡単にテーマができるとは思いませんでした。

 

WordPress Loop 実装

まずは Claude Code に最小限の WordPress Loop を実装してもらいました。

WordPress Loop とは? WordPress Loop は、WordPress テーマ開発において最も重要な仕組みの一つです。データベースから投稿記事を取得し、それらを順次表示するための PHP のループ処理です。have_posts()で投稿があるかチェックし、whileループで各投稿を処理、the_post()で投稿データを準備し、the_title()the_content()で実際のコンテンツを出力します。この Loop があることで、動的にコンテンツを表示できる WordPress の真価が発揮されます。

使用したプロンプト:

「WordPress の index.php に最小限の Loop を追加してください。
投稿タイトルと本文だけ表示できれば OK です」

Claude Code の実装結果:

最小テーマが完成しました:

作成したファイル:

- wp-content/themes/my-first-theme/index.php - WordPress Loop を含むメインテンプレート
- wp-content/themes/my-first-theme/style.css - テーマ情報と基本スタイル

実装した WordPress Loop 機能:

- have_posts()と while でループ処理
- the_post()で投稿データを準備
- the_title()で投稿タイトル表示
- the_content()で投稿本文表示
- 投稿がない場合のメッセージも追加

WordPress 管理画面の「外観 > テーマ」で「My First
Theme」を有効化すれば、投稿タイトルと本文が表示される最小テーマが動作します

WordPress 管理画面の「外観 > テーマ」で「My First Theme」を有効化すると、ちゃんと投稿タイトルと本文が表示されました!見た目はイマイチながらもサッと作れたことに感動です。 デフォルトテーマと今回の作成したテーマは以下の通りです。

Before: Twenty Twenty-Three (デフォルト) WordPress テーマ開発 Day2 Step2

  After: Claude Code で作成した簡単テーマ WordPress テーマ開発 Day2 Step1

 

記事詳細ページの作成

テーマを確認していると、記事のタイトルをクリックしても遷移できないことに気づきました。記事詳細ページがまだ作成されていなかったんですね。

追加プロンプト:

記事のタイトルをクリックしても遷移できませんでした。
記事の詳細ページについては、まだ作成していないのでしょうか?
もし、未作成であるならば、作成をお願いします。

Claude Code の実装結果:

記事詳細ページ(single.php)を作成しました!

追加した機能:

- 記事タイトル、本文、投稿日、投稿者の表示
- カテゴリーとタグの表示
- 前の記事・次の記事へのナビゲーション
- ホームに戻るリンク
- 記事詳細ページ専用のスタイル

これで記事のタイトルをクリックすると、記事詳細ページに正しく遷移するようになります。
WordPress のテンプレート階層により、個別記事の表示時には index.php ではなく、
single.php が自動的に使用されます。

動作確認用の記事作成

デフォルトの「Hello World!」記事だけでは動作確認が不十分だったので、Claude Code に記事コンテンツの提案をお願いしました。

プロンプト内容:

デフォルトの記事、1つしかありません。その為、動作確認としては不受分かと思います。
以下の条件に沿って、1 つ記事を作成してください。

### 条件

- 記事の内容:WordPress のテーマをプロンプトから作成したことについて
- タイトル:SEO を意識したタイトル
- 本文:文字数 400 文字
- 補足:テンション高めの人気ブロガー風の基調で記事を書く

Claude Code が提案した記事:

**タイトル:**「【2024 年最新】AI プロンプトで WordPress テーマを自作!初心者でも 30 分で完成する革新的な方法」
**本文::**
こんにちは!今日は超エキサイティングなニュースをお届けします ✨ ...(省略)

Claude Code が提案した実際の記事:

WordPress テーマ開発 Day2 Step5 いい感じでテンション高めの人気ブロガー風の基調になっていますね w

 

まとめ

🎯 達成できたこと

  • 最小テーマの作成完了(index.php、style.css、single.php)
  • WordPress Loop 実装による投稿データの動的表示
  • 基本テンプレート階層の理解と実装
  • 記事間ナビゲーション機能の実装
  • レスポンシブ対応の基本 CSS

📂 作成ファイル構成

wp-content/themes/my-first-theme/
├── index.php # メイン投稿一覧
├── single.php # 記事詳細ページ
└── style.css # テーマ情報・スタイル

💻 コード

  index.php

// index.php - メイン投稿一覧ページ
<!DOCTYPE html>
<html>
  <head>
    <title><?php bloginfo('name'); ?></title>
    <?php wp_head(); ?>
  </head>
  <body>
    <h1><?php bloginfo('name'); ?></h1>

    <?php if (have_posts()) : ?>
    <?php while (have_posts()) : the_post(); ?>
    <article>
      <h2>
        <a href="<?php the_permalink(); ?>"><?php the_title(); ?></a>
      </h2>
      <div><?php the_content(); ?></div>
    </article>
    <?php endwhile; ?>
    <?php else : ?>
    <p>投稿が見つかりませんでした。</p>
    <?php endif; ?>

    <?php wp_footer(); ?>
  </body>
</html>

// single.php - 記事詳細ページ
<!DOCTYPE html>
<html>
  <head>
    <title><?php the_title(); ?> - <?php bloginfo('name'); ?></title>
    <?php wp_head(); ?>
  </head>
  <body>
    <?php if (have_posts()) : ?>
    <?php while (have_posts()) : the_post(); ?>
    <article>
      <h1><?php the_title(); ?></h1>
      <div><?php the_content(); ?></div>
      <p>
        投稿日:
        <?php the_date(); ?>
        | 投稿者:
        <?php the_author(); ?>
      </p>
    </article>
    <?php endwhile; ?>
    <?php endif; ?>

    <a href="<?php echo home_url(); ?>">ホームに戻る</a>
    <?php wp_footer(); ?>
  </body>
</html>

  single.php

<!DOCTYPE html>
<html <?php language_attributes(); ?>>
<head>
    <meta charset="<?php bloginfo('charset'); ?>">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title><?php the_title(); ?> | <?php bloginfo('name'); ?></title>
    <?php wp_head(); ?>
</head>
<body <?php body_class(); ?>>
    <div class="container">
        <header>
            <h1><a href="<?php echo home_url(); ?>"><?php bloginfo('name'); ?></a></h1>
            <p><?php bloginfo('description'); ?></p>
        </header>

        <main>
            <?php if (have_posts()) : ?>
                <?php while (have_posts()) : the_post(); ?>
                    <article id="post-<?php the_ID(); ?>" <?php post_class(); ?>>
                        <h1 class="single-title"><?php the_title(); ?></h1>

                        <div class="post-meta">
                            <p>投稿日: <?php the_date(); ?> | 投稿者: <?php the_author(); ?></p>
                            <?php if (has_category()) : ?>
                                <p>カテゴリー: <?php the_category(', '); ?></p>
                            <?php endif; ?>
                            <?php if (has_tag()) : ?>
                                <p>タグ: <?php the_tags('', ', ', ''); ?></p>
                            <?php endif; ?>
                        </div>

                        <div class="post-content">
                            <?php the_content(); ?>
                        </div>

                        <div class="post-navigation">
                            <div class="nav-links">
                                <?php
                                $prev_post = get_previous_post();
                                $next_post = get_next_post();
                                ?>

                                <?php if ($prev_post) : ?>
                                    <div class="nav-previous">
                                        <a href="<?php echo get_permalink($prev_post->ID); ?>">
                                            ← <?php echo get_the_title($prev_post->ID); ?>
                                        </a>
                                    </div>
                                <?php endif; ?>

                                <?php if ($next_post) : ?>
                                    <div class="nav-next">
                                        <a href="<?php echo get_permalink($next_post->ID); ?>">
                                            <?php echo get_the_title($next_post->ID); ?> →
                                        </a>
                                    </div>
                                <?php endif; ?>
                            </div>
                        </div>

                        <div class="back-to-home">
                            <p><a href="<?php echo home_url(); ?>">← ホームに戻る</a></p>
                        </div>
                    </article>
                <?php endwhile; ?>
            <?php else : ?>
                <p>記事が見つかりませんでした。</p>
            <?php endif; ?>
        </main>
    </div>
    <?php wp_footer(); ?>
</body>
</html>

  style.css

/*
Theme Name: My First Theme
Author: あなたの名前
Description: 最初のWordPressテーマ
Version: 1.0
*/

/* 基本リセット */
* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

body {
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
  line-height: 1.6;
  color: #333;
  background-color: #f4f4f4;
}

.container {
  max-width: 800px;
  margin: 0 auto;
  padding: 20px;
  background-color: #fff;
  min-height: 100vh;
}

/* ヘッダー */
header {
  text-align: center;
  padding: 20px 0;
  border-bottom: 2px solid #eee;
  margin-bottom: 30px;
}

header h1 a {
  color: #333;
  text-decoration: none;
  font-size: 2rem;
}

header h1 a:hover {
  color: #0073aa;
}

header p {
  color: #666;
  margin-top: 10px;
}

/* メインコンテンツ */
main {
  padding: 20px 0;
}

article {
  margin-bottom: 40px;
  padding-bottom: 30px;
  border-bottom: 1px solid #eee;
}

article h2 {
  margin-bottom: 15px;
}

article h2 a {
  color: #333;
  text-decoration: none;
}

article h2 a:hover {
  color: #0073aa;
}

.post-content {
  margin-bottom: 15px;
  line-height: 1.8;
}

.post-meta {
  color: #666;
  font-size: 0.9rem;
}

/* 記事詳細ページ用スタイル */
.single-title {
  font-size: 2.2rem;
  margin-bottom: 20px;
  line-height: 1.3;
}

.post-navigation {
  margin-top: 40px;
  padding-top: 30px;
  border-top: 2px solid #eee;
}

.nav-links {
  display: flex;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 20px;
}

.nav-previous,
.nav-next {
  flex: 1;
  max-width: 48%;
}

.nav-previous a,
.nav-next a {
  color: #0073aa;
  text-decoration: none;
  font-size: 0.9rem;
}

.nav-previous a:hover,
.nav-next a:hover {
  text-decoration: underline;
}

.nav-next {
  text-align: right;
}

.back-to-home {
  margin-top: 30px;
  text-align: center;
}

.back-to-home a {
  color: #0073aa;
  text-decoration: none;
  font-weight: bold;
}

.back-to-home a:hover {
  text-decoration: underline;
}

 

🔧 使用した技術要素

  • PHP: WordPress 関数の基本使用
  • CSS: モバイルファーストのレスポンシブデザイン
  • HTML5: セマンティックマークアップ

Claude Code とプロンプトの組み合わせで、ここまで実用的なテーマが短時間で作成できるとは驚きました!そして、最短で WordPress のテーマ作成の経験が詰めたことは嬉しいです。徐々に必要な知見をためていきたいと思います。次回(Day 3)では、header.php と footer.php へのテンプレート分離、page.php の作成を予定しています。

 

最後まで読んでいただき、ありがとうございました!
この記事が少しでもお役に立てれば嬉しいです。良い開発ライフを!