Instructor: To get the express-handlebars package working correctly in your Express app, the first thing we need to do is configure the handlebars object.
We use the handlebars create method. There are a couple of default options you can pass to it, one of them being the default layout. This is the name of the default layout that will be used for all handlebar template across the whole site. You can override this, though.
We also can define the extension name for the files. We're going to use the extension name handlebars. Then you need to configure Express itself. Express engine needs to be told to use handlebars, and there's an engine property on the handlebars package. We also need to set the view engine for Express. That's handlebars as well.
Next thing we're going to do is create our default layout. To do that, we need a folder called views, which is a standard for Express. Within the views folder, we need another folder called layouts, which is where we store our handlebars layout. Then within the layouts, we can define our defaults.handlebars layout.
I have some HTML in my clipboard. It's just a basic HTML document. The only handlebars specifically in here are the three braces with a body. When the template is rendered, this section here is replaced. This now should have a standard layout across your site.
Now we're going to build an example handlebars template. We're going to call this invoice.handlebars. It's going to be a dynamically generated HTML invoice. I have some HTML in my clipboard, which is a basic layout, which is driven by CSS Grid. We've hardcoded for now some data so we can see it rendering.
Within our server.js file, we've defined a root called /invoice and then a pretend ID. We're calling it a controller, calling voice controller. If we look at the controller, it has a response.render method, and we're calling invoice, which is the name of the handlebars template. Let's fire up our server and test it.
I've started my server. It's running on port 811. If we bring a browser across and hit the URL, the handlebars layout is rendered along with the template. As you can see, we've got our test status from there.
Let's try to make this more dynamic now. To simulate a date space, I've created a dates.json file, which just has a JSON object in it with some customer information and a list of costs. Within my controller, for the root, I've included the dates.json file.
The first thing I can do is add a second property to the response.render method and pass it an object. What I'm going to pass is invoice_data. That will correspond to our data, which is coming from the JSON file. Then within the actual template, I can now go ahead and dynamically access that information.
I will add an example, which starts with two braces, then the object -- invoice_data -- then the property itself, which is invoice. I'm going to go ahead now and update these other fields. Now we need to use a block helper.
In handlebars, it's possible to iterate over data. In this case, we've got an array of costs. We use the each handlebars helper, and we pass it the array. Then within the block helper, we can then reference the values using this, which references the individual array item. Description in this case is the property. This one is this.cost. Then you need to end your block helper.
Let's see that running. I've got my server running, open my URL in the browser, and now we have data coming through from the dates.json file. You can see it's iterated over each of the objects. Now we need to add a bit more logic. We've got the dates not appearing, nor do we have a title.
There's a couple of ways you can provide more functionality to your handlebars. The first one is, you can simply within the controller, before passing it the data, I should do some manipulation. We're going to calculate the total cost, and also we'll put in a formatted date.
The first thing we do is the total cost. All we're going to do is set on our data objects an actual total inaudible cost property, which is what we've just calculated using the reduced the function. We'll say fix to only two decimal places.
By manipulating the data object before passing it through to handlebars, we can ensure that the actual data pass through is in the format we need. Let's do the date created now. For this, we're going to use the moment library to do date manipulation, and we're just going to format today's date.
Both of those two properties are now being set on our data object and passed through to handlebars. Let's see what that looks like. Bring up a browser, enter the URL, and we get the date formatted correctly with today's date. Also, the title is now coming through.
To add more logic to our handlebars templates, we can create reusable logic here, which we can then use across different handlebars templates. I created a helpers file. All I'm going to do is export a simple function. We'll call it gmap_link. What this is going to do is, when we pass the postcode, wrap it in a URL to send to Google Maps.
We'll now use this gmap link. Within our invoice templates, we'll go to the postcode and we'll add our gmap link tag, and then within the controller itself, within the object we pass to the render method, we can add a new property called helpers. This can reference the gmap_link method we just created.
We're passing this trough to our handlebars template. Let me just get that on the screen. We also need to reference our helpers file itself. This way, we've got reusable logic in a helpers file being passed through to our render method for our handlebars template.
We fire up a browser, put our URL in, and handlebars has scoped HTML. If we go back into our template, inaudible . We need three braces in this case. Go back to my browser, hit refresh, and we now have a link which should open Google Maps, which it does.