gavin_c's avatar

how to add an archive page in laravel 10?

Hiya, I'm wanting to create an archive section in my blog homepage where it shows the month and year of published posts in descending order as well as the number of posts per month.
I'm also trying to decide whether they need their own blade view (eg: archive.blade.php) within the post directory?
So when you click on each archive link, it routes you to that archive blade file that displays in the url as: website/blogs/{month-year}/
along with the number of posts published for that month.
so when you click on a post within that archive month, it routes you to: website/blogs/{post-title} which brings me to the question of slugs. How to create slugs for each archive link and post title?
Do you add it as part of your post model or controller? what does the routes for these look like?
can you give me a walk through how to set this up?
cheers.

0 likes
1 reply
LaryAI's avatar
Level 58

To create an archive page in Laravel 10, you can follow these steps:

Step 1: Update Your Routes

First, define the necessary routes in your web.php file. You'll need routes for the archive page and individual posts.

use App\Http\Controllers\PostController;

Route::get('/blogs/{month}-{year}', [PostController::class, 'archive'])->name('posts.archive');
Route::get('/blogs/{slug}', [PostController::class, 'show'])->name('posts.show');

Step 2: Create the Controller Methods

In your PostController, add methods to handle the archive and individual post views.

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Models\Post;
use Carbon\Carbon;

class PostController extends Controller
{
    public function archive($month, $year)
    {
        $posts = Post::whereYear('created_at', $year)
                     ->whereMonth('created_at', $month)
                     ->get();

        return view('posts.archive', compact('posts', 'month', 'year'));
    }

    public function show($slug)
    {
        $post = Post::where('slug', $slug)->firstOrFail();

        return view('posts.show', compact('post'));
    }
}

Step 3: Update Your Post Model

Ensure your Post model has a slug attribute. You can generate slugs using Laravel's Str helper.

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Str;

class Post extends Model
{
    use HasFactory;

    protected $fillable = ['title', 'content', 'slug'];

    public static function boot()
    {
        parent::boot();

        static::creating(function ($post) {
            $post->slug = Str::slug($post->title);
        });
    }
}

Step 4: Create Blade Views

Create a posts/archive.blade.php file to display the archive.

@extends('layouts.app')

@section('content')
    <h1>Archive for {{ $month }}-{{ $year }}</h1>
    <ul>
        @foreach($posts as $post)
            <li>
                <a href="{{ route('posts.show', $post->slug) }}">{{ $post->title }}</a>
            </li>
        @endforeach
    </ul>
@endsection

Create a posts/show.blade.php file to display individual posts.

@extends('layouts.app')

@section('content')
    <h1>{{ $post->title }}</h1>
    <p>{{ $post->content }}</p>
@endsection

Step 5: Generate Archive Links

In your main blog page, generate links to the archive pages. You can use a query to group posts by month and year.

$archives = Post::selectRaw('year(created_at) year, month(created_at) month, count(*) published')
                ->groupBy('year', 'month')
                ->orderByDesc('year')
                ->orderByDesc('month')
                ->get();

In your Blade view, loop through the $archives to create links.

<ul>
    @foreach($archives as $archive)
        <li>
            <a href="{{ route('posts.archive', ['month' => $archive->month, 'year' => $archive->year]) }}">
                {{ $archive->month }}-{{ $archive->year }} ({{ $archive->published }} posts)
            </a>
        </li>
    @endforeach
</ul>

Summary

  • Define routes for archives and individual posts.
  • Create controller methods to handle archive and post views.
  • Ensure your Post model generates slugs.
  • Create Blade views for displaying archives and posts.
  • Generate archive links on your main blog page.

This setup will allow you to have an archive page that lists posts by month and year, and individual post pages accessible via slugs.

Please or to participate in this conversation.