3.3 Creating Templates
Now that we have learned how to separate server and client code, it's time to make that client code, or markup, a little more flexible and easy to change. To do that, we'll make use of Go templates. These templates will allow us to separate the data from the markup and make it much easier to update our content as we start to make our web application more dynamic.
1.Introduction3 lessons, 12:09
2.the Basics8 lessons, 1:15:15
3.Building Web Servers in Go4 lessons, 43:38
4.Conclusion1 lesson, 01:32
3.3 Creating Templates
All right so we're really starting to make some pretty good headway here. But it's time to really up our game a little bit more. So we learned a pretty decent way of serving up HTML to the browser so that it can be presented to the end user. But the problem that we're going to run into now is that our page is always very static. So if I want to make changes to this page for any reason, if I want to change the title, if I want to change the header, or if I want to change any of those pieces of information, then I have to go in and manually change things. So wouldn't it be nice if we could take this HTML that we have stored off in another file and maybe make it a little bit more generic? Maybe we could make it so that the title could be driven from some information that comes from a database, or maybe some information that comes from a web service, and the same goes with the header. And heaven forbid when we actually get to the point where we want to start presenting some blog posts that have multiple pieces of information in them to the end user. Wouldn't it be nice if we could just kind of have a way to genericize our HTML file here? So that we could then change what it looks like just by sending in some different data. Well, it just so happens that Go supports that very thing, using what are known as Go templates. So let's go ahead and take a look and see what that looks like. So if I were to modify my HTML file just a little bit, I would start to no longer have a just a raw HTML file, I now have a Go template. So what does that look like? So we're going to take a look at my new version of blog.html. I now have a couple of little goofy looking things in here. I have these double curly brackets. And then I have some text in there. And the text in there is going to consist of a dot and then something after it. So I have .Title, .Header, and .Author. And I can have dot whatever I want in there. It doesn't really make much of a difference. So the first thing to notice here is those curly brackets. The curly brackets are what it's going to denote to Go when you're using its template functionality within its standard template library, that I want to use templates. And I want to inject a piece of data into this spot in my file. Now what I'm gonna put in there? Well, that's where we stick some text in there to say what you actually want to inject into that spot of the template. Now the dot is your context, that's going to be what is going to be ultimately your root object, or struct, is what you're going to see in a little while. And the property or the field that's hanging off of that is what I ultimately want to stick in these different places. So this might be just a lot of words so far. So let's go ahead and see what it is we're talking about and how we can do that within Go. So I have a new Go server here. And it's a little bit different, couple more modifications, but nothing too crazy. So I have imported a new package again, which is gonna be the HTML template package. And in there is where I'm gonna get some cool functionality that's going to allow me to transform some strings, in our case HTML, into a template using some of these curly brackets and things that I showed you a few moments ago. So I have that new package in here. I've created a new type, so now we're starting to get into the world of creating some of these things in code. So I have a new type called Blog, so I wanna be able to use that throughout my application. And I am now still dealing with the same type of main. I still have my load file cuz I'm still gonna go and read my text file, myblog.html file from disk. But now my handler has changed a little bit again. So now, I am going to say I want to create a new blog. So that blog is going to have a title, it's gonna have an author, and it's gonna have a header, so those those pieces of information that I wanted to extract out of here that would be ultimately more dynamic. Then I want to allow those values to change based on wherever I am within my application. So I have this new blog variable here. And then I have this template stuff going on down here. So what exactly is that doing? So within my template package, I have what's known as a ParseFiles function. And what's going to happen here is it's going to run off. And it's going to try to grab the file that I'm specifying. And it's gonna try to convert it into a template. And if it succeeds, I'm going to get a template. And if it errors, well I'm gonna get an error, so very similar to what we're doing up here with the reading file. And I can already tell that this is not going to work well because I don't have this specified, right. So I have to make sure this is Site3/blog.html. And then once I have that template, I want to execute that template, so what is that gonna do? So when I successfully get a template, I get this string that's templatized from a file into Go, into a way that it knows where these curly brackets are and where it needs to inject some pieces of data. And then I am going to execute that template to a response writer again, with a context. And this context is going to be blog. And it just so happens that the context object or struct or variable that I'm passing in to be executed against that template, just so happens to have the properties that are specified within the curly brackets within my template. So I see title, header, and author. And I'm gonna see the same exact things in my blog, I have title, author, and header. So if I were to save this, I can then go back to my server, so let's go ahead and stop it, if anything is running. And this time I want to run Site3/templates.go. And once it's done, then I can come back to my browser and I can once again refresh. And now you can see it changed a little bit. So now I have Welcome to my amazing blog by Derek Jensen. So we can come in and take a look at the source again. And as you can see here, the source is pretty much the same, nothing's really changed. But the content within it has changed. And the reason for that is because I have specified this brand new template file. Which has these little markers in there to say I want to inject some data in there from a context that I'm going to pass into the execute function that's found within the template package, which is all done over here. Now one thing to note is that, in a lot of situations, so far, when we've been talking about variables and things like that. I have been using some lowercase or camel case casings for my variable names. So in a lot of situations I use lowercase here like this lowercase b and lowercase e, and so on and so forth. But I also use camel case here like this. Now one thing I did do here is I made sure that the properties or the fields on my blog struct here were uppercase. And the reason for that is the uppercase properties are what's known as exported in the world of Go. So when you start to make things uppercase, then they are made accessible to other things. So if I were to change this down to lowercase t, and save this, and then change this to be a lowercase t like this and save that. Now it doesn't really look like much has changed here, just the capitalization of the t in titles. So if I were to save that and come back over here, let's go ahead and quit my server. And let's re-run my server, and come back to my browser and refresh my browser, all of a sudden things are not going to work. And it's gonna become very difficult for you to troubleshoot this, because in my particular code here, I'm not doing anything with any sort of errors. But one of the problems here is that when the template is trying to go and grab the title property, it's seeing here that this is lowercase, this is lowercase and it's uppercase over here, and so case does matter. So it's definitely something to pay very close attention to. So if you're going through and following along with these samples and you're typing these things out and all of a sudden you see blank screens, definitely double check the properties and the fields within your types to make sure that they are all common and consistent across the board. So if I were to fix that little problem, and then let's go ahead and restart my server. We're gonna go ahead and refresh and now everything is working again. So, once again, what did we do here? What we did is we were able to now make our HTML into a template by making it a little bit more generic and being able to inject some data into it based on some code that I'm generating on my server now. Not necessarily always the best thing in the world. And I'm going to show you, in an upcoming lesson, how we can maybe genericize the retrieval of these types of things like blogs and posts and things like that. And then have our page grow dynamically over time based on the content that we are creating for our end users.