7.1 Setting Up the Navigation
Our pages are dynamic, and as such, we need to dynamically build our navigation. We'll use a composer to provide our pages to the front-end views.
1.Introduction1 lesson, 01:23
2.Getting Started4 lessons, 45:12
3.Managing Pages6 lessons, 1:12:31
4.User Management2 lessons, 27:40
5.Managing the Blog3 lessons, 42:25
6.Adding Extras2 lessons, 25:48
7.Implementing the Front-End3 lessons, 32:10
8.Homework Review1 lesson, 07:11
9.Conclusion1 lesson, 01:24
7.1 Setting Up the Navigation
Traditionally, all of the hard stuff is in the back end. And then when it comes to the front end, well, that's the easy part because you have everything already done, all of your content managed. All you have to do on the front end is display that stuff and that's going to be very true in our application. We of course need to set up a few things, like we need to change what we display here. We also need to set up the navigation and the ability of viewing our pages. But for the most part, that's going to be fairly simple and straightforward. So we are going to start with what the user sees whenever they come to the root of our application. Right now, they're seeing the welcome view. That is of course inside of our resources views and then welcome.play.php. Now I typically think of this as the homepage. And it might be just because I'm old fashioned, but the front page has always been the homepage. And I also think of all of the little extension pages like About in contact. I think of all of those things as home. And when it comes to the blog or the admin portal, or something else that is very, well, it's very specific. I think of those as separate pieces. But anything that's informational about the site itself, I still consider home. So I want to call this home. Now, we have a home controller already. It was given to us whenever we ran the authentication scaffolding and we can reuse that, and we will. But I also wanted to think about the organization of the views which we are gonna create. Because I want to put all of these that are really going to be used on the frontend, inside of their own folder, and home to me makes sense. So I'm going to create a new folder simply called home, and let's use the home.blade.php file as the index view, inside of home. So let's do that index.blade.php. And we don't want to use the app layout. We definitely want a layout page because we want all the pages within our application to have the similar look and feel. But we don't want to use the layout that we used for our admin because that has a bunch of admin stuff. There's nothing that says that we can't use it. But I like to keep the layout pages separate so that the admin has its own layout page, and then the frontend has its own layout page. So let's take our app blade PHP. Let's copy it and let's rename the copy to frontend.blade.php and we will get rid of all of the administration links because we don't need that here. Now we do still need the links for logging in and things like that, so we will leave that. But everything else we'll just delete. And that will be a good starting place because we still want to add our navigation, which we will do up here. But then we need to set up the routes and all of that stuff. So let's go to our routing file, web.php, and let's change this so that the root of our application is going to be handled not by this function but by home controller and its index method. And of course, if we try to see that in the browser, we are still going to login because there is some authentication middleware being used that forces the user to log in. So we need to go to home controller and let's get rid of that off.middleware inside the constructor. And then for our index method, we will simply say home index as the view. So now, whenever we go to the root of our application, we see our index page but let's change this so that it explicitly says this is the index. So we will keep the container, but then we will say this is the index on home. Of course we would have whatever we needed for our homepage here, but this is going to be fine. So that now we need to focus on getting our navigation. Well here's the thing. Our navigation is going to be needed site wide. So if we think about this, it's not a feasible idea to retrieve our pages inside of every method, inside of every controller that's going to need those pages in order to build the navigation. So instead what we can use is called a view composer. It is something that runs for whatever views we specify and it provides data to those views. And it's not necessarily for the controllers and the methods on the controllers, it's more for the views. So we can create one of these view composers that will provide our pages to any view that we specify and they will be available so that we can build our navigation. So we need to go to the command line, and we're going to say php artisan make and we want to make a provider. And we're going to call this ComposerServiceProvider. And then we need to go to our applications config and add that to our providers. So let's go to config@php, and down where the providers are set, we are going to add our composer, so that is app, it created that file inside of providers, and it's ComposerServiceProvider class. So that has that set up. Now let's look at that provider, so we will go to the providers, and there is the composer service provider. So we have this method called boot and this is where we want to set up our composer. Now we can create a composer class and register it here inside of the boot method so that for every home view, we would supply the pages to that. Yeah, I don't want to do that. I want to be as simple as possible here. Now, later on we might think that okay class makes more sense, but in this particular case I don't think so. So the first thing we want to do is add a reference to the view Facade, that is inside of luminate, support Facades, view. Because we are going to use that facade in order to setup this composer. So we will say view composer, inside of the boot method mind you, and then the first argument is the view that we want to supply our pages to. Now, this can actually an array of views and we will get there, but for now, let's say that's for every view inside of home, we want our pages. So then we will have a function that accepts the view. And then we will simply say $view->with, let's call it pages, and then we will supply our pages. So that will be \App\Page. Now in this case we're not going to use the ordered whatever method that we used for displaying our links in order. Instead, we are going to retrieve all of our pages as normal, but now we have a method called toTree. Now, this is being supplied by the nested set package, but this gives us all of our pages in the correct order but it's also organized as a tree. And that's going to make it a lot easier to build our navigation. So for every view that is inside of home, these pages are going to be supplied to those views. And so we don't have to touch any controllers to add the pages there, it's just going to be supplied to those views. So let's go to our layout page. And inside of that layout page, we want to build our navigation right here. However, I want to do it like this. I want to include a partial view that's going to build our navigation. So we can call it partials.nav. And that means that we will need a folder inside the views called partials. So let's do that and then inside of partials, we'll create a new file called navblade.php. The navigation is going to be very similar to what we did in the admin. Whereas if we have a page that has any child pages, then it's going to be a drop down, otherwise it just going to be a normal link in the nav bar. So the first thing we want to do is loop over our pages and we will call each one just simply page. And then we will need to check to see what class that we want to use. Because if we have a drop down, then we have to use the drop down class. Otherwise we shouldn't have the drop down class because there won't be anything to drop down. However, let's start by just saying dropdown, and then we will add in the logic for displaying the correct class there. So after we have our li element, we need our link. The href is going to point to the URL property, and of course, the text is going to be the page's title. But after the title, we need the caret if we have a drop-down. So we can check that with an if statement. We will count the children of the page, and if we have any, then of course we need to display that span. So we will say span and caret and then we essentially want to perform the same check after the link because if we do have any children, then we want to display them in a sub-menu. So we will just copy and paste that check and inside of here we will have a UL element, but we need to give it a class of drop down menu. And then we need to build all of the li elements for this, and so we can do that very easily by just including this same partial nav view, so we are going to get some recursion here. And we can say that all of the pages in this partial view is going to be page, children. So we should be able to at least see this working. So let's go to the browser, let's refresh, and nothing. Okay, frontend isn't saved, so let's save that and again nothing. Okay, let's go to Index and here we are using the app. So let's change that to frontend. So now we should see our links and we do. Now it doesn't look like that there's a submenu here, but remember that we are only displaying the caret if there are any children. If we inspect this, then we see that the li element has a class of dropdown. So it is still an issue that we need to fix. Something else is that if we click on about here, in order to get to the sub menu we have to click. But if we click, it's going to take us to the About page. So we need to open up the sub menu on Hover. So we're going to have to add some CSS to do that because there's not a class that we can just add to the element that specifies that. Okay, so let's first of all work on the class that we want to display here inside of this top level li element because we're going to have to perform some logic. If there's children, then we have a dropdown. If not, then there's nothing. And we could easily do that with $pages->children and so on and so forth, but we have a presenter to do this kinda stuff for us. So let's go to our Presenters folder, and let's open up that PagePresenter. And let's add another method. We can call it dropDownClass. And basically, we just want to determine if we have any children. So we can return this children, we will just use the count method, and if we have any children, then we of course are going to say dropdown, otherwise we won't have anything. So there we go, and that means inside of our view then, we can use our presenter. So we will say page and then present and then dropDownClass. So let's check this out in the browser, let's refresh. Now if we inspect our contact, we should not have an li element with a class of drop down, we don't. That is only for our About. But we still have the issue of clicking there. So we need to add some CSS, but we can't just add a CSS file, although I guess we could. But we can also take advantage of the build tools that we have. Because inside of public CSS, there is this app.css. This is generated by our build process. So we can create our own file, make it part of the build process and then you would have it here. So if you go to the resource and then assets and then SAS. This app.scss is where everything is defined. So it's going to pull in everything here and then that other app CSS is generated. So we can also come in here and we can import our own file. Let's just call it frontend. And let's create that file. So we'll create a new file called frontend.scss. And all we want to do set the dropdown to have hover. And whenever that happens, then the dropdown-menu is going to display as block, pretty simple stuff. So now we just need to build that. So we can go to the command line. We can say npm run dev. That's going to build everything. It's also going to pull in our new CSS and add that to app.css, and then we will test it in the browser. So let's hop on over there and let's refresh the page. Whenever we hover over the About, our sub menu displays. So we are well on our way to getting our frontend implemented, we have our front page, we have our nav. So in the next lesson, we want to display our page's content whenever we navigate to them.