This episode is for members only

Sign up to access "Build A Static File Blog with Laravel" right now.

Get started
Already a member? Sign in to continue
11. Paginating with a Collection macro


This is going to be one of the very rare instances where you want to paginate a Laravel collection. Normally in Laravel, if we're working with data from the database, we can paginate this and fetch only the data we need with each SQL query, bring that data back. And then when we head over to page
two, it will just fetch the next set of records and it will be nice and quick. Now, in our case, we can't do that because we're working with flat files and we're just getting back a Laravel collection. We still can paginate this by going ahead and creating our own pagination macro for collections. So be really wary of this, but for this, it's really our only option unless we
come up with some kind of technique to read the first few files, but it's going to get really messy really quickly. And we're still going to end up with an incredibly fast blog page here. So let's get to work on doing this. We're going to open up our index controller for our posts, and we essentially want to be able to do this. There are some sort of hacks you can do to create
other methods down here, but with these kinds of things, I like to keep these really tightly coupled to the things that we're working with. And creating a macro is the perfect thing for this. Now, if you don't know what a macro is within Laravel, let's open up the base collection class from Laravel and have a look inside of here. You can see that it contains this macroable trait.
All that means is, although this code exists within the Laravel framework and we shouldn't modify it, we can still add methods onto this collection class to modify it. So this is really handy. So we can do this in any service provider. I'm just going to do this in the app service provider, but of course, you can create your own. And let's just take a look at how this works. So
we're going to go ahead and pull in the collection itself, not from Eloquent. We're going to pull in illuminate support collection, and then we're just going to use the macro method. The first argument to this is going to be the name of the macro that we want. So that is going to be paginate, because that's how we want this to work within our code.
The second is a closure, which is going to return and do something. So into here, what do we want to pass in? Well, over in our post index controller, let's start to add this in. So paginate, what do we normally do within Laravel when we're paginating? Well, we just pass in how many we want per page. There are other things that we can pass into here. For example,
the specific page we're on, and we can pass an array of options in. We will include them, but for now, we just kind of want to say how many we want per page. Now for us, we want that to be one because we've only technically got two blog posts. So I'm just going to kind of add this as one so we can see this actually working. So we know that we want to accept in here a per page
value, and we can set a default to that as well if we want to. We can accept in a page, which we want by default to be null, and we can accept in an array of options, which again, by default, we want to just be an empty array. So this is really the only one that we're interested in bringing in. Okay, how do we do this? Well, we go ahead and new up a length-aware paginator
passing these details in. So the first thing we need to do is work out what page we're on. Let's just go ahead and return this new length-aware paginator, which just comes directly from the Laravel framework, and just see what options we need to pass through to the constructor here. So the first thing is the items, which is, of course,
really important because the paginator needs to be aware of the items that need to get passed in. Then we need to know the total amount of items, so the paginator can work out how many pages there are. Then we need to know how many per page, again, so the paginator can work out how many pages to show. The current page, so it can show the correct items on a specific page. And then
lastly, an array of options. So not too tricky. Now, the first thing is we want to work out the items for a specific page. Now, that's going to be really tricky because, remember, we're working within a collection. Luckily, Laravel collections have a method called forPage. So let's just open up our collection from the framework, and let's look for forPage. It's probably not in here,
actually. So let's just have a look forPage. There we go. So it's under that enumerates values trait. So this will take in a perPage and perPage, and within a collection, it will work out the items that should be included for a specific page given a perPage value. So basically just doing this from scratch. So how do we get this? Well, let's just pass this in and always assume we're
on page one for now, and then we'll figure out how to get the current page and pass this in. So we're going to say this forPage, and we're using this because we're in the context of building up this collection macro, which means that we can reference any of the methods that exist on the collection. So forPage one, we're going to hard code that in for now, and then perPage. We know
what perPage is because we're passing it through when we use this over in our post index just here. Okay, so we've got the first one down. The second one is the total amount of records. That's easy because, again, we're working in the context of a collection. We can use count. That will give us back how many items there are. At the moment, we know there are two items within our collection.
The next one is perPage, which, again, is really simple because we're already passing that through. Then we have the page, the current page that we're on. Again, we need to hard code that for now until we can figure out how to get the page we're on, and the last is the options, which is easy because we're just passing these through to here. Okay, so now that we've done this, don't worry
about these red underlines. It's just because we're working within the context of a closure here, which doesn't quite fit a kind of standard, but this will work. So let's give this a refresh, and as you would expect, we've hard coded in page one. This is showing the blog post on page one based on a one per page basis. Let's change this to page two, and there we go. We are technically
now on page two. So let's go and switch this back to one, but now we need to figure out what current page we are on. So let's define out a page variable. We're either going to take in the page that we are specifying when we use this. That's really important. We've included it. We need that to work, or if that's not available, we are going to go ahead and use the paginator class.
So that's under illuminate pagination, and then we're just going to use the resolve current page method. All that will do is it will take from the query string the page that we currently have. Now, if that's not available for any reason, we're going to assume page one. So we're grabbing the current page, assuming page one, or if the page has been redefined in here, then we're just going
to use that. So let's just die dump on page and just see what we get. So let's come over, give this a refresh. We get page one. If I specify page two in here, sure enough, we get two, and so on and so forth. Kind of get the idea. So now that we've got this page variable that comes from either the query string or what we've defined, we can just put this directly into here, and we can put this directly
into here, and we are pretty much done. Let's head over, give this a refresh. Okay, so now I can go ahead and say, well, I want to be on page two, and sure enough, we are now on page two. Now that is all good, but we don't have any pagination links, which is obviously going to be really important, so we need to output them as well.
13 episodes1 hr 11 mins


Let's build a ridiculously fast blog from scratch in Laravel, entirely driven by markdown files. No database required!

Your blog will feature everything you're used to, like syntax highlighting, post tagging and pagination. Plus, it'll render in record time.

Once you're done with the course, you'll be able to add on additional features with ease, style it up how you want and quickly create new posts since there's no need for an admin panel.

Alex Garrett-Smith
Alex Garrett-Smith
Hey, I'm the founder of Codecourse!


No comments, yet. Be the first to leave a comment.