Setting Up HTML Template Files
What's going on guys? In this video, we're going to start working with HTML and templates using the Gin HTTP framework.
And if you want to learn data science with Python, check out Derek Ham. There is a link in the description below this video and you can also download the Golang cheat sheet. There is a link in the description below as well. Remember to subscribe to the channel and let's get started.
Let's get started by adding a new folder where we're going to store all the HTML templates. So we're going to call it templates. And here I'm going to create a couple of HTML files. Let's get started by the header.html. I'm also going to create a footer.html and finally an index.html that is going to group both the header and the footer.
The header is going to be pretty simple. Let's add the doctype. Let's be HTML tag. Let's add the head tag. Let's have a title and let's have a reference to bootstrap. And this is the URL to import the latest version of the bootstrap CSS framework. And finally, we are going to add the opening tag of the body, a body like this. Let's assign a class container.
And the footer is going to have just two elements: it's going to close the body of the document and it's going to close the HTML tag, like that. And that's pretty much it for the footer.
And then we have the index that is going to include the header. And in order to include the header, we can use template and the name of the file, in this case, header.html, and the same for the footer at the end. So instead of header, it's gonna be footer, like that. And in a couple of minutes, we are going to add dynamic content here to render the videos that are part of our API.
Serving Static Files and Templates in Gin
And now I'm going to create a new folder. I'm going to call it css where I'm going to store the CSS files for the application. So I'm going to create a new file, index.css. Okay.
Let's go to the server. And Gin provides two functions to load the static assets that we just created here within the templates folder. So the first function is going to be server.Static. The Static will allow us to serve the static files such as CSS files. So the first parameter is going to be the relative path. This is going to be the UI that we are going to use to serve the CSS file, so this is gonna be /css. And the second parameter is going to be the root directory, that in this case is ./templates/css.
The second function is the function that will allow us to load the HTML template. And this function is LoadHTMLGlob. And here we need to put the path to the templates. In this case, templates/ and here we can use wildcard *.html. A feature that Gin provides.
Organizing Endpoints with Route Groups
That will allow us to organize our API endpoints is the ability to group a set of endpoints. So we're going to create two groups. The first group is going to include the existing endpoints, these two: its GET and POST. It's gonna be an API group. And then we're going to create a view group that is going to clip a method to render HTML contents.
So the first group is going to be apiRoutes. So server.Group("/api"). And in order to add these two endpoints, this GET endpoint and the POST endpoint within this API group, we need to use curly braces like this, and we need to replace server here by apiRoutes. So this is going to be apiRoutes.GET and apiRoutes.POST.
And the second group is going to be viewRoutes, and here we are going to define a server.Group. And the name is gonna be /view. And again, here we have curly braces, and we create our endpoint that is gonna be viewRoutes.GET and we're gonna use /videos. And we need to create a function, so it's gonna be nil for now, and we're going to create a new function within the video controller to show all the existing videos. And that function is going to use the templates that we created here, this index.html file. Okay, so this is gonna be videoController.ShowAll.
Creating the View Controller Method
Okay, let's add this function to the video controller. Here to the interface we need to add that function that is going to receive the context like this. And let's implement this function here.
It's going to be a pointer to the controller struct, and the function ShowAll. And we're going to receive the context like this. Okay.
First, we're going to get all the existing videos, and we're going to store that in a local variable. So we use that service: FindAll. And we're going to create a map where we are going to store all the variables that we are going to use within the templates. So this is going to be data, and we're going to use gin.H, that is basically a map. And we're going to use two variables: title, and let's call it 'Video Page', and videos, where we are going to assign the list of videos that we get here from the service.
And this is the map that we are going to pass to the template. So in order to pass this data to the template, we need to use ctx.HTML. And here we pass the status code, that is http.StatusOK, status okay like this. Then we need to pass the file name of the template that is going to be index.html. And the third parameter is going to be the map where we assign the variables that we are going to pass to the template. So this is data.
Rendering Dynamic Data in Templates
Okay, now let's move on to the template. Go to the header. Here we have the title, and the idea is to use this title here that we are passing here as part of that template so we can render that variable like this, {{ .title }} and the name of the variable. And doing that, we are going to render in this case this value 'Video Page' as the title of our page.
Okay, now if we go to the index file. Here I already added this boilerplate, and what we are going to do here, we are going to render each video. As we can see here, we have the source of the video. This is the code, actually an iframe that YouTube provides if you want to embed a video within a web page. So this is the URL of the video, and this is the title of the video, and here is the description of the video. So we are going to replace these three values by attributes of the video struct. This one: we have the title, we have the description, and we have the URL, and we are going to ignore the rest. Okay.
Let's go back to the index. So here the URL, this is gonna be {{ .URL }}. And what else? This one is gonna be {{ .Title }} and the last one is gonna be {{ .Description }}.
And I forgot here to loop over the list of videos. And to do that, we need to use the range keyword. So this is going to be range, and here we need to use period and the name of the variable that in this case is this one that is named videos. We need to use {{ .videos }}. And we need to close this loop here. This is the end keyword. Okay, and that's pretty much all we need.
Demonstration and Final Result
So let's try this. go run server.go. And here as we can see, we have the two endpoints of the API. These are the endpoints that we already created, and this is the new endpoint that is going to render this HTML template. And here as we can see, this is the function that is going to run. This is actually the handler for this GET endpoint here. Okay.
So let's create a couple of videos using the API. I already created a couple of payloads to create new videos, so I'm going to create those videos. Yeah okay. I'm exceeding the max length, so I'm going to make it 200 let's say here, and 200 here. Okay, I'm going to start this and let's run this now. Okay, now we can create the videos here. This is unauthorized. I need to add actually the authorization. It's gonna be Basic Auth. I'm going to create it now. Yes, now I can. Because we need to pass this basic authentication.
So the same here. Authorization, Basic Auth, we send this. And now we are able to create this video as well. So now if we go to this URL localhost:8080/view/videos, we're going to see the videos that we created. Here is the video, the first video, the second video, and the third video showing the iframe with the video, the title, and the description.
Conclusion
That's all I have for today. Thank you guys for watching. Remember to subscribe to the channel and I'll see you in the next one. Take care. Bye.