カスタムフィールドで複数画像の表示 (Toolset Types編)

2017年10月25日に加筆・修正をしました。

Toolset TypesはAdvanced Custom Fieldと同様にカスタムフィールドを設定できるWordpressプラグインです。管理画面UIも比較的わかりやすく、複数画像の表示が可能ですが少し設定が必要です。

Toolset Types が稼働するPHPのバージョン

5.6以上での正常稼働が確認済みで、5.3だと動かないようです。

カスタムフィールドの設定

Toolset Typesは、画像やチェックボックス、シングルライン(テキスト)などの複数のカスタムフィールドを1つのグループにまとめる仕様のプラグインです。グループに使用するカスタムフィールドを登録しておき、グループ単位で、どの投稿タイプで使用するのかを設定する流れとなります。

投稿Field Groupの追加

管理画面左の「Toolset」 > 「投稿 Fields」をえらび、「投稿Field Group」タイトルのすぐ右にある「新規追加」ボタンをクリックすると、投稿Field Group 追加用ページへ移動します。

追加用ページへ移動後、投稿Field Groupの名前を英数小文字で入力し、右の「Field Groupを保存する」ボタンをクリックして保存します。

投稿Field Groupの追加

フイールドの追加

「+ 新しいフィールドを追加する」ボタンをクリックすると、フィールドの種類をえらぶためのモーダルウインドウが開くので「画像」をクリックします。

フイールドの追加

画像フイールドの設定

下記の項目を入力すると使えるようになります。

  • フィールド名 / 日本語でOK
  • フィールドスラグ / 英数小文字
  • シングルまたは繰り返しフィールドですか?

「シングルまたは繰り返しフィールドですか?」の項目は画像を複数登録できるように「このフィールドの複数インスタンスを許可する」にチェックを入れます。

画像フイールドの設定

使用する投稿タイプを指定

「投稿Field Groupの編集」ページで「Where to include this Field Group」欄の「編集」ボタンをクリックするとモーダルウインドウが開くので、使用する投稿タイプをえらびます。これでカスタムフィールドを使うための最低限の設定が完了します。

使用する投稿タイプを指定

カスタムフィールド登録での画像を表示するコード

複数登録の画像に対応させるコードがImage Field Type / Featured Image : How can I display image title / alt / desc? – Toolsetに記載されていましたので引用します。このコードであれば画像のaltには管理画面の「代替テキスト」で入力した内容が表示されます(仮にカスタムフィールド画像が1枚の場合でも同様)。なお、altと同じ内容でtitleが付加されるようなのでこの部分は削除して使用した方がSEO上良さそうです。

<?php
add_shortcode('my-images', 'my_images_shortcode');
function my_images_shortcode() {
    global $post, $wpdb;
    $images = get_post_meta($post->ID, 'wpcf-images', false);
    $out = '<ul>';
    foreach ($images as $image) {
        $attachment_id = $wpdb->get_var($wpdb->prepare(
        "SELECT ID FROM $wpdb->posts WHERE guid = %s",
        $image
    ));
    $alt = get_post_meta($attachment_id, '_wp_attachment_image_alt', true);
    $out .= '<li><img src="' . $image . '" alt="' . $alt . '" title="' . $alt . '"/></li>';
    }
    $out .= '</ul>';
    return $out;
}
?>

ループ中に直接コードを挿入する場合は下記のようにすれば使用できます。少し改変してます。


<?php if (have_posts()) : while (have_posts()) : the_post(); ?>
<?php
    $images = get_post_meta($post->ID, 'wpcf-images', false);
    $judge = array_filter($images);
    if($judge) {
        foreach ($images as $image) {
            $query = "SELECT ID FROM $wpdb->posts WHERE guid = %s";
            $prepared = $wpdb->prepare($query, $image);
            $attachment_id = $wpdb->get_var($prepared);
            $alt = esc_attr(get_post_meta($attachment_id, '_wp_attachment_image_alt', true));
            $out = '<img src="'.$image.'" alt="'.$alt.'"/>';
            echo $out;
        }
    }
...
?>

何をしているのか

  • array_filter()でカスタムフィールド値の判定。参考:PHPの連想配列で値がすべて空かどうかを判定する方法 – life.log.1
  • $query にIDを取得するためのSQLクエリ条件を入れて、
  • $prepared に「prepare」メソッドでエスケープ(%sに$imageが入る)したSQLクエリを入れて、
  • $attachment_id に「get_var」メソッドでIDを取得して、
  • 投稿のIDを使ってaltを取得する。

という感じです。「guid」には「投稿のURL」が入っているので、あらかじめ取得しておいた、投稿のURLが入っている「$image」を使って投稿のIDを取得しています。

添付ファイルも「投稿」

画像のIDを取得しようとしているのに「投稿のURL」を取得しようとするのは、カスタムフィールドの画像が添付ファイル扱いになっているのが理由で、「attachment」という投稿タイプで投稿していることになっています。「$wpdb->posts」ですべての投稿にアクセスできるので「SELECT ID FROM $wpdb->posts 〜」で投稿のIDを取得するSQLクエリ操作をすることになります。

画像サイズを変更する場合

取得される画像のサイズは上記のコードでは「フルサイズ」になります。状況によっては小さいサイズの画像を取得したい場合もありますので、その場合は下記のようなコードを記述して対応します。

function.php / 幅640px(高さはなりゆき)にリサイズした画像を生成

add_image_size('thumb', 640, 0, true);

$outの内容を変更

$attachImgSrc = wp_get_attachment_image_src($attachment_id, "thumb");
$out = '<img src="'.$attachImgSrc[0].'" alt="'.$alt.'" />';

画像をアップロードした後にコードを追加した場合、自動的にリサイズ画像が生成される訳ではないので、Regenerate Thumbnailsのようなプラグインを利用して画像を再生成します。なお、リサイズ画像の設定は管理画面の「設定」>「メディア」でも行えます。

なぜ、Advanced Custom FieldsではなくToolset Types?

有名どころのAdvanced Custom Fieldsですが、過去にこの記事を読んでからこのプラグインの使用を控えてます。
製作者に知っていて欲しいWordPressのカスタムフィールドと検索の話 – bulblub

記事を読んだきっかけがまさに「検索」の件だったわけで、呆然としたことがありました。
Toolset Typesと同様にカスタムフィールド値がシリアライズ化がされないCustom Field Templateをしばらく使っていましたが、少々使いにくい面もあったので最近はToolset Typesを使用しています。