【WordPress】記事内の最初の画像をサムネイルとして表示する方法

WordPressで投稿一覧に表示されるサムネイル画像は、デフォルトでは投稿に設定されたアイキャッチ画像が使用されます。しかし、アイキャッチ画像が設定されていない場合、記事内の最初の画像を自動的にサムネイルとして表示する方法があります。本記事では、その実装方法を詳しく解説します。

この記事でわかること

  • 本文から最初の画像URLを正しく取得する方法(よくある実装の落とし穴と検証結果つき)
  • 投稿一覧テンプレートでアイキャッチの代わりに表示するコード
  • サムネイル画像の表示スタイルを整えるCSS
スポンサーリンク

functions.phpにコードを追加

まずは、使用しているテーマのfunctions.phpファイルにコードを追加して、記事内の最初の画像を取得する関数を作成します。

functions.php:本文から最初の画像URLを取得しサムネイル表示
function get_first_image_from_content( $content ) {
    if ( preg_match( '/<img[^>]+src=["\']([^"\']+)["\'][^>]*>/i', $content, $matches ) ) {
        return $matches[1]; // 最初の画像のURLを返す
    }
    return false; // 画像が見つからない場合はfalseを返す
}

function display_post_thumbnail_or_first_image() {
    global $post;

    if ( has_post_thumbnail() ) {
        // アイキャッチ画像が設定されている場合
        the_post_thumbnail( 'thumbnail' );
    } else {
        // アイキャッチ画像がない場合、記事内の最初の画像を表示
        $first_image_url = get_first_image_from_content( $post->post_content );

        if ( $first_image_url ) {
            echo '<img src="' . esc_url( $first_image_url ) . '" alt="' . esc_attr( get_the_title() ) . '" />';
        }
    }
}

このコードは、投稿にアイキャッチ画像が設定されていない場合に、記事内の最初の画像を取得し、その画像をサムネイルとして表示します。

よくある実装には「最後の画像」を取得してしまう落とし穴がある
本文から最初の画像を取得する処理は、次のような正規表現で紹介されることがよくあります。しかし.+.*の貪欲マッチにより、本文に画像が2枚以上あると意図に反して最後の画像を取得してしまいます。実際にPHPで検証した結果は以下の通りです。
NG:画像が複数あると最後の画像を取得してしまう
preg_match_all( '/<img.+src=[\'"]([^\'"]+)[\'"].*>/i', $content, $matches );
// $content = '<img src="A.jpg"><p>text</p><img src="B.jpg">'
// -> $matches[1][0] は "B.jpg"(最後の画像。誤り)
OK:[^>]で属性の範囲を区切り最初の画像を正しく取得
preg_match( '/<img[^>]+src=["\']([^"\']+)["\'][^>]*>/i', $content, $matches );
// 同じ $content で -> $matches[1] は "A.jpg"(最初の画像。正しい)

投稿一覧テンプレートに表示コードを追加

次に、投稿一覧のテンプレートファイル(通常はindex.phpやarchive.phpなど)に、先ほど作成した関数を呼び出すコードを追加します。

index.php / archive.php:投稿ループ内でサムネイルを表示
<?php if ( have_posts() ) : ?>
    <?php while ( have_posts() ) : the_post(); ?>
        <div class="post">
            <div class="post-thumbnail">
                <?php display_post_thumbnail_or_first_image(); ?>
            </div>
            <h2 class="post-title"><?php the_title(); ?></h2>
            <div class="post-excerpt">
                <?php the_excerpt(); ?>
            </div>
        </div>
    <?php endwhile; ?>
<?php endif; ?>

このコードを追加することで、投稿一覧において、アイキャッチ画像が設定されていない投稿にも、記事内の最初の画像がサムネイルとして表示されます。

サムネイル画像のスタイルを調整

最後に、サムネイル画像の表示をスタイルシート(style.css)で調整します。以下のCSSコードを追加して、サムネイル画像が適切に表示されるようにしましょう。

style.css:サムネイル画像を枠内に収める
.post-thumbnail img {
    width: 100%;
    height: auto;
    object-fit: cover;
}

このCSSで、サムネイル画像が投稿の枠内にきれいに収まり、見栄えが良くなります。

関連記事

よくある質問(FAQ)

Q記事の最初の画像を取得するPHPコードの基本は?
Aget_the_content()$post->post_contentで本文を取得し、preg_match()で最初のimgタグのsrc属性を抽出します。[^>]でタグの範囲を区切ることが、複数画像がある場合に最初の1枚を正しく取得するポイントです。
Qアイキャッチがない場合に本文の最初の画像を代わりに使うには?
Ahas_post_thumbnail()でアイキャッチの有無を確認し、ない場合に本文から画像を抽出するロジックを組み合わせます。関数化してテーマのfunctions.phpに追加し、テンプレートから呼び出します。
Q抽出した画像URLをWordPressのattachmentとして処理できますか?
A本文内の画像がWordPressのメディアライブラリにアップロードされたものであれば、attachment_url_to_postid($url)でアタッチメントIDを取得し、wp_get_attachment_image()で適切なサイズで表示できます。
Q正規表現で本文の最初の画像ではなく最後の画像が取得されてしまいます
A.+.*のような貪欲マッチを使った正規表現が原因の可能性が高いです。貪欲マッチはできるだけ多く文字を消費しようとするため、本文に画像が複数あると最後のsrc=まで一致してしまいます。[^>]+のようにタグの終わりを明示的に区切ることで、最初の画像だけを確実に取得できます。

まとめ

これで、WordPressの投稿一覧において、アイキャッチ画像が設定されていない投稿に対しても、記事内の最初の画像を自動的にサムネイルとして表示することができるようになります。正規表現で画像を抽出する際は貪欲マッチによる「最後の画像」誤取得に注意し、テーマをカスタマイズする際に役立ててください。