7.3 Displaying the Blog
The final piece of the app front-end to implement is the blog itself. In this lesson, we'll set up a couple of routes to display the list of our posts and each individual post.
1.Introduction1 lesson, 01:23
2.Getting Started4 lessons, 46:41
3.Managing Pages6 lessons, 1:12:31
4.User Management2 lessons, 27:37
5.Managing the Blog4 lessons, 41:51
6.Adding Extras2 lessons, 26:07
7.Implementing the Front-End3 lessons, 30:24
8.Homework Review1 lesson, 07:11
9.Conclusion1 lesson, 01:24
7.3 Displaying the Blog
We are finally to the last piece of our application and that is displaying our blog, which is going to be pretty straightforward. There's just a few things that we need to set up first, and we're going to do this with a controller because we are going to essentially do two things. We will show our list of blog posts and then we will show the individual blog posts. And while we could just do those with simple functions within our routes, we're going to use a controller. So let's start by creating that controller, php artisan make controller and we could call this blog controller. But let's just call it blog post controller, because we already have a blog controller and in hindsight, we probably should have called the controller in our admin section, blog post controller. But naming things is hard that's why we have that saying. So blog posts controller is going to be fine. So let's go to our blog post controller and let's start adding some stuff here because the first thing we really want to do is display our list. So we will do that with a public function called index. We don't need to accept any information. And for right now, let's just return a view called blog index. So this means that we need to go to our resource folder. And let's create a folder inside of our views called blog. So new folder, and we will put of course all of our blog views there. Now to get us started, let's take the index view from home, let's paste it into blog. And let's get rid of this content here. We'll still keep our container. But then we want to iterate over all of our posts. So let's start with the for each. We don't have this things yet of course, but we will, so let's say post as post and then we will display all of our posts. And I guess we could go ahead and fill this out since we're here. So let's put everything inside of an article, and at least as far as the display of our list is concerned, let's just have the title and the excerpts. We could make the argument that we also want to display the date and time as well as the author. But let's just stick with those two pieces of information. So we'll have an H2 element that contains an A element, that's going to be for our title. As far as the URL is concerned, let's just leave it with a pound sign for now, and we will come back and add in the actual URL. But for the title, we of course want to use our title property. So we will have that there. And then for the excerpt, let's just use a P element and we're just going to output the excerpt. So that's going to get us started at least. So now that we have our view, let's go ahead and write our index method so that we can provide it data, so that it can display that data. Now, we want to retrieve only the published posts. And if you'll remember, we determine if a post is published based upon the published at field. If it's null, of course it's not published. But if the date is less than the current date and time, then it is published. But if it's in the future, then it hasn't been published yet. Even if it's a second off, it technically has not been published. So we're going to be working with dates. And that means I want to use carbon because it makes it a little bit easier to work with dates and times. So we will say composer require nest box carbon. And we will bring carbon into our controller here. So use carbon carbon. We also want to use our models, so use app post. And then we will just query. So let's say publish equals, we'll say post. And we could make the argument that eventually we want to display the author information here. So let's go ahead and do that. It's not going to be that big of a deal to include the author information. So we'll say with user, where the published at is going to be less than the current date and time. And so we will say carbon now, and we want to order this by the published date and time, but we want it in descending order because that's typically what we want. We want the newest stuff at the top. So we will order by published at descending, and then we could call the get method, but we wants to page inate. Right now, we don't have very many blog posts, but eventually we will. So let's page inate and let's just pick an arbitrary number of 15. So that's going to give us our posts. So we can pass that on to the view. We'll call it posts because that's what we used in the view, and then we have published. Okay, so we have almost everything set up, we need to set up our routes. So let's go to routes > web php, and down here at the bottom we have the old route for home. So let's repurpose this. We're not using that anymore. So it's not gonna hurt its feelings. We'll say blog post controller at index and let's give this the name of blog, because we do need to add a link up here in our nav. So we can do that by specifying a name for our route. So let's do that and then we will test to see how this is working though. Let's put this link before our dynamically generated page links. And it's going to be an li element with an A element. We'll say routes blog and then the text, it doesn't need to be anything but blog. So let's refresh. We see blog now, let's click on blog and we get an error, undefined variable pages. Now we didn't use pages anywhere within the view or anything. So let's read on, that is inside of the partials nav.blade.php. So this is from our composer. If you'll remember, we used a composer to get all of our pages. So that inside of our views, we could generate our menu. The problem is we said that use the pages only inside of our home views. So we want to go to our composer provider, that is inside of the providers and then the composer service provider, and we want to extend this beyond home. We also want our pages inside of our blog views as well, so all we have to do is change this first argument to an array. And then we specify the views in each element of the array. So we have everything inside of home. Now we're going to have everything with blog. So now whatever we go back, let's refresh the page. And we see that it works and we have our blog list. Now of course, these links don't work because we don't have anything yet to display them. So let's go back and let's go to our routes. Let's create another route, one for the individual blog posts. So the URL is going to be blog slash slug. Now, whenever we set up our database, we did not say that slug had to be unique. So we might want to add something else in, like the ID slash slug or something like that. You can make whatever choice you want to do. I'm just going to save slug. This is going to go to the view method on our blog post controller. And let's call this blog view so that we can generate that URL. So let's go to the index view again. And instead of having this pound sign, let's create our URL with the route blog view. And then we will specify the slug information as post slug. So now whenever we go back, let's refresh. Let's look at the URLs, we are getting the appropriate URL, but of course, we haven't written anything else and that view doesn't exist. So let's go back to our blog post controller. And let's add a method for viewing the individual posts. So view, we have the slug coming in, and our query is going to be somewhat similar. We want to retrieve the post with the user, where the published at is less than now, because that's important, we don't want to display just anything. We want to ensure that the blog post is published. But we don't need an order by and we don't need to page inate. Instead, we just need to first or fail, but we also need to specify the slug as well. So with the where, we're going to pass in an array of arrays where one of our tests is of the published field and then the other is for the slug. So let's do this slug first. We'll say slug is equal to whatever was provided to the method and then published at, and then first or fail. So then we will simply return the view. We call that blog view, and we'll pass that data as post and post there. Let's change that variable name and let's make this look nice and clean. And there we go, so we need a blog view. And so we will go to our blog folder. Let's just copy what we have with index. And we will rename it to view.blade.php because this is going to have quite a bit of what we want. We still want the article, we want the H2 and the link, but we also want to include author information and the date time. So let's put that inside of a P element, we will say published by and then we will include the post user name and then the date. Now if we just say post published at, we're going to get the exact data that we have in the database. So this is something that we will need to adjust here. But let's finish by outputting the body, and there we go. Now in this particular blog post, I did add some HTML in it. So here's what we could do. We could either just output the body safely or we could also make it raw, whichever you think that you need to do go for that. I'm gonna go for the raw view so that we can see that HTML, and there we go. Now, the date is something that I want to address, we want something that's a little bit more readable. And you can also make the argument that the end user doesn't really care about the time, it's just the date. Now since we have carbon, we can use it to parse this into a formatted date string. And we could do that inside of our view, but that's adding a little bit of extra logic and we have something that allows us to do that extra logic outside of the views, it's the presenters. So let's write another presenter. Actually, we're going to copy and paste a presenter and then make a few changes. So we'll take our page presenter, and we will rename it to post presenter. And let's add a method called in published date. So published date, and we will return carbon. We're going to parse the timestamp that the published at field gives us, and then we wants to return to formatted date string. Now of course, we need to bring in carbon. So let's do that. And we also need to set up this presenter with our post model. So after we finished bringing in carbon, let's go to our posts, and there it is. Actually, let's open up page so that we can just copy and paste. We want to use layer casts presenter presentable traits. Let's paste that into post. We also need to use that trait, so let's use presentable trait, and we also need to set that protected presenter variable as well, and the path to that is app presenters post presenter. So now inside of our view, let's go back, we can use that method. So instead of publish that we will say present and then published date. So whenever we view it in the browser, we should just see an error apparently, I need to change the name here. So post presenter, so I'm gonna have to change the name. You just got to change the class name as well. So now we have a readable date. It's not that the other wasn't readable, but this is much more readable. And so now we are done. We are displaying our list of blog posts, and then we are displaying the individual blog post. One last thing though, we need to set up the UI for the page nation and index, but that's easy enough to do. We just have to say hosts render, and we're good to go. So now we are done displaying our blog.