Laravel how to add pagination on categorized posts - php

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>
{{ $blog->title }}
</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;">
{{ $blog->title }}
</div>
#endforeach
<div>
{{ $blog_posts->links() }}
</div>
but now, I don't know how to add the pagination?
can someone help me out

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

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]);

Related

Call to undefined method Illuminate\Database\Eloquent\Builder::links() (View: D:\xampp\htdocs\mieaceh\resources\views\shop.blade.php)

I am trying to paginate my categories shop.blade.php but I get this error:
Call to undefined method Illuminate\Database\Eloquent\Builder::links()
(View: D:\xampp\htdocs\mieaceh\resources\views\shop.blade.php)
Here is my MenuController.blade.php
if (request()->category) {
$menu = Menu::with('categories')->whereHas('categories', function ($query) {
$query->where('slug', request()->category);
});
$categories = Category::all();
$categoryName = $categories->where('slug', request()->category)->first()->name;
} else {
$menu = Menu::inRandomOrder()->take(10)->paginate(8);
$categories = Category::all();
$categoryName = 'Featured';
}
return view('shop')->with([
'menu' => $menu,
'categories' => $categories,
'categoryName' => $categoryName,
]);
and my shop.blade.php
<div class="category text-center">
#foreach($categories as $category)
<a href="{{ route('menu.index', ['category' => $category->slug]) }}">
<div class="card-category" style="width: 10rem; height: 4rem;">
{{ $category->name }}
</div>
</a>
#endforeach
{{ $menu->links() }}
How to solve it?
Right now, if you have a request()->category, then you're not adding the paginate to the $menu query. Just add it
$menu = Menu::with('categories')->whereHas('categories', function ($query) {
$query->where('slug', request()->category);
})->paginate(8);
You are missing pagiante() method on your menu query:
$menu = Menu::with('categories')->whereHas('categories', function ($query) {
$query->where('slug', request()->category);
})->paginate(8);
The way you did your query, you were returning QueryBuilder class, which has no links() method (pagination). This way you will return collection of data which you will be able to paginate.

How to paginate ítems inside relationship in Laravel?

I have model Category with relation products:
public function products()
{
return $this->hasMany(Product::class);
}
In MainController I have code:
$products = Category::with('products')->whereNull('parent_id')->paginate(15);
Method paginate only paginate categories, but How I can paginate products?
It's not a good idea to use pagination inside another pagination, but if you want to do this, you should create manual pagination for products of each category:
use Illuminate\Pagination\LengthAwarePaginator as Paginator;
use Illuminate\Http\Request;
$categories = Category::with('products')->whereNull('parent_id')->paginate(15);
foreach ($categories as $category) {
$count = $category->products->count(); // total count of products in this category
$limit = 10; // count of products per page in child pagination
$page = $request->input('category'.$category->id.'page', 1); // current page of this category's pagination
$offset = ($page * $limit) - $limit; // offset for array_slice()
$itemsForCurrentPage = array_slice($category->products->toArray(), $offset, $limit, true);
$paginator = new Paginator($itemsForCurrentPage, $count, $limit, $page, [
'path' => $request->url(),
'query' => $request->query(),
]);
$paginator->setPageName('category'.$category->id.'page');
$category->paginator = $paginator;
}
return view('categories.index', ['categories' => $categories]);
And then in your categories\index.blade.php:
<ul>
#foreach ($categories as $category)
<li>
<h3>{{ $category->title }}</h3>
#if ($category->paginator)
<ul>
#foreach ($category->paginator->items() as $product)
<li>{{ $product['title'] }}</li>
#endforeach
</ul>
{{ $category->paginator->links() }}
#endif
</li>
#endforeach
</ul>
{{ $categories->links() }}
I hope this helps, but I say it again, it's not a good idea to use pagination inside another pagination.

having laravel category (slug based) posts with pagination

I have this function, where i get my categories base on their slug
public function postcategoryposts($slug){
$category = PostCategory::where('slug','=',$slug)->firstOrFail();
return view('front.postcategory-posts', compact('category'));
}
Currently i'm getting my each category posts in blade like:
#foreach($category->posts as $post)
{{$post->title}}
#endforeach
until here everything is normal, the problem is how to divide my posts into pages? I am not able to use:
$category = PostCategory::where('slug','=',$slug)->paginate(10);
because I'm using
firstOrFail();
any idea?
You need to add a function to your model to get posts and then paginate.
In your controller
public function postcategoryposts($slug)
{
$category = PostCategory::where('slug','=',$slug)->firstOrFail();
$posts = $category->getPaginatedPosts(10);
return view('front.postcategory-posts', compact('posts'));
}
In your model
// PostCategory model
public function getPaginatedPosts($limit = 10)
{
// Get category posts using laravel pagination method
return Post::where('category_id', '=', $this->id)->paginate($limit);
}
In your blade view
<div class="container">
#foreach ($posts as $post)
{{ $post->title }}
#endforeach
</div>
{{ $posts->render() }}
More informations about Laravel pagination here
Hope it's helps you :)

Laravel Paginate not working

I was trying to paginate some data with Query builder with the following query.
public function productSearch(Request $request)
{
$name = $request->name;
$products = DB::table('products')
->where('name', 'LIKE', "%$name%")
->paginate(4);
return view('product',compact('products');
}
But when I tried to show the pagination in the view page with the following line
{{ $products->links() }}
It shows
Method links does not exist
What could the possible error be since the pagination does not show?
2 types to print pagination link in laravel -
Try with -
use Illuminate\Support\Facades\DB;
public function productSearch(Request $request)
{
$name = $request->name;
$products = DB::table('products')
->where('name', 'LIKE', "%$name%")
->paginate(4);
return view('product',['products' => $products]);
}
In View -
<div class="container">
#foreach($products as $product)
<h4>{{ $product['name'] }}</h5> <br>
#endforeach
</div>
1st type to defined laravel pagination link -
{{ $products->links() }}
And 2nd type to defined laravel pagination link -
{{ $products->render(); }}
Note - Also you missed in your code -> return view('product',compact('products')); in return view('product',compact('products');
Here is your solution.
Just change your return view option
return view('product')->with('products', $products);
Hope this helps you.
Change to :
return view('product',compact('products'));
In View page try :
{{$products->render()}}
In your Controller:
return view('product',compact('products');
In your View:
#foreach($products as $product)
{{ $product->name }}
#endforach
{{ $products->links() }}
try with:
{{ $products->render() }}

Laravel 5.2 - Method links does not exist

i'm passing my array $posts to my view and i'm tryng use pagination but i have the error:
Method links does not exist. (View:
C:\xampp\htdocs\app\resources\views\search.blade.php)
CONTROLLER
$posts = Post::where('visible', 1)
->where('expire_date', '>', $current)->where('delete', 0);
$posts->paginate(1);
$posts = $posts->get();
return view('search', compact('posts'));
VIEW
<div class="pagination-bar text-center">
{{ $posts->links() }}
</div>
Change you code to this:
$posts = Post::where('visible', 1)
->where('expire_date', '>', $current)
->where('delete', 0)
->paginate(1);
return view('search', compact('posts'));
Your code doesn't work because you do not save paginate() results to a variable, like $posts = $posts->paginate(1);. Also, you shouldn't use get() or all() after paginate().

Categories