WordPress:ダミー画像をアイキャッチ画像と同様に出力する

WordPress:ダミー画像をアイキャッチ画像と同様に出力する

投稿記事にアイキャッチ画像が登録されていないと、記事一覧などで画像欄が空白になってしまいます。別途ダミー画像を保存しておき、その URL を指定すればいいのですが、それですと画像の表示サイズなどで他の記事のアイキャッチ画像と同じように扱えません。

ダミー画像をメディアライブラリに登録してアイキャッチ画像と同様に表示する方法です。

01ダミー画像を表示する最も簡単な方法

アイキャッチ画像がない場合にダミー画像を表示する最も簡単な方法は、テーマディレクトリにダミー画像を保存しておき、記事にアイキャッチ画像がなければダミー画像を表示する方法です。

ダミー画像の保存場所はどこでもいいのですが、テーマディレクトリ内で完結させておいた方がサイトを移動したり、テーマを変更したりする場合にうっかり忘れたりしないと思います。

考え方としては次のコードになります。記事にアイキャッチ画像が登録されていればアイキャッチ画像を表示し、登録されていなければテーマディレクトリ内の dummy 画像を表示します。実際には画像を記事へのリンクで囲ったり、クラスなどの属性を付加したりします。

if (has_post_thumbnail()) {
	the_post_thumbnail();
}else{
	echo '<img src="' . get_template_directory_uri() . '/images/dummy.jpg">';
}

詳しくは Developer Resources を参照してください。サンプルコードもあります。

また、記事内に画像があれば最初の画像を表示する方法もありますが今回とは趣旨が違いますのでその方法はとっていません。必要であればググるなどしてください。

出力される HTML

このコードでどのような HTML が出力されるかと言いますと、

<img src="//localhost:3000/wp-content/themes/テーマ名/images/dummy.jpg">

当然こうなります。一方、他のアイキャッチ画像はどうかと言いますと、

<img width="650" height="367" 
src="//localhost:3000/wp-content/uploads/2023/07/wordpress-loop-post-template.jpg" class="attachment-post-thumbnail size-post-thumbnail wp-post-image" alt="" decoding="async" fetchpriority="high" 
srcset="
//localhost:3000/wp-content/uploads/2023/07/wordpress-loop-post-template.jpg 650w, 
//localhost:3000/wp-content/uploads/2023/07/wordpress-loop-post-template-300x169.jpg 300w" 
sizes="(max-width: 650px) 100vw, 650px">

デバイスの解像度によって表示する画像を変える srcset 属性や sizes 属性が付加されています。

ダミー画像もこれと同じように表示できないかということです。

02メディアライブラリへの登録とアイキャッチ画像

WordPress の画像の管理方法は結構面倒です。WordPress では、メディアライブラリを使わずに ftp などでアップロードした画像はデータベースには登録されません。当たり前か…(笑)。

画像をメディアライブラリの「新しいメディアファイルの追加」で登録しますとデータベースの wp_posts と wp_postmeta の2つのテーブルに分けて保存されます。wp_posts テーブルは投稿記事も登録されるテーブルです。

wp_posts, wp_postmeta テーブル

まず、wp_posts です。

この中で今回重要となるフィールドは次の5つです。

  • ID __ 一意の識別子
  • post_status __ メディアファイルの場合は inherit
  • post_name __ メディアファイルの場合はファイル名(拡張子なし)
  • guid __ メディアファイルの URL
  • post_type __ メディアファイルの場合は attachment

次に、wp_postmeta です。

こちらにはひとつのファイルに対して2行あり、それぞれ meta_key と meta_value のセットでファイルのパスとファイルの保存形態などメタ情報が保存されます。ただ、この wp_postmeta のデータは、post_id が wp_posts の ID の値と紐付いていますので直接操作する必要はありません。

アイキャッチ画像の登録

以上がデータベースへのメディアファイルの保存のされ方です。

今回は以上を理解していれば問題ないのですが、ことのついでにメディアライブラリに登録したメディアファイルをアイキャッチ画像として登録した場合、どのようにデータベースに保存されるかをみておきます。記事内に挿入したメディアファイルは記事内のデータとして保存されるだけですのでデータベースには直接保存されるものはありません。

投稿記事にアイキャッチ画像を登録しますと wp_postmeta テーブルに

  • post_id __ 投稿記事の wp_posts の ID
  • meta_key __ _thumbnail_id
  • meta_data __ メディアファイルの wp_postmeta の meta_id

という1行が追加されるだけです。

ですので、この記事の最初のコードの関数 has_post_thumbnail() がやっていることは、wp_postmeta テーブル内を投稿記事の ID と meta_key の _thumbnail で検索してデータがあるかないかを答えてくるということになります。

03ダミー画像をアイキャッチ画像と同様に出力する

本題のダミー画像をアイキャッチ画像と同様に出力するです。考え方は、

  1. メディアライブラリに登録したダミー画像の一意の識別子、つまり wp_posts テーブルの ID を取り出す
  2. wp_get_attachment_image() 関数を使い HTML に整形して出力する

という流れになります。

wp_posts テーブルからダミー画像の ID を取り出すには wpdb クラスをつかって直接データーベースを操作すればいいのですが、今回は WP_Query クラスを使ってみます。

必要なパラメーターは、

  • ‘post_type’ => ‘attachment’
  • ‘post_status’ => ‘inherit’
  • ‘name’ => ‘dummy’

の3つです。メディアファイルの post_status は inherit です。また、name はダミー画像のファイル名です。仮に同じファイル名のファイルを保存しますと、dummy, dummy-1, dummy-2 などとなっていきます。

具体的なコードはこうなります。

$query = new WP_Query(array(
    'post_type' => 'attachment',
    'post_status' => 'inherit',
    'name' => 'dummy',
    'no_found_rows' => true
));
$thumbnail_id = $query->post->ID;

これで wp_posts に保存されたダミー画像の ID を取り出せます。

HTML への整形は、get_the_post_thumbnail() のソースコードをみますと、wp_get_attachment_image() 関数が使われていますのでそのまま利用します。また、メディアファイルの URL だけが必要な場合も想定し、wp_get_attachment_image_src() 関数も利用します。

ということで完成版のコードです。

// アイキャッチ画像未設定の記事にダミー画像挿入関数
function the_dummy_image($size='post-thumbnail'){
    $query = new WP_Query(array('post_type' => 'attachment', 'post_status' => 'inherit', 'name' => 'dummy', 'no_found_rows' => true));
    $thumbnail_id = $query->post->ID;
    echo wp_get_attachment_image($thumbnail_id, $size);
}

// ダミー画像の生データ出力関数
/*
 * array(4) {
 * [0]=>URL(string)
 * [1]=>width(int)
 * [2]=>height(int)
 * [3]=>trueは縦横比率保持(bool)
 */
function get_the_dummy_image($size='post-thumbnail'){
    $query = new WP_Query(array('post_type' => 'attachment', 'post_status' => 'inherit', 'name' => 'dummy', 'no_found_rows' => true));
    $thumbnail_id = $query->post->ID;
    return wp_get_attachment_image_src($thumbnail_id, $size);
}

運用事例

この記事の最初のコードは次のようになります。実際に使っているコードですので簡潔に三項演算子で書いています。

<figure class="p-cardL__thumbnail">
<a href="<?php the_permalink(); ?>"><?php has_post_thumbnail() ? the_post_thumbnail('medium') : the_dummy_image('medium'); ?></a>
</figure>
記事一覧では横幅 600px の画像

このサイトの記事一覧ページ(と同等のもの…)のキャプチャです。1つ目がダミー画像で、2つ目が投稿記事に登録したアイキャッチ画像です。

<figure class="p-card__thumbnail">
<?php has_post_thumbnail() ? the_post_thumbnail('thumbnail') : the_dummy_image('thumbnail'); ?>
</figure>
サイドバーでは横幅 150px のサムネイル画像

サイドバーのキャプチャです。

これでダミー画像も他の投稿記事のアイキャッチ画像と同じように扱え、サムネイルで表示したり、フルサイズで表示したりできます。