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

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

ただいまの
回答率

90.23%

Wordpressで投稿記事をサムネイル付きでカテゴリごとに1件ずつ表示したい

受付中

回答 4

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 3,086

haaako

score 0

はじめまして。
Webサイトの制作をしているCarolineともうします。

前提・実現したいこと

Wordpressで投稿記事を表示するのに下記ソース(1つ目)を使用しています。
サムネイルがある時ない時の条件分岐を含みます。

今回、これにカテゴリごとに1件ずつ表示する仕様を追加したく、
https://ja.forums.wordpress.org/topic/3160より下記ソース(2つ目)を参考にしたのですが、この2つのソースをうまく組み合わせることができません。。

どなたかお力をお貸しください。お手数ですが、よろしく御願い致します。 

実現イメージ

イメージ説明

ソースコード

<ul>
<li><a href="<?php the_permalink(); ?>">
<?php
$args = array( 'posts_per_page' => 1, 'order'=> '', 'orderby' => 'date', 'category' => '1' );
$postslist = get_posts( $args );
foreach ( $postslist as $post ) :
  setup_postdata( $post ); ?> 
<?php
if ( has_post_thumbnail() ) {
// サムネイル表示
the_post_thumbnail();
} else {
// サムネイルがない場合はNoImage画像表示
echo '<img src="NoImageURL" alt="NoImage">';
}
?>
<?php the_time('Y/m/d'); ?><br />
<?php $cat = get_the_category(); $cat = $cat[0]; { echo $cat->cat_name; } ?><br>
<?php the_title(); ?>
<?php endforeach; wp_reset_postdata(); ?>
</a></li>
</ul>
<?php
$categories = get_categories();
foreach($categories as $category) :
  echo '<h5>' . $category->cat_name . '</h5><ul>';
  query_posts('showposts=5&cat=' . $category->cat_ID);
    while(have_posts()) :
      the_post();
      echo '<li>' . get_the_title() . '</li>';
    endwhile;
  wp_reset_query();
  echo '</ul>';
endforeach;
?>
  • 気になる質問をクリップする

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 4

+1

Katsukiさんがおっしゃる様にカテゴリーごとに取得が必要だったと思います。

<?php
 $my_query = new WP_Query( array(
 'cat' => カテゴリーID,
 'posts_per_page' => '1',
 'orderby' => 'date',
 'order' => 'DESC'
 ));
 if( $my_query->have_posts() ) :
 ?>
 <?php while( $my_query->have_posts() ) : $my_query->the_post(); ?>
  <div class="container">
 <div class="row">
 <div class="col-md-4">
<?php
if ( has_post_thumbnail() ) {
the_post_thumbnail();
} else {
echo '<img src="NoImageURL" alt="NoImage">';
}
?>
 </div>
 <div class="col-md-8">
 <p><?php the_time('Y/m/d'); ?></p>
 <p><?php the_category(); ?></p>
 <p><?php the_title(); ?></p>
 </div>
 </div>
 </div>
 <?php endwhile; ?>
 <?php else : ?>
 <?php endif; ?>

上記コードを繰り返し使う事で実現出来るかと思います。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/03/07 13:42

    上記組み方は「bootstrap」ありきのものになっておりますので、適宜その部分の指定を変えていただければ応用できると思います。

    キャンセル

0

検証もしていませんし、望んでいる動きもちゃんと把握してないのにアレですが。
WordPress Codex 日本語版 を見ると、get_posts の category パラメータについて、

category パラメータはコンマ区切りの複数カテゴリー ID でもかまいません。

とありますが、これを利用すること、すなわち、

$args = array( 'posts_per_page' => 1, 'order'=> '', 'orderby' => 'date', 'category' => '1,2,3,4,5' );
$postslist = get_posts( $args );


とすることで、ご希望の動作になるでしょうか。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2016/01/28 09:59

    はじめまして。
    拙い質問に回答ありがとうございました。
    いただいたソースで差し替えをしたところ、カテゴリ1の記事が5件表示されました。
    少し、質問内容を修正しましたので、引き続きお力をお貸しいただければ幸いです。

    キャンセル

  • 2016/01/28 10:09 編集

    get_posts() で category=>'1,2,3,4,5' を渡すと、カテゴリー ID が 1 ~ 5 の記事が取れるけれど、カテゴリー ID が 1 の記事が 5 以上あると、先頭の五つはそのカテゴリーだけになってしまう、というわけですね、きっと。
    ほんと、検証なしの回答でごめんなさい。

    追記。
    これも勘違いですね。カテゴリID が 1 ~ 5 の記事を 1 件だけ取ってくる、というのを 5 回繰り返すからカテゴリ ID が 1 の記事が 5 回表示されるのですね、きっと。

    キャンセル

  • 2016/01/29 12:40

    そうですね、追記いただいたイメージです。
    カテゴリ1の記事が5回表示されている形になっています。
    わざわざ追記いただきありがとうございます。

    キャンセル

0

回答にはなっていませんので、コメントに書くのが妥当な内容ですが、シンタックスハイライトしてくれるとうれしいので回答の方に書きました。

方針としては「mysql からは可能性のある投稿をがつっと持ってきて、PHP 側で集計&ソートして投稿リストを作る」か、「SQL の組み立てを頑張って必要なリストを mysql から引っ張ってくる」か、のどちらかですが、後者の方が望ましいですよね。

とりあえず、mysql に直に問い合わせて、おそらくご希望の投稿リストを作ることには成功したと思います。カテゴリの一覧を出すのですが、そのカテゴリのついた最新の投稿の情報もつける、という感じになっています。ので、複数のカテゴリに同一の投稿がくっついてくるケースがあります。
あ、あと、テーブルの prefix が 'wp_' の場合ですね。

select
   main_posts.post_title as 'title',
   main_posts.post_date as 'date',
   main_cat.term_id as 'cat_id',
   main_cat.name as 'cat_name'
  from wp_posts as main_posts
    inner join wp_term_relationships on main_posts.ID = wp_term_relationships.object_id
    inner join wp_terms as main_cat on main_cat.term_id = wp_term_relationships.term_taxonomy_id
  where
    not exists (
     select 1
       from wp_posts as sub_posts
       inner join wp_term_relationships on sub_posts.ID = wp_term_relationships.object_id
       inner join wp_terms as sub_cat on sub_cat.term_id = wp_term_relationships.term_taxonomy_id
     where
       main_cat.term_id = sub_cat.term_id
         and
       main_posts.post_date < sub_posts.post_date
         and
       post_type = 'post'
         and
       post_status = 'publish'
     order by
       post_date desc
    )
      and
    post_type = 'post'
      and
    post_status = 'publish'
  order by
    cat_id
  ;

あとは、WordPress のカスタムクエリ機能を使って、どうにかこれ相当の sql を発行できないか、というところでしょうか。


2016-01-30 17:30 追記

サブクエリを含むクエリを、WordPress のフックを使ってきれいにやる方法がわからなかったので、$wpdb->get_result() を直接叩く方法でやってみました。
あと、とりあえずの実装なので css もべた書きしてしまいましたが、本来は別ファイルにすべきですね。

表示すべきカテゴリ名も、get_categories() を使わず、$post に入っているものを使えば余計な関数アクセス、DB アクセスがなくていいかな、と思いました。まだちゃんと把握していませんが、$wpdb->get_results() に渡すクエリでエイリアスをつけると (この場合 main_cat.name as 'cat_name' として cat_namne というエイリアスをつけています) それを簡単に拾えるみたいです (この場合 $post->cat_name)。

<?php
global $wpdb;
$query = "                                                                                                                                                      
select                                                                                                                                                          
   main_posts.*,                                                                                                                                                
   main_cat.term_id as 'cat_id',                                                                                                                                
   main_cat.name as 'cat_name'                                                                                                                                  
  from $wpdb->posts as main_posts                                                                                                                               
    inner join $wpdb->term_relationships on main_posts.ID = $wpdb->term_relationships.object_id                                                                 
    inner join $wpdb->terms as main_cat on main_cat.term_id = $wpdb->term_relationships.term_taxonomy_id                                                        
  where                                                                                                                                                         
    not exists (                                                                                                                                                
     select 1                                                                                                                                                   
       from $wpdb->posts as sub_posts                                                                                                                           
       inner join $wpdb->term_relationships on sub_posts.ID = $wpdb->term_relationships.object_id                                                               
       inner join $wpdb->terms as sub_cat on sub_cat.term_id = $wpdb->term_relationships.term_taxonomy_id                                                       
     where                                                                                                                                                      
       main_cat.term_id = sub_cat.term_id                                                                                                                       
         and                                                                                                                                                    
       main_posts.post_date < sub_posts.post_date                                                                                                               
         and                                                                                                                                                    
       post_type = 'post'                                                                                                                                       
         and                                                                                                                                                    
       post_status = 'publish'                                                                                                                                  
     order by                                                                                                                                                   
       post_date desc                                                                                                                                           
    )                                                                                                                                                           
      and                                                                                                                                                       
    post_type = 'post'                                                                                                                                          
      and                                                                                                                                                       
    post_status = 'publish'                                                                                                                                     
  order by                                                                                                                                                      
    cat_id                                                                                                                                                      
";
$postslist = $wpdb->get_results($query, OBJECT);
global $post;
?>
<style>
ul.wp2clist {
  list-style-type: none;
}
div.wp2box {
  display: table;
}
div.wp2box .wp2image {
  display: table-cell;
}
div.wp2box .wp2title {
  display: table-cell;
  list-style-type: none;
}
</style>
<ul class="wp2clist">
<?php foreach ( $postslist as $post ) :
    setup_postdata( $post );
    $link = get_permalink();
?>
  <li>
   <div class="wp2box">
    <div class="wp2image">
      <a href="<?php echo $link; ?>">
<?php
    if ( has_post_thumbnail() ) {
        // サムネイル表示                                                                                                                                       
        the_post_thumbnail();
    } else {
       // サムネイルがない場合はNoImage画像表示                                                                                                                 
       echo '<img src="NoImageURL" alt="NoImage">';
    }
?>
      </a>
    </div>
    <ul class="wp2title">
      <li><a href="<?php echo $link; ?>"><?php the_time('Y/m/d'); ?></a></li>
      <li><a href="<?php echo $link; ?>"><?php echo $post->cat_name; ?></a></li>
      <li><a href="<?php echo $link; ?>"><?php echo $post->post_title; ?></a></li>
    </ul>
   </div>
  </li>
<?php endforeach; wp_reset_postdata(); ?>
</ul>
<?php


function xxx() {
// Exit if accessed directly                                                                                                                                    
if ( !defined( 'ABSPATH' ) ) {
        exit;
}

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2016/02/01 13:49 編集

    回答ありがとうございます!
    自社サーバなのですがmysqlを触れる権限はなく、その辺りは専門外で全然わからないのでどこまでやれるかわかりませんが、いただいたソースを元に少しテストしてみようと思います。
    また、改めて結果報告させていただきます。
    ありがとうございます!

    キャンセル

  • 2016/02/01 16:17

    徐々に複雑なクエリにしていくほうが無難ですが、phpmyadmin もないとするとなかなか大変ですね(私は CLI の mysql コマンドを叩く派ですが)。
    私は次のページを参考に、どんなクエリが mysql に投げられているのかを確認しながら試行錯誤しました。
    http://foreignkey.jp/archives/875

    キャンセル

0

カテゴリ毎にいちいちゲットポストで取得しないといけなかったような気がする。

ループ使うと上手く動作しなかった記憶があります。

アーグも名前変え忘れずに。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

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

  • ただいまの回答率 90.23%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる