WordPressでカスタムフィールドの値を元に自然順っぽく並び替えする方法
注意
厳密な自然順の並び替え(ナチュラルソート)ではありません。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)で取得する場合は自動的に有効化されるので記載不要です。
この記事が気に入ったらサポートをしてみませんか?