‫In this video and the next one,
‫together we're gonna build the tour detail page.
‫And along the way
‫you're gonna learn some more Pug techniques
‫like conditionals and mixins.
‫And as I showed you before,
‫this is what the tour detail page actually looks like.
‫And so that's what we're going to build in this video
‫and the next one.
‫Now the only thing that we're gonna leave
‫for a bit later
‫is actually this map.
‫All right, but everything else
‫we're going to build in these tool lectures.
‫Including these reviews.
‫All right.
‫So right now we have our overview
‫and we have of course
‫these buttons with the URLs already created.
‫But then when we try to access this page
‫we of course get this error.
‫All right.
‫So let's go back to our VS code
‫and I actually want to start this
‫with a small challenge for you.
‫So what I want you to do
‫is to create a route for the detail page
‫according to the URL that we just built before.
‫And it's going to be similar
‫to what we already have here
‫but you have to tweak it a little bit.
‫Okay.
‫Enough of that,
‫I also want you to build this controller.
‫So get to it.
‫'Cause right now we only have
‫like this place holder.
‫And so let me actually give you the steps here.
‫And so as always,
‫first,
‫we need to get the data.
‫This time for the requested tour.
‫And for that,
‫keep in mind that we actually need the reviews here
‫and also the tour guides.
‫Okay.
‫So,
‫again let's take a look at that.
‫So we have these tour guides here.
‫Right, and so they are a separate data set basically.
‫So users.
‫And then here we also have the reviews.
‫Now these tour guides here,
‫I believe they're actually automatically populated
‫in a model.
‫So let's take a look at that very quick.
‫So the tour model
‫and so,
‫yeah.
‫So down here,
‫we have this auto populate
‫whenever there is a find query
‫but only for the guides.
‫And so don't forget to also populate
‫the reviews.
‫Okay.
‫Then after that,
‫we will build a template
‫but that we will do together okay,
‫so I don't need you to do this part.
‫And then finally,
‫I want you to complete this part here as well.
‫So render
‫template
‫using the data
‫from step one again.
‫All right.
‫So that's very simple as well.
‫And so what I want you to do
‫is to create the route
‫and then also get the data.
‫Okay so pause the video here and good luck with that.
‫So I hope you did that
‫and to let me know, solve it here for you.
‫And we're gonna start with the route.
‫And now all we actually need to add here is this slug.
‫And of course, we're doing that as a URL parameter.
‫So just like this, calling it slug.
‫So before we use the ID right?
‫And so we had it like this
‫and now let's just call it the slug.
‫All right.
‫Because again,
‫that is what the overview page looks like.
‫We have tour slash slug basically.
‫Okay, and so that's what we will then use
‫to create for the tour in the controller.
‫So let's do that now here.
‫So const,
‫tour
‫equal
‫await
‫tour
‫and findone.
‫So this time we cannot use find by ID.
‫Well because, we do not know
‫the ID of the tour.
‫And so instead,
‫we are searching by the slug.
‫And the slug is
‫as I hope you know
‫request.params
‫dot
‫slug
‫all right.
‫And now finally, that's all to populate
‫the arrays field.
‫All right.
‫So the path to populate is reviews.
‫And actually we do not need all the fields here.
‫So let's just specify the ones that we need.
‫And so,
‫that is only the review,
‫the rating,
‫and the user.
‫Because remember
‫that we actually display
‫so the user name and the user photo.
‫And then of course,
‫the review itself and the rating.
‫Okay.
‫Then of course,
‫it's complaining that we didn't use async.
‫And of course I wasn't gonna forget that.
‫But anyway it's good
‫that ES Line warns us about this kind of errors.
‫It really takes away a lot of bugs
‫from development.
‫Okay.
‫And then here of course
‫we're going to pass that tour variable
‫into our tour template.
‫So that one.
‫Give it a save.
‫No more errors.
‫And so that part is actually now complete.
‫And so all we need to do now
‫is to go ahead and build our template.
‫Okay.
‫So,
‫we already should have that here.
‫And that's the dev data.
‫So we have a lot of folders
‫and a lot of data.
‫And it can become a bit
‫confusing at some point.
‫Okay.
‫And so,
‫let's get rid of this placeholder content here.
‫And before we do anything else,
‫let's again take a look at the original HTML file.
‫Which is in that
‫public folder that I just closed.
‫Let's actually close all of these here,
‫'cause I find this really confusing.
‫Okay, the models as well.
‫And so now what we need is public
‫and then tour.html.
‫So the header we already have of course.
‫And then here goes all the content.
‫So,
‫all of these sections
‫that we have on our page
‫are of course translated here as HTML.
‫And just like before,
‫I actually already created a Pug template
‫based on all of this HTML code.
‫All right, we wouldn't want to translate
‫this here manually together.
‫Okay.
‫So I have it here already in this template file.
‫But of course,
‫again, if you feel like it,
‫you can pause the video now
‫and translate this on your own as well.
‫All right.
‫But what I'm going to do now is to
‫go ahead and copy all of this code.
‫Which is still a ton of code as you can see.
‫So let's copy all of this and go into our tour
‫and paste that here.
‫Now the annotation is going to be wrong again.
‫So let's copy, or actually select what we just pasted here.
‫And so everything except the first line is incorrect.
‫But all we need to do here is to add one more tab.
‫And that's it.
‫So now they're all inside of this content block
‫all at the same level.
‫So section
‫and section
‫and so basically all of the sections
‫are now at the same level,
‫so they're all siblings.
‫Great.
‫So let's just close up all of these
‫we no longer need.
‫And so just like before,
‫we now have this static page here
‫with all of this static data.
‫Which we know we'll have to go ahead an replace.
‫But before actually doing that,
‫let's just take a look if our route
‫is already working.
‫Okay.
‫So let's reload it
‫and that gives us the same error.
‫And I guess that's because
‫here we have tours
‫and not tour
‫as I think we have it in our route.
‫Right so here we have tour.
‫And that actually is the way it makes sense.
‫And so let's go ahead and change that here in our
‫overview.
‫Okay and so here
‫we actually want tour.
‫'Cause in fact,
‫we're actually only seeing one tour
‫and not multiple tours.
‫Right?
‫And so if we go back to the overview now,
‫we load it,
‫and now open up The Forest Hiker,
‫then you see that it's going to be tour.
‫And then of course,
‫we get the HTML for the page
‫that we just created.
‫Now for some reason the CSS is not here.
‫Let's just try to reload this.
‫Well, what's going on here?
‫Let's try to inspect this.
‫And I see we have a couple of errors.
‫So we can click on that.
‫And so the reason for the missing CSS,
‫because instead it's trying to load the file
‫in the wrong place.
‫So it's trying to load it in the CSS folder
‫inside of tour.
‫But that of course does not exist.
‫And so that is because
‫we're here on this tour route, okay.
‫And so we need to basically fix
‫the way that we import the CSS in our base template.
‫Let's go there.
‫And so here in fact,
‫we should have another slash.
‫Okay, and the same actually here.
‫And so that's
‫for the exact same reason
‫that I explained to you before in the overview down here.
‫So we started this URL as well with a slash.
‫And so again, that is then going to start
‫at the root of the page.
‫And that's the way it's supposed to work.
‫And in fact, the same applies to all of the images here.
‫So all the images should always
‫also start relative to the root URL.
‫So let's add that very quickly here to all of these images.
‫And,
‫yeah, that's it.
‫So that's all of them.
‫And so,
‫with that we've fixed the overview
‫and also this base file.
‫So if we now reload,
‫we should then get access to the correct CSS.
‫And indeed, here we go.
‫There is just one more error
‫which is here in this image.
‫And so again,
‫it's because it's trying to load it here
‫from the tour
‫and not from the root URL.
‫And so,
‫that problem is here in the header.
‫And so of course,
‫here we also need to make it relative
‫to the root path.
‫Probably the same in the footer.
‫And yeah.
‫All right.
‫Just to quickly confirm that,
‫yeah indeed, here we go.
‫Great.
‫So as I mentioned of course,
‫this has all the static data
‫about The Park Camper Tour
‫which is the one that we have in the template.
‫But we are looking at the forest hiker.
‫And so, let's now start by fixing our template
‫and basically using the dynamic data right in here.
‫So, remember that the variable that we passed in here
‫is called tour.
‫Right?
‫So it's simply called tour
‫and so that's what we have to call it here.
‫So tour
‫.name,
‫and also the same up here.
‫And now you already know that
‫we need to use a template string here
‫because we in fact want to create a string.
‫So named .tour.
‫And here this path is also not correct.
‫First of all it needs to be a template string
‫and then our images,
‫I'll write image slash tours
‫slash the name of the cover image.
‫So tour
‫dot, and now I don't remember if it's image cover,
‫or cover image.
‫So,
‫yeah.
‫Image cover.
‫Okay.
‫So let's quickly try that out.
‫And so remember, we're at The First Hiker.
‫And so that should now be the name.
‫And yet another error.
‫So,
‫it says here, cannot read property tour of undefined.
‫So let's go back and
‫yeah.
‫So here is this stupid mistake.
‫So it's of course tour.name
‫and not name.tour.
‫So,
‫what was I thinking there?
‫Let's reload this
‫and now indeed, we get The Forest Hiker
‫with this real nice cover image in the background.
‫Great.
‫And let's keep moving here.
‫So create yet another template string.
‫Tour.
‫Duration,
‫and then the number of days.
‫Then down here,
‫we have again the start location.
‫So,
‫tour.start
‫location.description, remember.
‫All right.
‫Now down here
‫we have these overview boxes here.
‫So overview box detail.
‫And as you see,
‫we have four equal boxes here
‫where the only thing that changes
‫is this icon name,
‫then the date and the next date.
‫Okay,
‫so here what changes is not the next date,
‫what changes is the description of the boxes.
‫So next date, difficulty,
‫participants and rating.
‫All right.
‫And so basically,
‫this code here is always the same
‫only with three pieces that change.
‫So the name of the icon,
‫the description and the value of that description.
‫And so,
‫since we don't like repeated code, right?
‫Let's use another feature of Pug
‫that we haven't used yet
‫which is called mixins.
‫So mixins are basically reusable pieces of code
‫that we can pass arguments into.
‫So a bit like a function.
‫And also it's exactly like mixins in SAS.
‫So that's a CSS pre processor
‫that you might be familiar with.
‫So let's copy this code here for this overview box.
‫So copying it.
‫And now out here, out of this block,
‫let's then create a new mixin.
‫So we write mixin and then the name of the mixin,
‫which I'm calling overview box.
‫And then a bit like a function,
‫we can specify some arguments.
‫And so remember how we have the description of the box,
‫then we have the value of that description
‫and let's just call it text here.
‫And then also, the icon name.
‫Okay.
‫So now, let's copy that text in here
‫and of course
‫this now messes up our formatting.
‫Let's just quickly fix that.
‫And so now,
‫these variables here,
‫they really work like all the other variables in Pug.
‫So,
‫here this should now be the text.
‫Right?
‫And this here should be the description.
‫So equal description.
‫Well here it's actually called label in the CSS.
‫So let's call it label here as well.
‫Okay so label, text and icon.
‫And so here we also need to change the name of that icon
‫and all of these icon names
‫always start with icon dash.
‫And so all we really need to replace
‫is this part.
‫So let's create again a template string.
‫And then get rid of this.
‫And icon.
‫Okay and now we can use this.
‫I also wanted to say that
‫we could also have exported this mixin into another file
‫and then included that file here.
‫But I think this doesn't make much sense.
‫In this case because it is
‫not really a lot of code.
‫Anyway,
‫let's now actually go ahead and use this mixin.
‫So let me copy just the name of it.
‫And so here instead of this overview box.
‫And for now let me actually just duplicate it here.
‫Okay, so we used this mixin
‫by writing plus
‫and then just like a regular function,
‫we passed empty arguments into it.
‫And so our first overview box is next date.
‫Then for now, just the date that is here.
‫So just that I can show you that it works in fact.
‫So August 20,
‫21.
‫And then here,
‫calendar.
‫Okay because that's the name here of the icon.
‫And so now we should get
‫two boxes.
‫So this one and this one
‫which should look exactly the same.
‫So let's quickly confirm that.
‫And so then we can move on
‫to actually use the mixin properly.
‫And yeah,
‫so here are our two exactly same boxes.
‫Great.
‫So let's get rid of this first one.
‫And of course then here
‫we want the real date.
‫Okay.
‫And so that is,
‫add tour
‫.start,
‫dates,
‫zero.
‫So let's take a look at that.
‫And remember,
‫that this is going to look a bit weird.
‫Such as it did before.
‫Okay.
‫So let's ahead and fix that.
‫So let's actually take that from here.
‫And so what we need
‫is basically this instead.
‫Now I don't want to make this line here
‫all too long
‫by simply pasting that here.
‫And so why not just create a new
‫java script variable for that.
‫So remember we need to use this syntax here
‫in order to create java script code
‫that's not going to produce any output.
‫And then
‫again we can simply write java script here.
‫Okay.
‫And so now in here I'm going to simply use
‫that date.
‫Great.
‫And now let's just duplicate this here a couple of times
‫for all the boxes that we have.
‫So the first one is for difficulty.
‫And the icon is trending up.
‫Then the next one is for participants.
‫With the icon of user.
‫And the last one is rating.
‫And the icon is a star.
‫So here we have the date but,
‫here in the difficulty we actually have tour
‫.difficulty.
‫Then here for the participants
‫we want this string.
‫Like 10 people.
‫So a template string
‫saying tour
‫.mix,
‫group size,
‫and then
‫people.
‫And finally we want the rating
‫and then out of five.
‫So tour,
‫and I can never remember
‫what I called this field.
‫And it is ratings average.
‫All right.
‫And then,
‫out of
‫five.
‫Okay.
‫And that should be it.
‫Now we can get rid of all this code.
‫And this way it looks a lot nicer.
‫And just to make sure that works,
‫let's give it a save here,
‫reload,
‫and indeed,
‫we get easy, 25 people, and the rating
‫five out of five.
‫Awesome.
‫So we already covered a lot of ground,
‫but let's split this video into two
‫and continue with the rest of the page
‫right in the next one.