2013-05-11 35 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

對於某種導航面板,你可以完成大部分的加工對DB側面,而不是獲取所有的博客文章記錄生成鏈接像這樣

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 2013-05-14 06:11:15

+0

這對Laravel 4.2中的我非常有用。謝謝! – NightMICU 2014-09-21 19:07:59

0

我認爲你很接近,但是你需要測試這些數據,那是你在問什麼?

您也可以查詢數據。

我並不是說這是解決問題的唯一方法,但這將如何工作? For Each語句可以將數據存儲到一個數組,像這樣:

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

繼續閱讀關於多態性和查詢關係,動態屬性...

14

:HOULD與此類似

$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(); 

如果你願意,你可以這樣

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; 

輸出添加小計到今年行的東西來實現這是最優雅的方式o這樣做是爲了將閉包傳遞給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

非常優雅!默認情況下,一個問題是asc!開始到2013年,2014年等... 如何在desc中對它進行排序? – kesm0 2015-05-20 10:01:26

+0

我找到解決方案: News :: orderBy('created_at','desc') - > get() - > groupBy(function($ date) – kesm0 2015-05-20 10:08:55

+1

這不會完全返回OP所要求的,他想要一個列表我們可以使用'count()'來解決這個問題,但它仍然會返回很多不需要的信息......但也許它是仍然比自定義SQL查詢更快?不知道... – amosmos 2015-07-27 07:48:38

0

我被困在這一段時間爲好。通過使用一些更laravel功能,我來到了以下解決方案:

要創建歸檔:

$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'); 
       }); 
     }); 

然後顯示(包括自舉4班):

<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