Laravel how to add pagination on categorized posts

148 Views Asked by At

I have an laravel-application where I want to add pagination to my "blog-posts"-section. I can make it work when I return all blog_posts, but since they are categorized, the pagination does not work anymore.

Here is my controller

public function index() {
   $blog_posts = Blog::where("publishes_on", "<=", Carbon::now())
      ->orderBy('publishes_on', 'desc')
      ->where('blog_status_id', '=', '2')
      ->with('blog_category')
      ->paginate(4);

   $blog_categories = BlogCategory::get();

   return view('blog.index', compact('blog_categories', 'blog_posts'));
}

and the blade view

@foreach($blog_categories as $category)

   @foreach($category->blog_posts as $blog)

     <div>
        <a href="/blog/{{ $blog->slug }}">{{ $blog->title }}</a>
     </div>

   @endforeach

@endforeach

Before I added the categories, my blade view looked like this

@foreach($blog_posts as $blog)

  <div style="border-top: 2px solid red; padding: 4px;">
     <a href="/blog/{{ $blog->slug }}">{{ $blog->title }}</a>
  </div>

@endforeach

<div> 
   {{ $blog_posts->links() }}
</div>

but now, I don't know how to add the pagination?

can someone help me out

2

There are 2 best solutions below

0
On

You can create your custom pagination: (https://laravel.com/api/5.8/Illuminate/Pagination/LengthAwarePaginator.html)

    $all_posts = Blog::where("publishes_on", "<=", Carbon::now())
        ->orderBy('publishes_on', 'desc')
        ->where('blog_status_id', '=', '2')
        ->with('blog_category')
        ->get();
    $blog_categories = BlogCategory::get();

    $count = count($all_posts);
    $page = (request('page'))?:1;
    $rpp =  4; //(request('perPage'))?:10;
    $offset = $rpp * ($page - 1);
    $paginator = new LengthAwarePaginator(
        $all_posts->slice($offset,$rpp),$count,$rpp,$page,[
        'path'  => request()->url(),
        'query' => request()->query(),
    ]);
    $blog_posts = $paginator;

    return view('blog.index', ['blog_posts' => $blog_posts, 
        'blog_categories' => $blog_categories]);
1
On

You can use setRelation to override blog_posts relationship and have it return a paginated collection instead:

<?php

$blog_categories = BlogCategory::get()
      ->map(function($blogCategory) {
          return $blogCategory
               ->setRelation( 'blog_posts', $blogCategory->blog_posts()->paginate(10) );
         });

Calling paginate() returns an instance of Illuminate\Pagination\LengthAwarePaginator

To get collection of blog posts, use this:

$category->blog_posts->getCollection()

To get pagination links view:

$category->blog_posts->links()

It's all untested, so let me know if it doesn't work