ピックアップ投稿表示を ACF Pro の繰り返しフィールドで実装する

WordPress
記事内に広告が含まれています。

サイトトップなどに特定の WordPress の投稿をピックアップして表示したい場合に個人的によく使うパターン。ACF Pro の繰り返しフィールドで表示したい投稿を選択して任意の場所に表示します。

投稿選択用の固定ページを作成

スラッグ名 pickup-posts として固定ページを作成します。毎回作成するのは面倒なので以下の XML ファイルをインポート。

参考 インポート用 XML ファイル(ZIP形式)

投稿選択用の繰り返しフィールドを作成

先ほどの固定ページに紐づける繰り返しフィールドを作成します。毎回作成するのは面倒なので以下の JSON ファイルをインポート。

参考 インポート用 JSON ファイル(ZIP形式)

固定ページとフィールドグループを紐づけ

上記をインポート後、ACF のメニュー【ACF】→【フィールドグループ】から、先ほどインポート(作成)したフィールドグループ【投稿選択】を編集。【設定】→【ロケーションルール】から先ほどインポート(作成)した固定ページに紐づけます。

固定ページでピックアップ表示したい投稿を選択

先ほどインポート(作成)した固定ページの編集画面を開くと【投稿選択】フィールドが追加されているので任意の投稿を選択。

テスト用に適当に数個選んでおきます。

ピックアップ投稿を表示したい箇所にコードを追加

ピックアップ投稿を表示する処理を追加します。テーマのテンプレートファイル内であれば以下のような感じ。

<?php

//(中略)

// ピックアップ投稿の最低表示数
$num_min_pickup_posts = 5;

// ピックアップ投稿の取得処理 ========================================

// ピックアップ投稿 ID を保存する配列
$ids_pickup_posts = array();
// ピックアップ投稿選択用固定ページを取得
$page_pickup_posts = get_page_by_path('pickup-posts', OBJECT, 'page');
// PICK UP 投稿の ID を保存
if (have_rows("pickup_posts", $page_pickup_posts->ID)) {
    while (have_rows("pickup_posts", $page_pickup_posts->ID)) {
        the_row();
        $tmp = get_sub_field("pickup_post");
        // 投稿が空でない場合のみ追加
        if (!($tmp instanceof stdClass) and !empty($tmp)) {
            array_push($ids_pickup_posts, $tmp->ID);
        }
    }
}
// 最低表示数に達していなければ最新順に必要数だけ取得
$num_add = $num_min_pickup_posts - count($ids_pickup_posts);
if (0 < $num_add) { $args = array( 'post_type' => 'post',
        'posts_per_page' => $num_add,
        'post__not_in' => $ids_pickup_posts,
    );
    $query = new WP_Query($args);
    if ($query->have_posts()) {
        while ($query->have_posts()) {
            $query->the_post();
            array_push($ids_pickup_posts, $post->ID);
        }
    }
    wp_reset_postdata();
}

// ピックアップ投稿の表示処理 ========================================

if (count($ids_pickup_posts)) {
    // ピックアップ投稿を取得
    $args = array(
        'post_type' => 'post',
        'posts_per_page' => -1,
        'post_status' => 'publish',
        'post__in' => $ids_pickup_posts,
        'orderby' => 'post__in',
    );
    $query = new WP_Query($args);
    if ($query->have_posts()) { ?>
<div class="sample-slider">
<?php
        while ($query->have_posts()) {
            $query->the_post();
            // アイキャッチ画像取得
            $thumb_pc = wp_get_attachment_image_src(get_post_thumbnail_id(), 'slide_pc');
            $thumb_sp = wp_get_attachment_image_src(get_post_thumbnail_id(), 'slide_sp');
            // アイキャッチ画像未指定の場合は代替画像
            if (empty($thumb_pc)) {
                $thumb_pc = get_thumb_noimage_pc(); // テーマ外で使用する場合のための自作関数
                $thumb_sp = get_thumb_noimage_sp(); // テーマ外で使用する場合のための自作関数
            } else {
                $thumb_pc[4] = $thumb_sp[4] = get_post_meta(get_post_thumbnail_id(), '_wp_attachment_image_alt', true);
            }
            // カテゴリーごとにCSSクラス名を付与したい場合は先頭のカテゴリーを使用(不定)
            $_cat = get_the_category();
            $_cat = $_cat[0];
            // カスタムフィールド取得(例・NEWバッジを表示することが多いので)
            $new = get_field('new'); ?>
    <div class="card-post<?php if (!empty($new)) { ?> new<?php } ?> cat-<?php echo $_cat->slug; ?>">
        <figure class="post-thumb">
            <picture>
                <source media="(max-width: 812px)" srcset="<?php echo $thumb_sp[0]; ?>" width="<?php echo $thumb_sp[1]; ?>" height="<?php echo $thumb_sp[2]; ?>" >
                <img src="<?php echo $thumb_pc[0]; ?>" alt="<?php echo $thumb_pc[4]; ?>" width="<?php echo $thumb_pc[1]; ?>" height="<?php echo $thumb_pc[2]; ?>">
            </picture>
        </figure>
        <h2 class="post-title"><a data-mh href="<?php the_permalink(); ?>"><?php the_title(); ?></a></h2>
        <p class="post-date"><time datetime="<?php the_time('Y-m-d'); ?>"><?php the_time('Y年n月j日'); ?></time></p>
        <div class="post-meta">
            <p class="post-cat"><?php the_category(' '); ?></p>
<?php
            if (has_tag()) { ?>
            <ul class="post-tag">
                <li><?php the_tags('', '</li><li>'); ?></li>
            </ul>
<?php
            } ?>
        </div>
    </div>
<?php
        } ?>
<?php
    }
    wp_reset_postdata();
} ?>
</div>

補足

  • 各投稿に「ピックアップに表示」とかいう真偽値のカスタムフィールドを追加して WP_Query() で取得するのもアリなんだけど(以前はその方法を使ってた)「一箇所(固定ページ)で管理したい」とか「表示順を並べ替えたい」という要望が意外と多いのでこの形に落ち着きました。
  • テーマ外で使う場合は wp-load.php を読み込んでから、とか、マルチサイト WordPerss を読み込んで switch_to_blog($bid_child) してから、とか。
タイトルとURLをコピーしました