2013-05-11 28 views
5

ブログ記事のアーカイブリストを生成しようとしています。次のようにアーカイブリストが新しい順に年と日付を表示する必要がありますLaravelでブログのアーカイブリストを生成する

2013 (21) 
    - May (2) 
    - April (3) 
    - March (5) 
    - February (1) 
    - January (10) 
2012 (10) 
    - December (6) 
    - November (4) 

()内の数字は、その期間内の記事の数があります。年または年を選択した場合は、選択した期間のブログ投稿のみが表示されます。

は、これまでのところ私は実行して、各ブログ記事の年と月を見つけることができました:

$posts = Post::all(); 
$archive = array(); 
foreach ($posts as $post) { 
    $year = date('Y', strtotime($post->created_at)); 
    $month = date('m', strtotime($post->created_at)); 
} 

は、どのように私は上記の目的を達成するために行くのですか?

答えて

14

この

SELECT YEAR(created_at) year, 
     MONTH(created_at) month, 
     MONTHNAME(created_at) month_name, 
     COUNT(*) post_count 
    FROM post 
GROUP BY year, MONTH(created_at) 
ORDER BY year DESC, month DESC; 

出力のようなクエリを使用して:

| YEAR | MONTH | MONTH_NAME | POST_COUNT | 
------------------------------------------ 
| 2013 |  5 |  May |   5 | 
| 2013 |  4 |  April |   3 | 
| 2013 |  3 |  March |   4 | 
| 2013 |  2 | February |   3 | 
| 2013 |  1 | January |   2 | 
| 2012 | 12 | December |   2 | 
| 2012 | 11 | November |   3 | 

私はlaravelの専門家ではないんだけど、それはよ

| YEAR | MONTH | MONTH_NAME | POST_COUNT | 
------------------------------------------ 
| 2013 | 13 |  (null) |   17 | 
| 2013 |  5 |  May |   5 | 
| 2013 |  4 |  April |   3 | 
| 2013 |  3 |  March |   4 | 
| 2013 |  2 | February |   3 | 
| 2013 |  1 | January |   2 | 
| 2012 | 13 |  (null) |   5 | 
| 2012 | 12 | December |   2 | 
| 2012 | 11 | November |   3 | 

SQLFiddle

+0

感謝。 SQLクエリーは機能しましたが、それがLaravelの生のクエリーの方法ではないと思うので、うまくいきませんでした。 – SUB0DH

+0

これはLaravel 4.2で私にとってはうまくいきました。ありがとう! – NightMICU

0

私はあなたが近くだと思っていますが、データをテストする必要があります、それはあなたが求めるものですか?

また、データを照会することもできます。

私はこの問題を解決する唯一の方法ではありませんが、どのように機能しますか?我々は最初の場所でデータをフィルタ処理していた場合は...何をトリックを行うだろう

function checkdate($datein,$posts){ 

    foreach ($posts as $post){ 
     $year = date('Y', strtotime($post->created_at))) 
     $month = date('m', strtotime($post->created_at))) 

     if(($year == $datein->year)||($month == $datein->month)){ 
     //good 
     } 
     else { 
     //bad 
     } 
    } 
} 

、しかし:各ステートメントのため、配列にこのような何かを、データを格納することができます。私はLaravelがそれを扱う良い方法を持っていると確信しています。

多型と照会関係、動的な性質について読んhttp://four.laravel.com/docs/eloquent#query-scopes

キープ...ナビゲーションパネルのいくつかの並べ替えあなたがDB側の処理のほとんどを行うと、全てのブログの記事のレコードをフェッチすることができないでリンクを生成するための

14

:houldはあなたがこの

SELECT YEAR(created_at) year, 
     MONTH(created_at) month, 
     MONTHNAME(created_at) month_name, 
     COUNT(*) post_count 
    FROM post 
GROUP BY year, MONTH(created_at) 
UNION ALL 
SELECT YEAR(created_at) year, 
     13 month, 
     NULL month_name, 
     COUNT(*) post_count 
    FROM post 
GROUP BY year 
ORDER BY year DESC, month DESC; 

出力のような年の行に小計を追加することができますしたい場合は、この

$links = DB::table('post') 
    ->select(DB::raw('YEAR(created_at) year, MONTH(created_at) month, MONTHNAME(created_at) month_name, COUNT(*) post_count')) 
    ->groupBy('year') 
    ->groupBy('month') 
    ->orderBy('year', 'desc') 
    ->orderBy('month', 'desc') 
    ->get(); 

に似た何かを達成することこれは最もエレガントな方法ですこれは、groupBy()コレクションメソッドにクロージャを渡すことです。

$posts_by_date = Post::all()->groupBy(function($date) { 
    return Carbon::parse($date->created_at)->format('Y-m'); 
}); 

その後することができますこれに似たブレード・テンプレートで、それをループ:私もしばらくの間、この上で立ち往生した

@foreach ($posts_by_date as $date => $posts) 
    <h2>{{ $date }}</h2> 
    @foreach ($posts as $post) 
     <h3>{{ $post->title }}</h3> 
     {{ $post->content }} 
    @endforeach 
@endforeach 
+0

非常にエレガント!デフォルトで1つの問題は、並べ替えはascです! 2013年、2014年などに開始... どのようにそれをdescでソートするには? – kesm0

+0

私は解決策を見つけました: News :: orderBy( '​​created_at'、 'desc') - > get() - > groupBy(function($ date) – kesm0

+1

これはOPが尋ねたことを正確に返しません。 'count()'を使ってこの問題を解決することは本当ですが、まだ多くの不必要な情報が返されています...しかし、おそらくそれはそれでもカスタムSQLクエリは高速ですか?わかりません... – amosmos

0

。いくつかのより多くのlaravel機能を使用して、私は次の解決策に来た:

アーカイブを作成するには:(ブートストラップ4クラスを含む)を表示するために次に

$archive = Post::orderBy('created_at', 'desc') 
     ->whereNotNull('created_at') 
     ->get() 
     ->groupBy(function(Post $post) { 
      return $post->created_at->format('Y'); 
     }) 
     ->map(function ($item) { 
      return $item 
       ->sortByDesc('created_at') 
       ->groupBy(function ($item) { 
        return $item->created_at->format('F'); 
       }); 
     }); 

を:

<div class="archive mt-5"> 
<h4>Archive</h4> 

@foreach($archive as $year => $months) 
    <div> 
     <div id="heading_{{ $loop->index }}"> 
      <h6 class="mb-0"> 
       <button class="btn btn-link py-0 my-0" data-toggle="collapse" 
         data-target="#collapse_{{ $loop->index }}" 
         aria-expanded="true" 
         aria-controls="collapse_{{ $loop->index }}"> 
        > 
       </button> 
       {{ $year }} 
      </h6> 
     </div> 

     <div id="collapse_{{ $loop->index }}" class="collapse" aria-labelledby="heading_{{ $loop->index }}" 
      data-parent="#accordion"> 
      <div> 
       <ul style="list-style-type: none;"> 
        @foreach($months as $month => $posts) 
         <li class=""> 
           {{ $month }} ({{ count($posts) }}) 
         </li> 

        @endforeach 
       </ul> 
      </div> 
     </div> 
    </div> 
@endforeach 

関連する問題