Welcome to part 2 of the Twitaron series
- Getting started
- Views & Controllers
- User Accounts
- Under development…
In our previous article we started with the basics and built a web application capable of serving static content, compressing that content, and implementing cache headers.
In this installment of the Twitatron series, we will be diving into Views and Controllers.
Getting setup
Our view engine of choice will be Jade. Jade is a terse language for writing HTML templates. It is capable of producing HTML, supports dynamic code, and supports reusability. You can find a tutorial here to learn more about Jade.
First thing we need to do is create a directory to store our views. If you don’t already have a directory named views
you will need to create one now.
We will now need to tell Express about the view engine we wish to use.
Open up server.js
and update it with the following code after the static middleware code.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
|
Next, we need to install the Jade npm package.
1
|
|
What we did was add two pieces of middleware to our Express application. First, we told it to set the directory for our views to /views
. Second, we told it to use Jade as our view engine.
We are now ready to create our first view.
Our first view
In the views
directory create a new file named home.jade
and add the following code to it.
1 2 3 4 5 6 7 |
|
Next, we need to create a route at the root of our application to render this view. Open up server.js
and update it with the following code. Be sure to remove the “dummy” route we made in the first tutorial that just returned the text “Twitatron”.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
|
Finally, because we now have a view, we do not need the index.html
file inside our public
directory. Go ahead and delete it.
What we have done is setup a new route to handle GET requests to /. When a browser requests http://localhost:3000/
it will execute the anonymous function we defined to render the view named home
. Because we already defined the directory for our views to be views
, Express will look for a view named home.jade
, render it into html, and return it back to the requesting client.
Go ahead and test out your code to make sure everything is working. You should get back a response with the text “A Twitatron view has been born!” along with the Twitatron bird image.
Layout and partials
The next thing to update in our application is to implement a layout view and some partial views. This will help us reduce a significant amount of view code through reuse.
The first thing we will create is our layout view. This will define the general layout of our application and will be used in most of our other views. Inside the views
directory, create a filed named layout.jade
. Update it with the following code.
1 2 3 4 5 6 7 8 9 |
|
You will notice that our layout contains references to 3 partial views. Let’s go ahead and create these now. First, create a sub-directory inside the views
directory named partials
. Next, create three new views named: head.jade
, navigation.jade
, and footer.jade
. Update each one as follows.
Head
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
|
This view contains all our information for the head section of our HTML. Right now there are references to many icons for our application that do not yet exist. Don’t worry about that for now as we will be making these in future tutorials.
Navigation
1 2 3 |
|
Pretty simple navigation piece for now. This will become more robust as we progress through the series.
Footer
1 2 3 4 5 |
|
The last thing we need to do is update our current view for the homepage to use the new layout view. Update home.jade
with the following.
1 2 3 4 5 |
|
Our view now says to extend our layout view and use the content defined within the content block within the block content section in the layout.
Now, all future views we create can extend the layout view and thus provide a head section, navigation, and footer. Later we will update our layout to add things like CSS, JavaScript, and more.
Adding some dynamic code
By themselves, views are helpful but they are much more powerful when you support dynamic code. This can be done easily taking advantage of Express. Let’s go ahead and add a new element to our view that shows the IP address of the person making the request to our page.
Open up server.js
and update our route handler as follows.
1 2 3 4 5 6 7 8 9 |
|
What this does is add the IP address of the client making the request to the res.locals.ip
object which makes it available to our views. The res.locals
object is where you can add anything you want available in views.
Next, update home.jade
as follows with a new element.
1 2 3 4 5 6 |
|
This example is more to illustrate how to add dynamic code to your view from within your application. In future articles, we will dive more deeply into how to take advantage of this.
Controllers
The next thing we need to help make our application easier to understand and maintain are controllers. As our application grows, our route handlers will increase in quantity and complexity. We will do this by pulling out most functionality and placing them within separate modules.
Let’s start by updating the current route handler for we have the the root of our application.
If you don’t already have a directory named controllers
you will need to create one now. Inside this folder, create a new file named home.js
and update it with the following code.
1 2 3 4 |
|
What we have done is put our route handler code into a separate home controller module. Now we just need to update server.js
to import the module and use it. Update server.js
with the following code.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
|
It may not seem like much now, but this type of pattern will help our application as we add a lot more functionality.
Using path to normalize paths
In two places, we have referenced the local file system using the __dirname
global and a directory. To make our code more robust, we will take advantage of the core Node module path
. The path
module provides the function join
that will join all the arguments into a normalized path.
For example, the following code would result in the path /Users/scott/Projects/twitatron/public
1
|
|
Update the two places within server.js
where we are using the dirname
global to use the path
module.
1 2 3 4 5 6 7 8 9 10 11 |
|
Wrap up
While our application may not yet be pretty, we have a solid base to build and grow from. We have views, layouts, partials, controllers, and more. Stay tuned for more articles on this tutorial series on building production ready Node web applications.
If you found this article or others useful be sure to subscribe to my RSS feed or follow me on Twitter. Also, if there are certain topics you would like me to write on, feel free to leave comments and let me know.
Source code for this part can be found here on GitHub.