- ベストアンサー
WordPressで投稿記事を3パターン表示したい
- WordPressで投稿記事を3パターン表示するための方法について相談です。
- 投稿記事を3ファイルに分けて表示したいが、うまくいかず全てpage.phpとして表示されます。アドバイスをお願いします。
- page.php、page-secound.php、page-third.phpの3つのファイルがあり、それぞれのページに割り当てたカスタムフィールドを使って振り分けたいです。
- みんなの回答 (30)
- 専門家の回答
質問者が選んだベストアンサー
front-page.phpのコードをもとにして、search.phpを作ってみました。 コードはこちらです。 https://wandbox.org/permlink/vqm36EiTCbCl1QKF 私のfront-page.phpが古いかも知れませんが、変更箇所がわかるようにしていますので、最新のものと見比べてみてください。 削除している箇所は以下のように括ってコメント化しています。 /* ここから削除 (もとのコード) ここまで削除 */ 追加している箇所は以下のように括っています。 /* ここから追加 */ (追加したコード) /* ここまで追加 */ 削除と追加はそれぞれ二か所ずつあります。 SQL文は大幅に変更しています。 1.'single_rss_feed1'は以前やられていたように直接JOINしました。 2.画像はWordPress関数で取得するのでなくしました。 3.カテゴリーはWordPress関数で取得するのでなくしました。 4.$post_itemsとして使えるよう取得項目はwp_postsのすべての項目にしました。 5.全件件数取得のためのSQL文を別途追加しました。
その他の回答 (29)
- dell_OK
- ベストアンサー率13% (766/5720)
・下記ページにsearch.phpとpage-front.phpを載せているのですが、search.phpに関しまして下記コードの設置場所は正しいでしょうか? post.post_date DESC,wp_postmeta.meta_key ='single_rss_feed1'; この条件の追加分です。 ---- INNER JOIN ( SELECT * FROM wp_postmeta WHERE meta_key='single_rss_feed1' ) AS feed ON post.ID = feed.post_id ---- 以下の場所に挿入してください。 ---- FROM wp_posts AS post ここに挿入 ----
補足
訂正頂きありがとうございます 修正致しました。
- dell_OK
- ベストアンサー率13% (766/5720)
・確認なのですが$wpdbとphpmyadminを使って格納や取得を行う場合はどちらも負担は同じでしょうか。 そうですね。同じだと思います。 どちらも内部でそれぞれ違った複雑なことをしているので、それぞれなりの負担はかかっていると思います。
補足
ありがとうございます。勉強になりました。
- dell_OK
- ベストアンサー率13% (766/5720)
回答No.26のつづき。 それで件数のためになぜこうする必要があったかですが、書き直したものを件数だけ取得するように直すと、こうなります。 ---- SELECT COUNT(*) AS all_count FROM wp_posts AS post LEFT JOIN ( SELECT * FROM wp_postmeta WHERE meta_key = '_thumbnail_id' ) AS thumbnail ON post.ID = thumbnail.post_id LEFT JOIN wp_posts AS attachment ON thumbnail.meta_value = attachment.ID LEFT JOIN ( SELECT category.object_id AS post_id, GROUP_CONCAT(category.name ORDER BY category.term_id) AS category_names, GROUP_CONCAT(category.slug ORDER BY category.term_id) AS category_slugs FROM ( SELECT sub_a.name, sub_a.slug, sub_c.object_id, sub_a.term_id FROM wp_terms AS sub_a LEFT JOIN wp_term_taxonomy AS sub_b ON sub_a.term_id = sub_b.term_id LEFT JOIN wp_term_relationships AS sub_c ON sub_b.term_taxonomy_id = sub_c.term_taxonomy_id WHERE sub_b.taxonomy = 'category' ) AS category GROUP BY category.object_id ) AS category ON post.ID = category.post_id WHERE post.post_type = 'post' AND post.post_status = 'publish' AND post.post_content LIKE %s OR post.post_title LIKE %s OR post.post_excerpt LIKE %s) ---- 何が違うかと言うと、最初の方法では、もとのSQL文をひとつのテーブルに見立てて、その外側で件数をカウントしていたのが、SELECTの項目をCOUNT()にするだけでよくなります。 実はCOUNT()もグループ関数なのでGROUP BYと一緒に使うものです。 グループ化の必要でなければGROUP BYを書かないことで、全件をひとつのグループとみなして件数をひとつだけ返してくれます。 ここではその手法で件数を取得しています。 ですが、もとのSQL文にはGROUP BYがあったため、それをCOUNT()だけにしても期待通りのものは取得できません。 試しにやってみるとどのようになるかわかります。
補足
解説ありがとうございます。 GROUP BYをCOUNTに変えて全件取得にしたのですね SQL単体でカウントした場合、その後の2ブロックに活かすときに難しいような気がしたのですが、そうでもないのでしょうか? 今から教えて頂いたコードを試してみます。
- dell_OK
- ベストアンサー率13% (766/5720)
・全件数はCOUNTでSQLで計算するんですかね COUNT()の使い方はこんな感じです。 ---- SELECT COUNT(*) FROM wp_posts ---- 手書きのSQL文でするならこうなります。 ---- SELECT COUNT(*) AS all_count FROM ( SELECT post.ID AS post_id, post.post_title, post.post_date, post.post_excerpt, post.comment_count, post.guid AS post_url, attachment.guid AS thumbnail_url, GROUP_CONCAT(category.name ORDER BY category.term_id) AS category_names, GROUP_CONCAT(category.slug ORDER BY category.term_id) AS category_slugs FROM wp_posts AS post LEFT JOIN ( SELECT * FROM wp_postmeta WHERE meta_key = '_thumbnail_id' ) AS thumbnail ON post.ID = thumbnail.post_id LEFT JOIN wp_posts AS attachment ON thumbnail.meta_value = attachment.ID LEFT JOIN ( SELECT sub_a.name, sub_a.slug, sub_c.object_id, sub_a.term_id FROM wp_terms AS sub_a LEFT JOIN wp_term_taxonomy AS sub_b ON sub_a.term_id = sub_b.term_id LEFT JOIN wp_term_relationships AS sub_c ON sub_b.term_taxonomy_id = sub_c.term_taxonomy_id WHERE sub_b.taxonomy = 'category' ) AS category ON post.ID = category.object_id WHERE post.post_type = 'post' AND post.post_status = 'publish' AND (post.post_content LIKE %s OR post.post_title LIKE %s OR post.post_excerpt LIKE %s) GROUP BY post.ID ) AS counter ---- これは単純にもととほぼ同じSQL文をひとつのテーブルに見立てて、その件数を取得する方法です。 そのテーブルの内容は使わないので順序は不要ですし、LIMITも不要なので、以下の部分はなくしています。 ---- ORDER BY post.post_date DESC LIMIT %d,%d ---- 内容を使わないと言う意味では、 ---- SELECT post.ID AS post_id, post.post_title, post.post_date, post.post_excerpt, post.comment_count, post.guid AS post_url, attachment.guid AS thumbnail_url, GROUP_CONCAT(category.name ORDER BY category.term_id) AS category_names, GROUP_CONCAT(category.slug ORDER BY category.term_id) AS category_slugs FROM ---- この部分も不要なので、 ---- SELECT 1 FROM ---- まったく意味もないこのようなものにしても大丈夫です。 実はもう少し工夫すると、よりよい書き方もあります。 私がちょっと楽したくて手を抜いていましたが、もとのSQL文は以下のような書き方の方がよかったです。 取得する結果は全く同じです。 ---- SELECT post.ID, post.post_title, post.post_date, post.post_excerpt, post.comment_count, post.guid AS post_url, attachment.guid AS thumbnail_url, category.category_names, category.category_slugs FROM wp_posts AS post LEFT JOIN ( SELECT * FROM wp_postmeta WHERE meta_key = '_thumbnail_id' ) AS thumbnail ON post.ID = thumbnail.post_id LEFT JOIN wp_posts AS attachment ON thumbnail.meta_value = attachment.ID LEFT JOIN ( SELECT category.object_id AS post_id, GROUP_CONCAT(category.name ORDER BY category.term_id) AS category_names, GROUP_CONCAT(category.slug ORDER BY category.term_id) AS category_slugs FROM ( SELECT sub_a.name, sub_a.slug, sub_c.object_id, sub_a.term_id FROM wp_terms AS sub_a LEFT JOIN wp_term_taxonomy AS sub_b ON sub_a.term_id = sub_b.term_id LEFT JOIN wp_term_relationships AS sub_c ON sub_b.term_taxonomy_id = sub_c.term_taxonomy_id WHERE sub_b.taxonomy = 'category' ) AS category GROUP BY category.object_id ) AS category ON post.ID = category.post_id WHERE post.post_type = 'post' AND post.post_status = 'publish' AND post.post_content LIKE %s OR post.post_title LIKE %s OR post.post_excerpt LIKE %s) ORDER BY post.post_date DESC ---- もともとはカテゴリーの連結を外側でしていましたが、グループキーとなるもの(category.object_id)は内側にあるのでそこでグループ化を完結させておく方法です。 こうしておくと外側で新たにJOINするテーブルが増えた時の問題がなくなります。 説明は割愛しますが、そのような問題を抱えていました。 また、内側のSQL文だけでカテゴリーの連結が確認できるので、これを外側とJOINすればいいのだと言う判断もしやすくなります。 ---- SELECT category.object_id AS post_id, GROUP_CONCAT(category.name ORDER BY category.term_id) AS category_names, GROUP_CONCAT(category.slug ORDER BY category.term_id) AS category_slugs FROM ( SELECT sub_a.name, sub_a.slug, sub_c.object_id, sub_a.term_id FROM wp_terms AS sub_a LEFT JOIN wp_term_taxonomy AS sub_b ON sub_a.term_id = sub_b.term_id LEFT JOIN wp_term_relationships AS sub_c ON sub_b.term_taxonomy_id = sub_c.term_taxonomy_id WHERE sub_b.taxonomy = 'category' ) AS category GROUP BY category.object_id ----
- dell_OK
- ベストアンサー率13% (766/5720)
・LIMTに関して理解ができていないのですが、LIMITを付けていないSQL文も実行する必要とは具体的にどのような要素でしょうか? LIMITは何件目から何件分を取得するというものです。 これだと最大で何件分までしか件数をカウントできません。 ですがページナビは最終ページがどこまであるかわかっていないと配置できません。 現在は最大で5ページまでページリンクを配置するようになっていますが、それは最後のページが5ページ以上あった場合のいったん終了位置です。 全ページ数が3ページしかないのに5ページまでのページリンクを配置するのはおかしいですよね。 この全ページ数はどこまであるのかを算出するために、全件数は何件なのかを知る必要があります。 LIMITがあると全件数を知ることができないため、LIMITなしのSQL文を実行して結果を取得する必要があるわけです。 件数そのものを取得するためのCOUNT()と言うSQL関数があるので実際に全件データを取得するよりははやい方法もあります。 ・もしSQLを使用せずに$wpdbで記事を取得していた場合、負担は軽減されるのでしょうか? 同じようにwordpressのdbからデータを取得しているので変わらないのでしょうか? 想像はしていたのですが、質問者さまは思い違いをされているようです。 $wpdbはデータベースへの接続やその他もろもろの面倒を省くためにあるだけです。 [W]ord[P]ress[D]ata[b]aseの略称にすぎません。 $wpdbが何をしているのかと言うと、内部でSQL文を生成してSQLを実行してデータを取得してデータを加工して結果を返してくれたり表示してくれたりしています。 この度SQL文を書いたのでまったく別のことをされていると思われていたかも知れませんが、それは、$wpdbがSQL文を生成しているところを手書きしただけです。 $wpdbが複雑なことをしてなるべくデータベースへのアクセスを繰り返さないよう一度取得したデータはメモリ内で処理するような仕組みにはなっていそうなので極端な負荷はかかっているように感じないかも知れませんが、自分でSQL文を書いて(負荷のかからないような記述である前提)データを加工した方が、$wpdbがやっている無駄っぽいことを省けます。 $wpdbを使った方がコードを書く人間の手間は軽減されますが、サーバーの負担は増えていると考えた方が正しいと私は思います。
補足
全ページ数が3ページしかないのに5ページまでのページリンクを配置するのはおかしいですよね。 この全ページ数はどこまであるのかを算出するために、全件数は何件なのかを知る必要があります。 LIMITがあると全件数を知ることができないため、LIMITなしのSQL文を実行して結果を取得する必要があるわけです。 件数そのものを取得するためのCOUNT()と言うSQL関数があるので実際に全件データを取得するよりははやい方法もあります。 A.説明ありがとうございます ということは全件数はCOUNTでSQLで計算するんですかね $wpdbを使った方がコードを書く人間の手間は軽減されますが、サーバーの負担は増えていると考えた方が正しいと私は思います。 A.SQLの方が自分で操作しているので負担が大きいかと思っていたのですが、そうでもないのですね勉強になりました。 確認なのですが$wpdbとphpmyadminを使って格納や取得を行う場合はどちらも負担は同じでしょうか。
- dell_OK
- ベストアンサー率13% (766/5720)
オフセットについては新しいSQL文でも簡単に付けることができます。 まずSQL文の最後にLIMITを追加します。 LIMITはRSSのSQL文でも使っています。 ---- 省略 post.post_date DESC LIMIT %d,%d ---- $posts_per_pageと$posts_offsetにはfront-page.phpと同じように以下の方法で算出しておきます。次の処理で使うためこのふたつの変数だけを明示しましたが、当然のことでこれに必要な変数も準備している前提です。 ---- $posts_per_page = $block_per_page * $group_per_block; //ページあたり投稿件数 5×2の10件画像は1なので$posts_per_group省略 $posts_offset = ($current_page - 1) * $posts_per_page; //投稿オフセット ---- あとはprepare()の引数に上記の変数を追加します。 ---- $query = $wpdb->prepare($sql, "%$search_query%", "%$search_query%", "%$search_query%", $posts_offset, $posts_per_page); ---- このようにしてオフセットは簡単に追加できます。 必要な分のデータを取得するためにはこれだけで済む話しですが、私が気にしているのはページナビのために、条件に一致する件数が何件あるかを取得しておかなければならないことです。 そのためにはLIMITを付けていないSQL文も実行する必要があります。 そっくりそのままのSQL文である必要はないのですが、条件に関する部分は必要になってくるので、とりあえずはそのままのSQL文でもいいと思います。 どちらにしても、二回も似たようなSQLを実行させるのは負荷をかけているようなものです。実際にどれくらいの負荷がかかるのかはわかりませんが、心配するほどのことではないとも思っています。 いっそのことLIMITは付けないで全件取得しておいて、オフセットを考慮した何件目から何件を表示するようにした方がいいのかも知れません。 ただ検索結果がページナビを必要とするほどヒットするとしたら、全件取得するのはあまりいい方法とも言えません。 最大件数のデータが蓄積されていないとパフォーマンスの話しをしても実感がわかないと思いますので、なるべく簡単な方法で作るだけ作って、パフォーマンスに問題が出てきたら改良を考えてみるしかなさそうです。
お礼
下記のコードで投稿ページを20件で制限するように書いてみたのですが間違いはありますでしょうか? ※参考サイト https://teratail.com/questions/39007 $posts_offset = ($current_page - 1) * $posts_per_page; //投稿オフセット $page_sum = $posts_per_page / $limit; //何ページになるか $posts_offset = $offset; $offset = $page*$limit;//表示したいデータ数 $limit = 20;//20ページで終了 下記ページにsearch.phpとpage-front.phpを載せているのですが、search.phpに関しまして下記コードの設置場所は正しいでしょうか? post.post_date DESC, post.post_date DESC,wp_postmeta.meta_key ='single_rss_feed1'; LIMIT %d,%d, 画像が1つの場合はタイトルの保持が必要ないのですが、画像が2つ3つの場合の書き方がよく分かりません。アドバイスお願いいたします。 配列を作ってタイトルと画像以外はset_other_dataにまとめたほうがいいのでしょうか? 良い方法が思いつかずfunctionsでSQLのコードをまとめる方法が分からないため、考えてみたのですが分かりませんでした… for ($k = 0; $k < $group_per_block; ++$k) { //ここから画像とタイトルの処理 echo '<ul>'; for ($j = 0; $j < $posts_per_group; ++$j) { $item_index = $i * $group_per_block * $posts_per_group + $k * $posts_per_group + $j;//画像2のときに2番目のタイトルを保存に変える if ($item_index >= count($post_items)) { break; } $item = $post_items[$item_index]; set_other_data($item); if (1 == $j) { //2番目の記事を保存して、タイトルを設定 $keep_item = $item; $title = '<br>'.$item->post_title; } else { //2番目以外のタイトルを設定 $title = ''; } echo "<li><a href=\"{$item->guid}\"><img src=\"{$item->thumbnail}\">{$title}</a></li>"; } echo '</ul>'; //ここまで画像とタイトルの処理 //保存した2番目の記事の日付、カテゴリー、コメント数、記事の抜粋を表示 $item = $keep_item; echo '<ul>'; echo "<li>{$item->post_date}</li>"; if ($item->categories) { foreach ($item->categories as $cat_ID) { $category = $categories[$cat_ID]; echo "<li>{$category->cat_name}</li>"; } } echo "<li><a href=\"{$item->guid}\">{$item->comments}</a></li>"; echo "<li>{$item->post_excerpt}</li>"; echo '</ul>'; } } https://wandbox.org/permlink/8jGkc8FWZJFdunhe page-front.phpで記事が4件しか出力されていないので、そちらについてもアドバイスをよろしくお願いいたします…
補足
---- $posts_per_page = $block_per_page * $group_per_block; //ページあたり投稿件数 5×2の10件画像は1なので$posts_per_group省略 $posts_offset = ($current_page - 1) * $posts_per_page; //投稿オフセット ---- あとはprepare()の引数に上記の変数を追加します。 ---- $query = $wpdb->prepare($sql, "%$search_query%", "%$search_query%", "%$search_query%", $posts_offset, $posts_per_page); ---- このようにしてオフセットは簡単に追加できます。 A.prepareにセットできるんですね。勉強になりました。ありがとうございます。 必要な分のデータを取得するためにはこれだけで済む話しですが、私が気にしているのはページナビのために、条件に一致する件数が何件あるかを取得しておかなければならないことです。 そのためにはLIMITを付けていないSQL文も実行する必要があります。 そっくりそのままのSQL文である必要はないのですが、条件に関する部分は必要になってくるので、とりあえずはそのままのSQL文でもいいと思います。 A.すみません。LIMTに関して理解ができていないのですが、LIMITを付けていないSQL文も実行する必要とは具体的にどのような要素でしょうか? どちらにしても、二回も似たようなSQLを実行させるのは負荷をかけているようなものです。実際にどれくらいの負荷がかかるのかはわかりませんが、心配するほどのことではないとも思っています。 いっそのことLIMITは付けないで全件取得しておいて、オフセットを考慮した何件目から何件を表示するようにした方がいいのかも知れません。 A.なるほど、LIMITとは取得条件を絞ったもので、それ以外にもSQLが必要ということですね。確かに負荷を考えると取得を絞ったほうがよさそうですね。1~200件までを取得することを想定しています。 画像が2件3件の場合も同様で別途検索ページを考えているため、負荷を考えて1ページ5×2の10件×20ページが理想ですが、負荷が多い場合10~20ページの間で軽減できればと考えています。 1つお聞きしたいのですが、もしSQLを使用せずに$wpdbで記事を取得していた場合、負担は軽減されるのでしょうか? 同じようにwordpressのdbからデータを取得しているので変わらないのでしょうか? 今後カテゴリーのクリック数をAjaxで計算してそれをphpファイルにカウントさせて、そこから上位20件を人気カテゴリーとして表示して、そのカテゴリーリンクから記事を出力するコンテンツを考えているのですが、記事に出力するカテゴリーと別に考えているため、SQlで機能を実装するのはかなり難しいと思っております。 ただ検索結果がページナビを必要とするほどヒットするとしたら、全件取得するのはあまりいい方法とも言えません。 最大件数のデータが蓄積されていないとパフォーマンスの話しをしても実感がわかないと思いますので、なるべく簡単な方法で作るだけ作って、パフォーマンスに問題が出てきたら改良を考えてみるしかなさそうです。 A.定期的に自動記事削除は考えているのですが1年単位を想定しているので、データ貯蔵されそうですね。
- dell_OK
- ベストアンサー率13% (766/5720)
・テーマから参考にしたということは何かのサイトを見られたのでしょうか?インストールされたテーマから設計をたどったのでしょうか? インストールされたテーマからプログラムをたどりました。 デバッガというものを使うと、PHPのソースコードを一行(一命令)ずつ実行しながら進めて、たどることができます。 質問者さまもいつか身につけておくと便利になります。 ・front-page.phpと全く同じデザインにしたいのですが、かなり困難なのでしょうか? 私がすっかり失念して、SQL文の説明で以下の条件がなくなってしまっていました。 wp_postmeta.meta_key ='single_rss_feed1' それに加え、front-page.phpと同じデザインにすることを考えると、コードも同じようにしてほぼそのまま使った方がいいような気がします。 SQLでいろいろな項目を取得する方向で進んでいましたが、この条件を追加して、投稿記事IDだけを取得してget_post()を使うか、もしかすると全項目を取得すれば同じようなことができるかも知れませんが、それはこれから確認してみます。 そうすれば、front-page.phpの以下の部分ががらりと変わりますが、変更点はほぼそれくらいになると思います。 ---- $args = [ 'posts_per_page' => $posts_per_page, 'offset' => $posts_offset, ]; $post_items = get_posts($args); ---- 問題はページを切り替えた時に検索文字を引き渡す方法です。 これについても検討してみます。 参考サイトのOFFSETなしの方法では前後のページ移動しかできないので、現在のデザインには不向きかと思います。
補足
インストールされたテーマからプログラムをたどりました。 デバッガというものを使うと、PHPのソースコードを一行(一命令)ずつ実行しながら進めて、たどることができます。 質問者さまもいつか身につけておくと便利になります。 A.プログラムをある程度組み終えた後に実践してみたいと思います ・front-page.phpと全く同じデザインにしたいのですが、かなり困難なのでしょうか? それに加え、front-page.phpと同じデザインにすることを考えると、コードも同じようにしてほぼそのまま使った方がいいような気がします。 SQLでいろいろな項目を取得する方向で進んでいましたが、この条件を追加して、投稿記事IDだけを取得してget_post()を使うか、もしかすると全項目を取得すれば同じようなことができるかも知れませんが、それはこれから確認してみます。 A. SQLで$argsを使う事ができればオフセットを使う事ができ、そこから制限も可能なのですが オフセットをSQLで使用すると現在のブロック機能を扱うのが難しいため、オフセットを使わずにページナビをSQL外で実装する方法を考えておりました 問題はページを切り替えた時に検索文字を引き渡す方法です。 これについても検討してみます。 参考サイトのOFFSETなしの方法では前後のページ移動しかできないので、現在のデザインには不向きかと思います。 A.ありがとうございます ページナビに使える方法かと思っていましたが使えなかったのですね
- dell_OK
- ベストアンサー率13% (766/5720)
投稿記事へのリンクを付けてみました。 ---- <?php $search_query = get_search_query(); ?> <?php global $wpdb; ?> <?php $sql = " SELECT post.ID AS post_id, post.post_title, post.post_date, post.post_excerpt, post.comment_count, post.guid AS post_url, attachment.guid AS thumbnail_url, GROUP_CONCAT(category.name ORDER BY category.term_id) AS category_names, GROUP_CONCAT(category.slug ORDER BY category.term_id) AS category_slugs FROM wp_posts AS post LEFT JOIN ( SELECT * FROM wp_postmeta WHERE meta_key = '_thumbnail_id' ) AS thumbnail ON post.ID = thumbnail.post_id LEFT JOIN wp_posts AS attachment ON thumbnail.meta_value = attachment.ID LEFT JOIN ( SELECT sub_a.name, sub_a.slug, sub_c.object_id, sub_a.term_id FROM wp_terms AS sub_a LEFT JOIN wp_term_taxonomy AS sub_b ON sub_a.term_id = sub_b.term_id LEFT JOIN wp_term_relationships AS sub_c ON sub_b.term_taxonomy_id = sub_c.term_taxonomy_id WHERE sub_b.taxonomy = 'category' ) AS category ON post.ID = category.object_id WHERE post.post_type = 'post' AND post.post_status = 'publish' AND (post.post_content LIKE %s OR post.post_title LIKE %s OR post.post_excerpt LIKE %s) GROUP BY post.ID ORDER BY post.post_date DESC "; $query = $wpdb->prepare($sql, "%$search_query%", "%$search_query%", "%$search_query%"); $results = $wpdb->get_results($query); ?> <?php if ($results) : ?> <ul> <?php foreach ($results as $result) : ?> <li> <?php echo "<a href=\"{$result->post_url}\">{$result->post_title}</a>"; echo $result->post_date; echo $result->category_names; if (empty($result->comment_count)) { echo 'コメントなし'; } else { echo "{$result->comment_count}件のコメント"; } echo $result->post_excerpt; echo "<a href=\"{$result->post_url}/#more-{$result->post_id}/\">続きを読む</a>"; if (empty($result->thumbnail_url)) { $result->thumbnail_url = 'noimage.jpg'; } echo "<img src=\"{$result->thumbnail_url}\">"; ?> </li> <?php endforeach; ?> </ul> <?php endif; ?> ---- タイトルを表示してリンクしている部分の追加はここです。 ---- echo "<a href=\"{$result->post_url}\">{$result->post_title}</a>"; ---- 投稿記事へのリンクとして使えそうなものがwp_postsにありました。 画像と同じでguidです。 SQL文に追加したのはここです。 ---- post.guid AS post_url, ---- guidの名前ではよくないので別名post_urlを付けています。 それをechoで$result->post_urlとして使っています。 「続きを読む」リンクを追加しているのはここです。 ---- echo "<a href=\"{$result->post_url}/#more-{$result->post_id}/\">続きを読む</a>"; ---- 抜粋の次に表示しているのでそれらしく見えます。 テーマTwenty Elevenの続きを見るのURLを参考にして、WordPressの関数を追っかけてみると、URLの構成は以下のようになっていました。 投稿記事へのURL/#more-投稿記事ID/ これにならってリンクのURLを生成しています。 投稿記事の本文に「続きを読む」設定をしていればそこまでスクロールしてくれる仕組みのようです。設定していなければ先頭から表示されます。 設定していないのでしたら、わざわざこのURLを生成しなくても、タイトルのリンクと同じURLでいいと思います。 URLの生成で投稿記事IDが必要だったため、SQL文に追加したのはここです。 ---- post.ID AS post_id, ---- もとの名前IDのままでもよかったのですが、他のIDが今後増えたときに識別しやすいように別名post_idを付けています。 単純に項目を表示しているだけなので、表示をデザインするにはスタイルシートが反映されるようにそれぞれの項目を何かしらのHTMLタグで括りclass属性を書くなどが必要です。
お礼
下記のコードが使えるか心配だったのですが、SQLのページナビはSQLのoffsetでRSSのページナビは別途作成すれば問題ない気がします。 //ページリンク $display_pages = 5; //番号を表示したいページ数 $display_page_count = 0; $pages = ceil($wp_query->found_posts / $posts_per_page); for ($i = 1; $i <= $pages; ++$i) { if (1 == $i) { $page_text = '<<'; echo "<a href=\"?page={$i}\">{$page_text}</a> "; if ($current_page > 1) { $j = $current_page - 1; } else { $j = 1; } $page_text = '<'; echo "<a href=\"?page={$j}\">{$page_text}</a> "; } if ($i >= $current_page && ++$display_page_count <= $display_pages) { $page_text = $i; echo "<a href=\"?page={$i}\">{$page_text}</a> "; } if ($i == $pages) { if ($current_page < $pages) { $j = $current_page + 1; } else { $j = $pages; } $page_text = '>'; echo "<a href=\"?page={$j}\">{$page_text}</a> "; $page_text = '>>'; echo "<a href=\"?page={$i}\">{$page_text}</a> "; } } ?> </div></div></div> <!--ここまで-->
補足
ofsetで投稿の切り替えを行う場合SQL本体でページング機能の制限が行われていた為、これが懸念点でした。 通常の検索ページではホーム画面と同じデザインになる為、難しいようであればglobal $wpdbを扱う方法に切り替えるしか無さそうです。
- dell_OK
- ベストアンサー率13% (766/5720)
検索結果表示ページ(search.php)のことでよかったでしょうか。 私は検索結果を全件表示でいいと思っていますが、ページング機能を付けようとされていますか。
お礼
タイトルを表示してリンクしている部分の追加はここです。 ---- echo "<a href=\"{$result->post_url}\">{$result->post_title}</a>"; ---- 投稿記事へのリンクとして使えそうなものがwp_postsにありました。 画像と同じでguidです。 SQL文に追加したのはここです。 ---- post.guid AS post_url, ---- guidの名前ではよくないので別名post_urlを付けています。 それをechoで$result->post_urlとして使っています。 「続きを読む」リンクを追加しているのはここです。 ---- echo "<a href=\"{$result->post_url}/#more-{$result->post_id}/\">続きを読む</a>"; ----。 A.詳しい説明ありがとうございます。タイトルのリンクから続きを読むを設定できるんですね。guridから使えるのは便利ですね。勉強になります。 抜粋の次に表示しているのでそれらしく見えます。 テーマTwenty Elevenの続きを見るのURLを参考にして、WordPressの関数を追っかけてみると、URLの構成は以下のようになっていました。 投稿記事へのURL/#more-投稿記事ID/ これにならってリンクのURLを生成しています。 投稿記事の本文に「続きを読む」設定をしていればそこまでスクロールしてくれる仕組みのようです。設定していなければ先頭から表示されます。 設定していないのでしたら、わざわざこのURLを生成しなくても、タイトルのリンクと同じURLでいいと思います。 URLの生成で投稿記事IDが必要だったため、SQL文に追加したのはここです。 ---- post.ID AS post_id, ---- もとの名前IDのままでもよかったのですが、他のIDが今後増えたときに識別しやすいように別名post_idを付けています。 単純に項目を表示しているだけなので、表示をデザインするにはスタイルシートが反映されるようにそれぞれの項目を何かしらのHTMLタグで括りclass属性を書くなどが必要です。 A.テーマから参考にしたということは何かのサイトを見られたのでしょうか?インストールされたテーマから設計をたどったのでしょうか? ありがとうございます。勉強になりました。 1点お聞きしたいのですがofsetでSQLの投稿数を制限した場合、RSSのページ当たり件数を指定することはできますでしょうか? 2ブロックに分けて出力する場合、SQLでページネーションを使用するとRSSとの数を計算するのは難しそうなのでその他の方法を考えています。 ※参考サイト https://qiita.com/mpyw/items/07c03600c2e38e91415e
補足
front-page.phpと全く同じデザインにしたいのですが、かなり困難なのでしょうか?
- dell_OK
- ベストアンサー率13% (766/5720)
項目を表示するだけでしたらこんな感じになります。 必要な項目はSQLで取得するようにしているので、WordPressの関数は使わなくて済むようにしたいです。 リンクのhrefをどうするかは検討中です。 search.php ---- <?php $search_query = get_search_query(); ?> <?php global $wpdb; ?> <?php $sql = " SELECT post.post_title, post.post_date, post.post_excerpt, post.comment_count, attachment.guid AS thumbnail_url, GROUP_CONCAT(category.name ORDER BY category.term_id) AS category_names, GROUP_CONCAT(category.slug ORDER BY category.term_id) AS category_slugs FROM wp_posts AS post LEFT JOIN ( SELECT * FROM wp_postmeta WHERE meta_key = '_thumbnail_id' ) AS thumbnail ON post.ID = thumbnail.post_id LEFT JOIN wp_posts AS attachment ON thumbnail.meta_value = attachment.ID LEFT JOIN ( SELECT sub_a.name, sub_a.slug, sub_c.object_id, sub_a.term_id FROM wp_terms AS sub_a LEFT JOIN wp_term_taxonomy AS sub_b ON sub_a.term_id = sub_b.term_id LEFT JOIN wp_term_relationships AS sub_c ON sub_b.term_taxonomy_id = sub_c.term_taxonomy_id WHERE sub_b.taxonomy = 'category' ) AS category ON post.ID = category.object_id WHERE post.post_type = 'post' AND post.post_status = 'publish' AND (post.post_content LIKE %s OR post.post_title LIKE %s OR post.post_excerpt LIKE %s) GROUP BY post.ID ORDER BY post.post_date DESC "; $query = $wpdb->prepare($sql, "%$search_query%", "%$search_query%", "%$search_query%"); $results = $wpdb->get_results($query); ?> <?php if ($results) : ?> <ul> <?php foreach ($results as $result) : ?> <li> <?php echo $result->post_date; echo $result->category_names; if (empty($result->comment_count)) { echo 'コメントなし'; } else { echo "{$result->comment_count}件のコメント"; } echo $result->post_excerpt; if (empty($result->thumbnail_url)) { $result->thumbnail_url = 'noimage.jpg'; } echo "<img src=\"{$result->thumbnail_url}\">"; ?> </li> <?php endforeach; ?> </ul> <?php endif; ?> ----
お礼
調べてみたのですが$posts_per_blockというのがSQLでも使用できるのか分からなかったため、per block SQLという似たコードを見つけました。ほかにもSQLで使用できるか組んでみたのですが、どうでしょうか? Wordpressの関数を使わない方法が分からなかったため、 ※以下上記を踏まえたコードをfront-per.pageを参考に書いてみました。$argsを$sqlに変えてみたのですが、調べてみて出てこなかったので使用できるかわからない状態です。 per block SQL(使える),post_count(使える),block_page(使えるかわからない),$group_block(SQLで使う),$posts_per_page(使える), $posts_offset(使える), //使えるかわからない $sqlは使えない気がする $sql = [ 'posts_per_page' => $posts_per_page, 'offset' => $posts_offset, 'meta_key' => 'single_rss_feed 1',/*カスタムフィールドのフィールド名*/ ]; $post_items = get_posts($sql); ※以下上記を踏まえたコード _________________________ $group_per_block = 5; //ブロックあたり投稿グループ件数 //投稿読み込み $per block SQL = $result->post_count / $block_page;//元々設定したコードを追加 $posts_per_page = $block_page * $group_block; //ページあたり投稿件数 5×2の10件画像は1なので$posts_per_group省略 $posts_offset = ($current_page - 1) * $posts_per_page; //投稿オフセット $sql = [ 'posts_per_page' => $posts_per_page, 'offset' => $posts_offset, 'meta_key' => 'single_rss_feed 1',/*カスタムフィールドのフィールド名*/ ]; $post_items = get_posts($sql);
補足
回答ありがとうございます。 そのまま使用することが可能なんですね。勉強になります。 一度functionにコードを書いてそこから呼び出す必要があるのではないかと思ってました。 データベースからのデータでも条件を指定するときにデータベースに接続するものかと思っておりましたが、echoの時に条件分岐できるのは覚えておきます。 コードを詳しく確認して、再度ページナビまで自分で考えてみます。
お礼
コードの修正ありがとうございます。 どうしても腑に落ちなかったため先に質問だけをしてしまいました。すみません。 あと2日で質問の期限が切れてしまうので、続きはこちらにお願いいたします。 https://okwave.jp/qa/q10006002.html
補足
2.画像はWordPress関数で取得するのでなくしました。 3.カテゴリーはWordPress関数で取得するのでなくしました。 4.$post_itemsとして使えるよう取得項目はwp_postsのすべての項目にしました。 A.それぞれSQLで取得しなければいけない項目だと思っていたのですが、postから取得できるのでしょうか? 今回の場合、検索データを使うためにはSQLを通す必要がある。データベースから情報をもらい、そこを通して各項目を表示する、postの場合現在のデータを表示するものだと思っていて、自分の中では$resultを通さないと条件の指定はできないと考えております。 function set_other_data($post)にSresultは通す必要はないのでしょうか? SQLを使い表示する場合は条件もSQLの関数を使うものだと思っておりました。