質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
HTML5

HTML5 (Hyper Text Markup Language、バージョン 5)は、マークアップ言語であるHTMLの第5版です。

WordPress

WordPressは、PHPで開発されているオープンソースのブログソフトウェアです。データベース管理システムにはMySQLを用いています。フリーのブログソフトウェアの中では最も人気が高く、PHPとHTMLを使って簡単にテンプレートをカスタマイズすることができます。

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

HTML

HTMLとは、ウェブ上の文書を記述・作成するためのマークアップ言語のことです。文章の中に記述することで、文書の論理構造などを設定することができます。ハイパーリンクを設定できるハイパーテキストであり、画像・リスト・表などのデータファイルをリンクする情報に結びつけて情報を整理します。現在あるネットワーク上のほとんどのウェブページはHTMLで作成されています。

Q&A

解決済

1回答

1931閲覧

指定したカスタムフィールドの値で絞り込み、その最新1件ずつを表示するようなループは?

jaimy

総合スコア13

HTML5

HTML5 (Hyper Text Markup Language、バージョン 5)は、マークアップ言語であるHTMLの第5版です。

WordPress

WordPressは、PHPで開発されているオープンソースのブログソフトウェアです。データベース管理システムにはMySQLを用いています。フリーのブログソフトウェアの中では最も人気が高く、PHPとHTMLを使って簡単にテンプレートをカスタマイズすることができます。

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

HTML

HTMLとは、ウェブ上の文書を記述・作成するためのマークアップ言語のことです。文章の中に記述することで、文書の論理構造などを設定することができます。ハイパーリンクを設定できるハイパーテキストであり、画像・リスト・表などのデータファイルをリンクする情報に結びつけて情報を整理します。現在あるネットワーク上のほとんどのウェブページはHTMLで作成されています。

0グッド

0クリップ

投稿2019/04/14 14:41

編集2019/04/22 00:55

###実現したいこと
wordpressですが、wp_query等を使い、次の 条件 で記事を表示したいです。

###条件
カスタムフィールドnumberの値ごとに、最新1件ずつ

###例

たとえば次のような投稿ならば、表示したいのは、「記事B」と「記事C」です。「記事A」は表示しません。

記事投稿日number表示
記事A4/11×
記事B4/21
記事C4/32

###なぜか
なぜ「記事A」を表示しないのかというと、同じnumberの記事は最新1件しか表示しないという条件なので、numberが「1」の最新の記事として、「記事A」でなく「記事B」を表示します。

そして「記事C」はnumberが「2」ですがこれは1つしかないので表示します。

以上の条件で記事を取得する方法がわかる方がいたら、どうかご指導をお願い致します。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

CHERRY

2019/04/22 00:39

「記事A」と「記事B」をみると 最新1件の「最新」を判断する条件は日付ではないようですが、最新と判断した条件は何でしょうか?
jaimy

2019/04/22 00:54

ご指摘大変感謝いたします。逆でした。申し訳ございませんでした。
guest

回答1

0

ベストアンサー

残念ながら wp_posts や WP_Query で、条件に含まれる各項目から n 件ずつ取り出すという動作を簡単に実行することは難しいです。

WordPressの WP_Query で行うとしたら

  1. カスタムフィールドに含まれる値一覧の配列を用意
  2. カスタムフィールドの値を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 } }

関数リファレンス/WP_Query 参照


もし、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
CHERRY

総合スコア25171

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

jaimy

2019/04/22 03:42 編集

どうもありがとうございます。ご回答がつかず悩んでました。 カスタムフィールドの値ごとに1回ずつ検索する必要。ですか。大変そうですね。 以下、別の方法を考えてみたので、ご意見をくださいませんでしょうか? たとえば日付、number、記事IDで、こんな配列を作りますよね。 $arr = array( array( "date" => "4/1", "number" => "001", "post_id" => "10", ), array( "date" => "4/2", "number" => "001", "post_id" => "20", ), array( "date" => "4/3", "number" => "009", "post_id" => "90", ), ); そしたら、numberが一緒の「配列0」と「配列1」のdateを比べて、新しい方の「配列1」を残します。 お次はそうやって残った配列のpost_idを見ます。つまり20と90です。 あとはそれらで配列を作ってpost__inでこう。 $args = array( 'post__in' =>array("20","90") ); $query = new WP_Query( $args ); とするのはどうですか? あと、SQLは書けませんが、一番早い方法を教えていただけませんでしょうか?その方法を習得してみたいと思います。
CHERRY

2019/04/22 03:59 編集

やり方としては問題なくデータを取得できると思いますが、プログラムのコード化が面倒かなと思います。 ---- 一番早いとは検索速度がですか? カスタマイズの手間(テーマ修正にかかる時間/工数)ですか? WordPress で、SQLを直接使うやり方は、基本的に回答に記載した「カスタムクエリ」か「関数リファレンス/wpdb_Class」のどちらかになります。(PHPで接続からごりごり書くという手もありますが、ほぼ使いません。) 速度的には、画面表示までを含めるとどちらが飛び抜けて早いというわけでもないと思います。 テーマへの依存が少ない変更方法という意味では、「カスタムクエリ」を使うほうが テーマファイルの functions.php を書き加えるだけで、表示項目が変わらなければ、デフォルトのメインループや WP_Query のループにあまり手を加えなくてもそのまま使えるので、カスタマイズの対応はしやすいと思います。
jaimy

2019/04/22 09:39 編集

ありがとうございます!! ご回答いただいたものだと、何度も検索しますよね。 でもpost__inなら一回で済むから、検索速度は多少早いのかな?と思いました。(そんなことないでしょうか?笑) Twitterのような感じで記事数はとても多いので、手間よりも速度を優先したいです。
jaimy

2019/04/22 11:05

こんばんは。その後いかがでしょうか?
CHERRY

2019/04/22 13:11

えーと.... まだ、本業の関係で出先で作業中なので、何も考えていません。(5分10分程度のスキマ時間で書けるコードでもないので。) もしも、サーバーが止まっていてなんとしても今日中の解決して稼働させなければいけない等の理由で、急がれているのであれば、Web制作会社やクラウドワークスで、業務として WordPress のサポートされているところがありますのでお願いできそうなところを探してそちらに相談されることをおすすめします。
jaimy

2019/04/22 15:06

せっかちな性格で申し訳ございません。急ぎというわけではないです。 その後あれこれ調べてみました結果、下のコメントのような条件を追加すればできるのだと思うのですが(ですよね?)、この条件はやはり複雑なコードになるのでしょうか。 $results = $wpdb->get_results(” SELECT * FROM `wp_post` WHERE `post_status` = ‘publish’ LIMIT 20 // あとは自分が投稿者の記事のnumberを取得し、その最新1件ずつを表示する条件をここに書く “); foreach ($results as $value) { print(‘<li><a href=”‘.get_permalink($value->ID).'”>’.$value->post_title.'</a></li>’); }
CHERRY

2019/04/23 02:25

いえ、それで構いません。 get_results 等は、テーマの表示部分で、使われている have_post 等を使ったループしている部分を書き直さないとだめなので、テーマ全体に対して手を入れてよいのであれば問題ありません。
jaimy

2019/04/23 06:12

ループの内容がすべてこれになってしまうのですか!!笑 その影響範囲が怖いですね。メインループは「pre_get_post」で変えており、さらに「new WP_Query」で複数のサブループも作っていますが、これらすべて変わってしまいますか? ということは、これは仰っていた「カスタムクエリを使う方法」ではないということでしょうか?
CHERRY

2019/04/23 06:20 編集

いえ、情報が少ないので具体的に表示したい場所の詳細がわからないので、wpdb で、検索する場合は、既存の index ページで出力内容を変更するのであれば、 対象ページの表示周りのループを書き換える必要があるという話です。 新規にページを作る場合は、影響はないと思います。 逆に「カスタムクエリ」を使用する場合は、WordPress 通常の WP_Query の条件を上書きするので、表示部分に手を加える必要がないのですが、「カスタムクエリ」を使う場所を 「条件分岐タグ」で指定する必要があるという話です。( pre_get_posts を使われているのであれば、同じような感じですね。 )
jaimy

2019/04/23 06:57

あのすみません、おすすめの「カスタムクエリ」ですが、それはどのようなものですか?このコメントの2つ前のコードではないんですよね?
CHERRY

2019/04/23 07:01 編集

カスタムクエリの例は、コメント欄は、markdownが使えないので、回答欄の後半にに追記していますので確認してください。
jaimy

2019/04/23 11:01 編集

すみません!!回答欄の追記を見ていませんでした。まさかの完全コードに申し訳ない思いです。素人の理解に合わせたご説明までどうもありがとうございました。 ---ここに別途質問を書いていましたが、話が違うので削除しました---
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問