BETA

WordPressでカスタムフィールドの値を元に自然順っぽく並び替えする方法

投稿日:2018-10-26
最終更新:2018-10-26
※この記事は外部サイト(https://note.mu/oceant/n/nf966887bba41)からのクロス投稿です

注意

厳密な自然順の並び替え(ナチュラルソート)ではありません。WordPressで利用されているMySQL自体にナチュラルソートの機能がないようなので、あくまで擬似的なものと捉えてください。上手くいかないパターンもあると思います。

やりたいこと

テキスト型のカスタムフィールドの値を元に、各投稿をナチュラルソートしたい。

通常の昇順でやった場合

コード例

$posts= get_posts(
    array(
        'post_type' => array('custom_post_type'),
        'meta_key' => 'custom_field_key',
        'orderby' => 'meta_value',
        'order' => 'asc'
    )
);

結果

A-1
A-10
A-11
A-2
A-3
...

単純にorderをascとした場合、上記のような残念な結果となります。

ちなみに、カスタムフィールドが数値型の場合は 'orderby' => 'meta_value_num' とすればナチュラルソートされます。

やりたい昇順

A-1
A-2
A-3
...
A-10
A-11

こんな並びにしたい。

結論

// 以下をfunction.phpに記載
function custom_orderby($orderby) {
    global $wpdb;
    $orderby = "LENGTH(".$wpdb->prefix."postmeta.meta_value) ASC, ".$wpdb->prefix."postmeta.meta_value ASC";
    return $orderby;
}

// 以下をナチュラルソートしたい箇所に記載
add_filter('posts_orderby', 'custom_orderby', 10,2);
$posts= get_posts(
    array(
        'post_type' => array('custom_post_type'),
        'meta_key' => 'custom_field_key',
        'suppress_filters' => false
    )
);

考え方

自然順っぽくするには、まずテキストの長さでソートし(桁で揃える)、その後に値でソートすることで実現できそうです。

コード上のポイント

function.phpにて、posts_orderbyをフックして独自のSQLを実行させる関数を記載します。add_filterを個別に記載しているのは、全ての投稿取得で利用するわけではないケースが多いだろう、という予測から。

また、get_posts内にて 'suppress_filters' => false というオプションを追加しています。

get_postsで取得する場合、このオプションを記載しないとposts_orderbyのフックが有効化されないため、忘れずに記載しましょう。get_posts以外(query_postsやWP_Query)で取得する場合は自動的に有効化されるので記載不要です。

技術ブログをはじめよう Qrunch(クランチ)は、プログラマの技術アプトプットに特化したブログサービスです
駆け出しエンジニアからエキスパートまで全ての方々のアウトプットを歓迎しております!
or 外部アカウントで 登録 / ログイン する
クランチについてもっと詳しく

この記事が掲載されているブログ

@oceant'の技術ブログ

よく一緒に読まれる記事

0件のコメント

ブログ開設 or ログイン してコメントを送ってみよう
目次をみる
技術ブログをはじめよう Qrunch(クランチ)は、プログラマの技術アプトプットに特化したブログサービスです
or 外部アカウントではじめる
10秒で技術ブログが作れます!