在 Laravel 中为博客生成归档列表
Posted
技术标签:
【中文标题】在 Laravel 中为博客生成归档列表【英文标题】:Generating archive list for a blog in Laravel 【发布时间】:2013-05-05 21:06:35 【问题描述】:我正在尝试为博客文章生成存档列表。存档列表应按时间倒序显示年份和日期,如下所示:
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));
我该如何实现上述目标?
【问题讨论】:
【参考方案1】:为了在某种导航面板中生成链接,您可以在数据库端进行大部分处理,而不是使用这样的查询获取所有博客文章记录
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 方面的专家,但是应该用类似的东西来实现
$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;
输出:
| 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
【讨论】:
谢谢。 SQL 查询有效,但我认为这不是 Laravel 中原始查询的方式,所以它不起作用。【参考方案2】:这是最优雅的方法是将闭包传递给 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
【讨论】:
非常优雅!默认情况下有一个问题,排序是 asc !从 2013 年、2014 年等开始……如何在 desc 中对其进行排序? 我找到了解决方案:News::orderBy('created_at', 'desc')->get()->groupBy(function($date) 这并没有完全返回 OP 所要求的内容,他想要一个包含每个月的帖子数的月份列表,而这会返回帖子本身,以月为单位进行组织。确实可以在这里使用count()
来解决这个问题,但是它仍然会返回很多不需要的信息……但也许它仍然比自定义 SQL 查询更快?不知道...【参考方案3】:
我也被困了一段时间。通过使用更多 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
【讨论】:
【参考方案4】:我认为你很接近,但你需要测试数据,这是你的要求吗?
您也可以查询数据。
我并不是说这是解决问题的唯一方法,但是这将如何工作? 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
继续阅读有关多态性和查询关系、动态属性...
【讨论】:
以上是关于在 Laravel 中为博客生成归档列表的主要内容,如果未能解决你的问题,请参考以下文章