###実現したいこと
wordpressですが、wp_query
等を使い、次の 条件 で記事を表示したいです。
###条件
カスタムフィールドnumber
の値ごとに、最新1件ずつ
###例
たとえば次のような投稿ならば、表示したいのは、「記事B」と「記事C」です。「記事A」は表示しません。
記事 | 投稿日 | number | 表示 |
---|---|---|---|
記事A | 4/1 | 1 | × |
記事B | 4/2 | 1 | 〇 |
記事C | 4/3 | 2 | 〇 |
###なぜか
なぜ「記事A」を表示しないのかというと、同じnumber
の記事は最新1件しか表示しないという条件なので、number
が「1」の最新の記事として、「記事A」でなく「記事B」を表示します。
そして「記事C」はnumber
が「2」ですがこれは1つしかないので表示します。
以上の条件で記事を取得する方法がわかる方がいたら、どうかご指導をお願い致します。
気になる質問をクリップする
クリップした質問は、後からいつでもMYページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2019/04/22 00:54
回答1件
0
ベストアンサー
残念ながら wp_posts や WP_Query で、条件に含まれる各項目から n 件ずつ取り出すという動作を簡単に実行することは難しいです。
WordPressの WP_Query で行うとしたら
- カスタムフィールドに含まれる値一覧の配列を用意
- カスタムフィールドの値を1つずつループさせて WP_Query でデータ取得
という処理を書く必要があります。
たとえば、$values にカスタムフィールドの値一覧を用意しておいて、foreach でカスタムフィールドの項目を1項目ずつ WP_Query に渡して カスタムフィールドの値ごとに1回ずつ検索する必要があります。
$values = array( '001', '002', '009', '050', '100', '999' ); // カスタムフィールドの全項目一覧 foreach( $values as $value ) { $args = array( 'posts_per_page' => 1, 'meta_key' => 'number', 'meta_value' => $value, 'meta_compare' => '=', 'order' => 'DESC', 'orderby' => 'date', ); $query = new WP_Query( $args ); if ( $query->have_posts() ) { echo '<ul>'; while ( $query->have_posts() ) { $query->the_post(); echo '<li>' . get_the_title() . '</li>'; } echo '</ul>'; wp_reset_postdata(); } else { // no posts found } }
もし、SQLが、書けるのであれば、
- カスタムクエリ を利用して、WP_Query の条件を SQL で設定したり
- 関数リファレンス/wpdb_Class を利用して、直接、SQLで検索したり
することもできます。
(追記 2019.04.23 11:25)
カスタムクエリで対応する例
まず、条件分岐タグ を使って、どのテンプレートの場合に実行するのか条件を決めます。
条件分岐タグで、使用場所を指定しない場合、全ての SQL に適用されることになります。
内容によっては、ログインできなくなったり、一切の投稿が表示されなくなったりしますので、注意してください。
詳細がわかりませんので、アーカイブのメインクエリーと仮定します。
希望する内容が取得できる SQL を考えます。
質問の内容から推測して
SELECT wp_posts.ID FROM wp_posts INNER JOIN wp_postmeta ON wp_posts.ID = wp_postmeta.post_id INNER JOIN ( SELECT wp_postmeta.meta_value as number, max(wp_posts.post_date) as max_date FROM wp_posts INNER JOIN wp_postmeta ON wp_posts.ID = wp_postmeta.post_id WHERE wp_postmeta.meta_key = 'number' GROUP BY wp_postmeta.meta_value ) AS j2 ON wp_postmeta.meta_value =j2.number AND wp_posts.post_date = j2.max_date
のような感じでしょうか。
作成した SQL を WordPress の HOOK で実行できるように構築しなおして、functions.php に記載します。
INNER JOIN は posts_join
フックを、絞り込み条件がある場合の WHERE や AND は posts_where
フックを使用します。
function my_posts_join_tt184471( $join ) { global $wpdb; if( ! is_admin() && is_archive() && is_main_query() ) { $join .= "INNER JOIN ". $wpdb->postmeta ." ON ". $wpdb->posts .".ID = ". $wpdb->postmeta .".post_id "; $join .= "INNER JOIN ( "; $join .= " SELECT ". $wpdb->postmeta .".meta_value as number, max(". $wpdb->posts .".post_date) as max_date "; $join .= " FROM ". $wpdb->posts; $join .= " INNER JOIN ". $wpdb->postmeta ." ON ". $wpdb->posts .".id = ". $wpdb->postmeta .".post_id "; $join .= " WHERE ". $wpdb->postmeta .".meta_key = 'number' "; $join .= " GROUP BY ". $wpdb->postmeta .".meta_value "; $join .= " ) AS j1 "; $join .= " ON ". $wpdb->postmeta .".meta_value = j1.number AND ". $wpdb->posts .".post_date = j1.max_date "; } return $join; } add_filter('posts_join', 'my_posts_join_tt184471' );
使用している条件分岐タグは、下記です。
! is_admin()
管理画面を除く( ! で否定 )is_archive()
アーカイブテンプレートis_main_query()
メインクエリー
カスタムクエリの場合、表示まわりは、標準の archive.php のままで OK です。
--
参考:
投稿2019/04/22 02:27
編集2019/04/23 02:41総合スコア25171
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2019/04/22 03:42 編集
2019/04/22 03:59 編集
2019/04/22 09:39 編集
2019/04/22 11:05
2019/04/22 13:11
2019/04/22 15:06
2019/04/23 02:25
2019/04/23 06:12
2019/04/23 06:20 編集
2019/04/23 06:57
2019/04/23 07:01 編集
2019/04/23 11:01 編集
あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。