WordPressで記事内に画像がない場合の一覧表示用画像の設定


前回書いた「WordPressで記事内の画像を自動リサイズして一覧表示させるやり方」の説明によって、投稿ページ内の1枚目の画像を一覧表示させるところまでは実現できているとします。

現時点では以下のような感じのコードになっています。

<ul>
<?php
$args = array(
  'posts_per_page' => '5',
  'post_type' => 'post',
);
$custom_post = get_posts($args);
?>
<?php foreach($custom_post as $post): setup_postdata($post); ?>
<?php
$args = array(
  'post_parent' => $post->ID,
  'post_type' => 'attachment',
  'post_mine_type' => 'image',
  'order' => 'ASC',
  'posts_per_page' => 1,
);
$attachments = get_children($args);
?>
<?php foreach($attachments as $attachment): ?>
<?php $url = wp_get_attachment_image_src($attachment->ID, 'sidebar-thumbnail'); ?>
<?php $alt = esc_html(get_post_meta($attachment->ID, '_wp_attachment_image_alt', true)); ?>
  <li><img src="<?php echo $url[0]; ?>" alt="<?php echo $alt; ?>" /><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></li>
<?php endforeach; ?>
<?php endforeach; ?>
<?php wp_reset_postdata(); ?>
</ul>

上記のコードでは各投稿ページ内に画像がない場合の処理が含まれていないため、今回はその処理をこれに追加していこうと思います。
手順としては以下のようになる。

1、get_children関数によって各投稿ページ内の画像が1枚取得されているのでこれが空かどうかを判定し、
2、空じゃない場合はそれを表示。
3、空の場合はあらかじめ用意しておいた画像を表示。

という流れになる。
なので、まずはget_childrenの直後、foreachの前にif文によって$attachmentsが空かどうかを判定する。

<?php if( !empty($attachments) ): ?>

空じゃない場合は今まで通りの出力をし(以下のコードを参照)、

<?php if( !empty($attachments) ): ?>
<?php foreach($attachments as $attachment): ?>
<?php $url = wp_get_attachment_image_src($attachment->ID, 'sidebar-thumbnail'); ?>
<?php $alt = esc_html(get_post_meta($attachment->ID, '_wp_attachment_image_alt', true)); ?>
  <li><img src="<?php echo $url[0]; ?>" alt="<?php echo $alt; ?>" /><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></li>
<?php endforeach; ?>

空の場合はあらかじめ用意しておいた画像を出力する。(以下のコードを参照)

<?php else: ?>
  <li><img src="デフォルト画像のURL" alt="デフォルト画像" /><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></li>
<?php endif; ?>

完成形のコード

完成形としては以下のようなコードになります。

<ul>
<?php
$args = array(
  'posts_per_page' => '5',
  'post_type' => 'post',
);
$custom_post = get_posts($args);
?>
<?php foreach($custom_post as $post): setup_postdata($post); ?>
<?php
$args = array(
  'post_parent' => $post->ID,
  'post_type' => 'attachment',
  'post_mine_type' => 'image',
  'order' => 'ASC',
  'posts_per_page' => 1,
);
$attachments = get_children($args);
?>
<?php if( !empty($attachments) ): ?>
<?php foreach($attachments as $attachment): ?>
<?php $url = wp_get_attachment_image_src($attachment->ID, 'sidebar-thumbnail'); ?>
<?php $alt = esc_html(get_post_meta($attachment->ID, '_wp_attachment_image_alt', true)); ?>
  <li><img src="<?php echo $url[0]; ?>" alt="<?php echo $alt; ?>" /><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></li>
<?php endforeach; ?>
<?php else: ?>
  <li><img src="デフォルト画像のURL" alt="デフォルト画像" /><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></li>
<?php endif; ?>
<?php endforeach; ?>
<?php wp_reset_postdata(); ?>
</ul>

このやり方の問題点

このやり方で表示される「投稿記事内の1枚目の画像」というのは、そのページ編集時に最初にアップロードした画像が選ばれるようです。
記事を書いている時にアップロードした画像は、その記事内で使用する・しないにかかわらずその記事と紐付いているようです。

つまり、「記事を書く時に画像をアップロードはしたけど、その画像は記事内では使用しなかった」場合でもその画像が一覧表示に使われてしまいます。
同様の理由から、「過去にアップロードした画像を再び使用」した場合、その画像は一覧表示の際に適用されません。
過去にアップロードした写真というのは、今書いている記事に紐付いていないからだと思われます。

例えば、今ご覧になっているこの記事内にある最初の画像はチョコレートケーキの写真ですね。
このページに使われている写真
本来なら一覧表示の部分にはこの写真が適用されるはずです。

しかし、トップページやサイドバーにある一覧表示では別の写真が表示されています。
一覧表示で選ばれている画像
これは私が最初にアップロードした画像を使わなかったからです。(一覧に表示されている画像が最初にアップロードしたもの)

画像がどの記事に紐付いているのかはWordPress管理画面の「メディアライブラリ」を見るとわかります。
記事と画像の紐付き

この問題点を解決させる方法はまた次の機会に書くことにします。