WordPressのカスタムフィールドを使って投稿の優先順位を設定する方法

カスタムフィールドを活用した投稿の並び替え

WordPressでは、投稿の順番を制御する方法として「カスタムフィールド」を利用できます。
特に menu_order というフィールドを使えば、指定した投稿を優先的に表示し、
カスタムフィールドが削除された場合は通常の新着順に戻す ことが可能です。

この記事では、カスタムフィールド menu_order を活用し、値が設定されている投稿を優先表示し、
未設定の投稿は新着順に戻す 方法を解説します。

投稿を優先表示するための menu_order の仕組み

menu_order の値が設定された投稿を優先的に表示
小さい値ほど優先順位が高くなる(例:-10 の投稿が 0 よりも前に表示される)。

menu_order が未設定(削除)された投稿は通常の新着順に戻る
投稿の公開日時が新しい順に並ぶ(date DESC)。

この仕組みをWordPressのショートコードを利用したカスタムクエリで実装します。

menu_order を考慮した投稿の取得コード

以下のコードでは、menu_order が設定されている投稿を優先表示し、
設定されていない投稿は新着順で表示します。

カスタムショートコードの実装

function sampleFunction($attributes, $content = null) {
    extract(shortcode_atts(array(
        "limit" => '6',
        "category" => '',
        "type" => 'post',
        "wrapper_class" => '',
        "item_class" => ''
    ), $attributes));

    global $entry;
    $originalEntry = $entry;

    // `menu_order` が設定されている投稿を優先表示
    $priorityArgs = array(
        'numberposts' => $limit,
        'order' => 'ASC',
        'post_type' => $type,
        'category' => $category,
        'meta_key' => 'menu_order',
        'orderby' => array(
            'menu_order' => 'ASC',
            'date' => 'DESC'
        ),
        'meta_query' => array(
            array(
                'key' => 'menu_order',
                'value' => '',
                'compare' => '!='
            )
        )
    );
    $priorityPosts = get_posts($priorityArgs);

    // `menu_order` が未設定の投稿を通常の新着順で表示
    $regularArgs = array(
        'numberposts' => $limit - count($priorityPosts),
        'order' => 'DESC',
        'orderby' => 'date',
        'post_type' => $type,
        'category' => $category,
        'meta_query' => array(
            'relation' => 'OR',
            array(
                'key' => 'menu_order',
                'compare' => 'NOT EXISTS'
            ),
            array(
                'key' => 'menu_order',
                'value' => '',
                'compare' => '='
            )
        )
    );
    $regularPosts = get_posts($regularArgs);

    // 投稿リストを統合
    $allPosts = array_merge($priorityPosts, $regularPosts);

    $output = '<div class="'.$wrapper_class.'">';
    $counter = 0;

    foreach($allPosts as $entry):
        setup_postdata($entry);
        $counter++;

        // アイキャッチ画像の取得
        $image = get_the_post_thumbnail($entry->ID);
        if (!$image) {
            $image = '<img src="'.get_stylesheet_directory_uri().'/img/sample/default_image.jpg">';
        }

        // 投稿概要を取得
        if (mb_strlen($entry->post_content) > 50) {
            $summary = mb_substr(strip_tags($entry->post_content), 0, 50) . '...';
        } else {
            $summary = strip_tags(get_the_content());
        }

        // HTML 出力
        $output .= '<div class="entry'.$counter.' '.$item_class.'"><a href="'.get_permalink().'">
            <div class="thumbnail"><p>'.$image.'</p></div>
            <div class="content">
                <p class="title">'.get_the_title().'</p>
                <p class="description">'.$summary.'</p>
            </div></a>
        </div>';
    endforeach;

    $output .= '</div>';
    $entry = $originalEntry;
    wp_reset_postdata();

    return $output;
}
add_shortcode("sample-list", "sampleFunction");

動作のポイント

menu_order が設定されている投稿を優先的に取得
menu_order が削除された投稿は新着順で取得
get_posts() の結果を array_merge() で結合し、投稿リストを作成

WordPress管理画面での設定方法

menu_order の値を設定

優先表示したい投稿menu_order = -10 などの小さい値
通常の投稿menu_order を削除

ショートコードを使って投稿を表示

投稿または固定ページに以下のショートコードを挿入します。

[sample-list limit="6" category="news" type="post" wrapper_class="post-list" item_class="post-item"]

まとめ

menu_order の値が設定されている投稿が優先的に表示される
menu_order を削除すると通常の新着順に戻る
ACFを活用せずにWordPress標準のメタデータを活用可能
menu_order を利用して簡単に投稿の表示順をカスタマイズできる

この方法を使えば、投稿の表示順を自由にカスタマイズできるようになります。
ぜひ活用してみてください!