カスタム投稿タイプの投稿を「特定の条件」で並び替えて表示する方法

WordPress を使用していると、「特定のカスタムフィールドを持つ投稿を先頭に表示したい」
というケースがよくあります。
この記事では、カスタム投稿タイプにおいて、特定のフィールドを持つ投稿を先頭に、
それ以外をその後に表示する方法を解説します。

実現する機能

  1. カスタム投稿タイプの投稿を対象。
  2. 特定のカスタムフィールド(例:highlight)が存在する投稿を先頭に表示。
  3. タクソノミー条件が指定されている場合、その条件に一致する投稿を表示。
  4. カスタムフィールドを持たない投稿を、その後に表示。

サンプルコード

以下に、目的を実現するサンプルコードを示します。
このコードでは、highlight というカスタムフィールドを基準に投稿を分けています。

<div class="sample_post_list">
    <?php
    // 現在のタクソノミークエリ情報を取得
    $taxonomy_query = array();
    if (is_tax()) {
        $current_taxonomy = get_queried_object();
        if ($current_taxonomy) {
            $taxonomy_query[] = array(
                'taxonomy' => $current_taxonomy->taxonomy,
                'field'    => 'slug',
                'terms'    => $current_taxonomy->slug,
            );
        }
    }

    // 特定のカスタムフィールド「highlight」がついている投稿を先頭に取得
    $highlight_args = array(
        'post_type'      => 'sample_post', // サンプル用のカスタム投稿タイプ
        'posts_per_page' => -1, // 全投稿を取得
        'meta_key'       => 'highlight', // カスタムフィールドキー
        'orderby'        => 'meta_value_num', // カスタムフィールド値で並び替え
        'order'          => 'DESC', // 降順
        'tax_query'      => $taxonomy_query, // タクソノミーフィルタ
        'meta_query'     => array(
            array(
                'key'     => 'highlight',
                'compare' => 'EXISTS', // カスタムフィールドが存在する投稿を取得
            ),
        ),
    );
    $highlight_query = new WP_Query($highlight_args);

    // 特定のカスタムフィールド「highlight」がない投稿を取得
    $regular_args = array(
        'post_type'      => 'sample_post',
        'posts_per_page' => -1,
        'tax_query'      => $taxonomy_query,
        'meta_query'     => array(
            array(
                'key'     => 'highlight',
                'compare' => 'NOT EXISTS', // カスタムフィールドが存在しない投稿を取得
            ),
        ),
    );
    $regular_query = new WP_Query($regular_args);

    // 「highlight」がついている投稿を表示
    if ($highlight_query->have_posts()) :
        while ($highlight_query->have_posts()) : $highlight_query->the_post(); ?>
            <div class="sample_item">
                <a class="sample_thumbnail" href="<?php the_permalink(); ?>">
                    <p class="highlight_label"><span>HIGHLIGHT</span></p>
                    <?php
                    if ($custom_image = get_field('custom_image')) :
                        echo '<img class="thumbnail_image" src="' . esc_url($custom_image) . '" alt="Highlighted Post">';
                    elseif (has_post_thumbnail()) :
                        the_post_thumbnail('medium', array('class' => 'thumbnail_image'));
                    else :
                        echo '<img class="thumbnail_image" src="' . esc_url(get_template_directory_uri()) . '/images/default.jpg" alt="Default Thumbnail">';
                    endif;
                    ?>
                </a>
            </div>
        <?php endwhile;
    endif;
    wp_reset_postdata();

    // 「highlight」がついていない投稿を表示
    if ($regular_query->have_posts()) :
        while ($regular_query->have_posts()) : $regular_query->the_post(); ?>
            <div class="sample_item">
                <a class="sample_thumbnail" href="<?php the_permalink(); ?>">
                    <?php
                    if ($custom_image = get_field('custom_image')) :
                        echo '<img class="thumbnail_image" src="' . esc_url($custom_image) . '" alt="Regular Post">';
                    elseif (has_post_thumbnail()) :
                        the_post_thumbnail('medium', array('class' => 'thumbnail_image'));
                    else :
                        echo '<img class="thumbnail_image" src="' . esc_url(get_template_directory_uri()) . '/images/default.jpg" alt="Default Thumbnail">';
                    endif;
                    ?>
                </a>
            </div>
        <?php endwhile;
    endif;
    wp_reset_postdata();
    ?>
</div>

コードの解説

タクソノミー条件の適用

現在のタクソノミーアーカイブページの条件を取得し、投稿クエリに適用しています。
これにより、現在表示しているカテゴリやタグに関連する投稿だけを表示します。

highlight フィールドを基準にしたクエリ

WP_Query を2回使用して、

  • カスタムフィールド highlight を持つ投稿
  • 持たない投稿

をそれぞれ取得し、分けて表示しています。

サムネイル画像の取得

カスタムフィールド custom_image、投稿サムネイル、デフォルト画像の順でサムネイルを表示しています。

ページネーションへの対応

サンプルコードではすべての投稿を取得していますが、
ページネーションを追加する場合は posts_per_page を調整し、paged 引数を使用します。

実装時の注意点

カスタム投稿タイプ名

コード中の sample_post を実際のカスタム投稿タイプ名に置き換えてください。

カスタムフィールド名

使用しているカスタムフィールドキー highlight を、実際に使用しているフィールド名に変更してください。

ACF(Advanced Custom Fields)の利用

カスタムフィールドの取得に ACF を使用しています。ACF をインストールしていない場合は適宜修正してください。

まとめ

この方法を使用すると、特定のカスタムフィールドを基準に投稿を並び替え、
さらにタクソノミー条件にも対応した表示が可能になります。
WordPress の柔軟なクエリ機能を活用して、サイトのユーザー体験を向上させましょう!