Check out a free preview of the full Organizing JavaScript Functionality course:
The "Building Templates" Lesson is part of the full, Organizing JavaScript Functionality course featured in this preview video. Here's what you'd learn in this lesson:

Kyle continues his walkthrough of the application code. He describes how the templates are built and how they get injected into the application. He also has code watching the templates directory to reload the templates when they are changed. The templates are created with Grips.

Get Unlimited Access Now

Transcript from the "Building Templates" Lesson

[00:00:00]
>> [MUSIC]

[00:00:03]
>> Kyle Simpson: So, where does Tmpls.js come from, you notice it's in the web/js directory, where does that thing come from? Well, I actually have another utility here, called build templates, it's a script that is in the main root of your file. And if you look at build templates, let me to zoom out, it's a little easier to see more at a time.

[00:00:21] What build templates does, I can scroll down here, essential what it does is you spin it up, you run this program and it will process through all the templates that are in the templates directory. These are grips templates. If you were using a different templating engine, if you didn't like grips then you'd just be using a gulp or a grunt process for whatever engine you want.

[00:00:44] Again, not to overload people, we're not using grunt and gulp here. I'm not saying that those aren't good tools, but that's yet more machinery that I have to teach you. So, I'm showing you how to do it without even invoking any other tool. This is just a simple script that I wrote to go through the files in templates directory and run them through the grips templating engine and compile them.

[00:01:05] So, that's what it does it. It loops through all the templates in that file, processes each one of them. This is the command in the grips templating engine to compile one of those files and it compiles it from the HTML template into runnable JavaScript that can then be rendered either in Node or in the server.

[00:01:22] So, essentially this build templates JavaScript file produces the Tmpls.js file. It starts with, is it similar to the ejs template engine? Similar in that they are both template engines, yes. Similar in style or syntax, definitely not. Okay, so there is a base wrapper that I have and right off the bat this is going to illustrate how I share code between Node and the browser.

[00:01:58] I use the UMD style of module wrapper. Now I will fully admit and agree to you that those five lines of code being boilerplate on the top of each of my files is not at all ideal. I don't like that crap up there, but the other take away is that I don't even have to worry about it.

[00:02:19] I can literally just hide it, which is what I often do. I don't have these hidden, because I want to teach, but I just hide those things and not worry about those sorts of details. Which is usually what I do when I'm really trying to think about, so I can use like code folding in Sublime.

[00:02:33] And then I don't have to worry about that UMD header. But this is essentially replacing my need for browserify. Because this file as it is, can be run in any of those environments. It can run in Node, it can run in the browser, it can run inside of require in the browser and it doesn't need to be transformed.

[00:02:55] So, my choice instead of using browserify is to use the UMD wrapper. Some people like that, some people don't, I'm not passing judgment that browserify is bad. I actually think it's a great tool but my choice here was I don't wanna invoke some other tool that I have to teach you.

[00:03:11] So, another way of doing it plain barebones is to put in the UMD wrapper. And I don't write this every time I just duplicate my file. [LAUGH] I duplicated another module and I don't even think about the boilerplate stuff. The contents of my module is what starts here and you'll notice that my module is in strict mode.

[00:03:30] And I have this init function and I have a little placeholder here, a comments placeholder. That's where the compiled templates get put into. So, this is a wrapper and I compile all the templates with grips and I stuff all of that executable code right in here. And that is the Tmpls.js file that can work identically in both the browser and the server.

[00:03:59]
>> Kyle Simpson: Okay.
>> Kyle Simpson: The other thing that build templates does, in addition to building the initial template bundle, is it sets up a watch. And this watch is duplicating the same sort of feature that you've probably used in something like grunt or gulp. I'm setting up a watch to listen for templates being changed in my templates directory.

[00:04:22] Every time I save a file, this watch will automatically kick in, it'll see that file had been created or changed. It'll kick in and re-invoke my build template scripts or it'll rebuild my template bundle every time I make a change. I don't have to go back to the command line and do it, it just automatically watches it.

[00:04:40] So, essentially when I start this up, I start up build templates and then I don't think about it anymore and it automatically builds. Now another thing on that topic is,
>> Kyle Simpson: I said, I had watch going on in my Node server process, so I'm back in server.js. And I said I had Node going on in my server watch process.

[00:05:03] Where's that going? Here, I have another watch.createMonitor. And I'm watching for the Tmpls.js file to change. This is an interesting trick I haven't really seen a lot of other frameworks doing. I'm not saying that nobody else is doing it but essentially what I want is to not have to restart my server if my templates have changed.

[00:05:27] So, I'm hot reloading my templates bundle into my server instance every time it changes. In other words, when I change a template file, one watch process rebuilds the template bundle and another watch process re-hot loads it directly into my server instance without restarting. So, I can just do a refresh of my page immediately after changing my template and bam the new view is available.

[00:05:52] So, let me illustrate that process just to kind of point that out and that will segue us into talking about these grips templates. So, I just have a basic one, this index, here's my content, my basic content. So, if I wanted to make a change, I don't have that build template process running yet.

[00:06:15] So, before I even save the file, let me start up that build templates watch that's gonna go on. So, now that's in the background, the build templates watcher is in the background. Actually we run it, you have to run it with the watch thing to make it do that.

[00:06:31] So, now it's watching for that change to the template. So, when I save this file,
>> Kyle Simpson: They can come back to the command line and you'll see that it is now rebuilt my template bundle. My server was automatically redoing or watching for those things. So, if I look at my server log file,

[00:07:03]
>> Kyle Simpson: You notice that it reloaded my templates. So, my server has reloaded the templates into its process. Which means without even restarting the server, if I come back over here, now it's updated and it can serve it up from an initial page. And we can also hot load that JavaScript into the browser if we want.

[00:07:21] I don't have that process set up but it's easy to do the same thing in your browser and hot load your new templates.
>> Kyle Simpson: A couple of quick things about grips, just if you were at all interested in learning how grips works. I have,
>> Kyle Simpson: A little online playground for the template engine.

[00:07:46] So, these four boxes, this is the template that you write and then this shows you what it gets compiled into. And by default that's the code that's compiled with all of the debug stuff in it, so that it gives you nice friendly error messages. And that's what you'd use in dev, but if you wanted to switch it to being smaller and being production without debug stuff, switching the mode, this shows you how much shorter the code is when I don't have all the debug stuff in.

[00:08:14] So, you can kind of get a sense and if you wanted to look at the code that I was producing, it's pretty highly compressed stuff but if you at all cared about it. Most of the stuff in there is things like this which are producing information that an error message can use.

[00:08:28] That's a distinction point between grips and other templating engines is that there's actually quite a few features in here that are built for much better error messaging than you've seen with other template engines. It's much, much richer, stack trace based, sorts of error messaging from your templates, not only from, if you have an error compiling your template but much more so if you have a runtime error with your template.

[00:08:53] There aren't a lot of template engines that do runtime error checking in any graceful way. But that's been built into grips from the beginning. All right, so you can change something about your template. You can change something about the data that's being put in. So, if I change this to world too and I come out on focus from that, it doesn't need to be recompiled but it will re-render and shows you now that it says world too.

[00:09:18] If I change my template up here, I'd like to add in an extra couple of exclamation marks, it will actually recompile the template first. And then it will rerender it and show you the info down there. So, there's a little playground if you wanted it all to learn about the syntax.

[00:09:36] There's a bunch of documentation and then a bunch of different preset examples that show you doing different things with the template engine and how to produce this stuff. So, if you wanna learn grips, that might help a little bit. But we're not really doing a lot of complicated stuff with grips here.

[00:09:55] All I'm doing is I'm defining, the define tag is how you define a partial. To include a partial from another location, you just say partial and give it the ID of the partial. So, I have this stuff template down here. And of course, all I need to do then is add more stuff into any part of my template, click Save, let those watches run for a moment.

[00:10:20] And now if I do a refresh, we see the exclamation show up.
>> Kyle Simpson: Grips is definitely a partials based templating engine. So, we define things in terms of template partials. Also you notice that files can extend other files. So, I have a master template that I've set up for the page which has like my doctype stuff in it.

[00:10:46] And then I'm calling out to a partial content which allows me to do essentially a basic but powerful form of template inheritance. So, the index template inherits the master and it overwrites certain partials. So, I can have lots of different pages that inherit from master. I can have something that inherited from index and override partials.

[00:11:12] So, it supports those sorts of features. Just gonna see if I had any examples of, yeah, so here's how you drop in a value, instead of dropping in a partial. You're just gonna insert it. By the way, grips does have a shorthand form of all of the,
>> Kyle Simpson: Syntax, so the long form is like it uses words like define.

[00:11:38] But there's a shorthand form of all the syntax if you prefer to write less code. And the short form, uses a single operator in place of these different words. So, if you have a really long complex template and you find yourself writing a bunch of words, you might like the short form that you can use, either form is valid.

[00:11:58] Okay,
>> Kyle Simpson: Main takeaway here is, it really would not matter at all what template engine you like to use. I don't care if you wanna use mustache or you wanna use dust or whatever. Whatever template engine suits you, the same concept that I'm presenting here can be done very easily with any of those templating engines.

[00:12:22] You just simply have a template that you change a file, you have a watch that rebuilds it. You load that into some file that you can use in both places. And then in my server, if I wanna use the template engine, it's exactly the same as if I'm using it in the browser.

[00:12:37] So, let's look at this loadPage route. You'll notice that I'm calling out to my view sort of like a controller, if you like. I'm calling out to my view and I'm calling this function called getPageHTML. That just simply invokes grips and it loads the appropriate section of HTML and then it sends it back out.

[00:12:58] So, this View.getPageHTML wouldn't have to change at all if you wanted to swap out a different templating engine. You just go into that getPageHTML and specify a different templating engine.