How to create Archive block of the content type

  • Posted on: 11 December 2019
  • By: stillfinder

Let's say we have a Post model and we want to create an Archive block. Something like this:

- December 2019
- November 2019

First of all we need to add archives function to our model:

public static function archives()
        return static::selectRaw('year(created_at) year, monthname(created_at) month, count(*) published')
            ->groupBy('year', 'month')
            ->orderByRaw('min(created_at) desc')

Then add to our boot method of AppServiceProvider the next:

View::composer('web.partials.archives', function ($view) {
    $view->with('archives', Post::archives());

And finally, something like that to our blade template:

@foreach($archives as $stats)
        <a href="/?month={{ $stats['month'] }}&year={{ $stats['year'] }}">{{ $stats['month'] . ' ' . $stats['year'] }}</a>

After that, we can change the index method in our controller to filter by the provided month / year values. For example:

public function index(Request $request)
        $posts = Post::latest()
            ->filterByDate(request(['month', 'year']))
        return view('web.posts.index', compact('posts'));

Post model:

    public function scopeFilterByDate($query, $filters)
        if (isset($filters['month'])) {
            $query->whereMonth('created_at', Carbon::parse($filters['month'])->month);
        if (isset($filters['year'])) {
            $query->whereYear('created_at', $filters['year']);

BTW, if you are using pagination, you should add pagination links like below. Otherwise the month/year parameters will be replaced by the pagination query parameter

{{ $posts->appends(request()->input())->links() }}