Quantcast
Viewing latest article 9
Browse Latest Browse All 10

Views – Node.js Tutorial for Beginners

In this tutorial we’ll be talking about views. By the end of this tutorial, you’ll be able to separate code logic and design easily. I’ll also be introducing a template engine called Handlebars.

Handlebars

We need to install handlebars before we can use it. What is handlebars? Well, it’s a template engine. Handlebars is beyond the scope of this tutorial series. Luckily, I’ve already covered it in another series I wrote. You can find it here.

Handlebars Tutorial Series

Handlebars is usually done on the client side, but we’ll be rendering the templates on the server. Let’s install handlebars with the following command.

npm install handlebars --save

This will install handlebars for us and allow us to compile and process handlebars templates. Let’s update our server variable with the following code.

var server = new Hapi.Server('localhost', 8080, {
    views: {
        engines: { html: require('handlebars') },
        path: "./views",
        isCached: false
    }
});

The third parameter is completely optional. This is where Hapi starts to shine. Hapi is a configuration based framework. We just have to change the default settings by passing in an object and Hapi will take care of the rest. Right now, we only want to change how the views work. The views object has a couple of properties we can set. The engine property will tell Hapi what kind of extension the application should look for when finding templates. We’ll be using HTML, but we want handlebars to process and compile these HTML files.

The path property is where Hapi can find these templates. You’ll notice that we have ./ prefixed to the folder name. This just tells Node that we want it to search for this folder in the root directory of the application. Create a folder named views in the root directory of the application. We’ll be creating our templates here soon.

The isCached property will cache our templates if set to true. This value is set to true by default, but we change it to false since we’re in the development phase of this project. You should set this to true when you’re working on a production server. That’s it! We can now start working with views. Before we do, let’s add the required files for our templates to display properly.

Public Directory

We need to be able to serve images, CSS, and JS files without having to define a route for each file. Hapi has you covered with dynamic routes. We’ll be using bootstrap to style our blog application. Create a folder called public and put the bootstrap files in this folder. You can download bootstrap by clicking here.

We now need to create a route that will handle serving these files to our visitors whenever they’re requested. Let’s add this new route below our home page route.

server.route({
    path: "/public/{path*}",
    method: "GET",
    handler: {
        directory: {
            path: "./public",
            listing: false,
            index: false
        }
    }
});

Let’s take a look at the path property. You’ll notice that there’s curly brackets surrounding the word path. This tells Hapi that this part of the route string will be dynamic. We also insert an asterisk to tell Hapi that this path can have multiple nested folders. So, for example, if a user wanted to access the bootstrap.min.css file, then they would have to type http://localhost:8080/public/css/bootstrap.min.css. Our handler is where the magic happens.

The handler property can either be a function or an object. If it’s an object, then we can quickly define some properties that Hapi will use to create this dynamic route. We want this route to be a directory because that’s what it is. We set the path property to tell where Hapi can find our files. It’ll automatically append the dynamic part of our route to our path.

The listing property will tell Hapi to not list our files and the index property will tell Hapi that there is no index.html file.

We now have a dynamic route for serving static files. We can now focus on our home page. Update your home page route to the following bit of code.

server.route({
    method: 'GET',
    path: '/',
    handler: function (request, reply) {
        reply.view('index');
    }
});

We only updated our handler function. Instead of directly replying a simple message, we reply a view. A view is just a HTML file. We just pass in the name of the HTML file that it should display. We omit the .html file extension because we told Hapi earlier that this will be the default extension. Hapi will automatically append the .html file extension for you.

It’ll also look for the index.html file in the views  folder. Let’s create the index.html file in the views folder now. Insert the following code below.

Index Template Source Code

Index Template Source Code

<!DOCTYPE html>
<html lang="en">

<head>

    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <meta name="description" content="">
    <meta name="author" content="">

    <title>Blog Home</title>

    <!-- Bootstrap Core CSS -->
    <link href="/public/css/bootstrap.min.css" rel="stylesheet">

    <!-- Custom CSS -->
    <style type="text/css">
        body {
            padding-top: 70px; /* Required padding for .navbar-fixed-top. Remove if using .navbar-static-top. Change if height of navigation changes. */
        }

        footer {
            margin: 50px 0;
        }
    </style>
    <!-- HTML5 Shim and Respond.js IE8 support of HTML5 elements and media queries -->
    <!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
    <!--[if lt IE 9]>
    <script src="https://oss.maxcdn.com/libs/html5shiv/3.7.0/html5shiv.js"></script>
    <script src="https://oss.maxcdn.com/libs/respond.js/1.4.2/respond.min.js"></script>
    <![endif]-->

</head>

<body>

<!-- Navigation -->
<nav class="navbar navbar-inverse navbar-fixed-top" role="navigation">
    <div class="container">
        <!-- Brand and toggle get grouped for better mobile display -->
        <div class="navbar-header">
            <button type="button" class="navbar-toggle" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1">
                <span class="sr-only">Toggle navigation</span>
                <span class="icon-bar"></span>
                <span class="icon-bar"></span>
                <span class="icon-bar"></span>
            </button>
            <a class="navbar-brand" href="#">My Blog</a>
        </div>
        <!-- Collect the nav links, forms, and other content for toggling -->
        <div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
            <ul class="nav navbar-nav">
                <li>
                    <a href="#">About</a>
                </li>
                <li>
                    <a href="#">Services</a>
                </li>
                <li>
                    <a href="#">Contact</a>
                </li>
            </ul>
        </div>
        <!-- /.navbar-collapse -->
    </div>
    <!-- /.container -->
</nav>

<!-- Page Content -->
<div class="container">

    <div class="row">

        <!-- Blog Entries Column -->
        <div class="col-md-8">

            <h1 class="page-header">
                Page Heading
                <small>Secondary Text</small>
            </h1>

            <!-- First Blog Post -->
            <h2>
                <a href="#">Blog Post Title</a>
            </h2>
            <p class="lead">
                by <a href="#">Jack</a>
            </p>
            <p><span class="glyphicon glyphicon-time"></span> Posted on August 28, 2013 at 10:00 PM</p>
            <hr>
            <img class="img-responsive" src="http://placehold.it/900x300" alt="">
            <hr>
            <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Dolore, veritatis, tempora, necessitatibus inventore nisi quam quia repellat ut tempore laborum possimus eum dicta id animi corrupti debitis ipsum officiis rerum.</p>
            <a class="btn btn-primary" href="#">Read More <span class="glyphicon glyphicon-chevron-right"></span></a>

            <hr>

            <!-- Pager -->
            <ul class="pager">
                <li class="previous">
                    <a href="#">&larr; Older</a>
                </li>
                <li class="next">
                    <a href="#">Newer &rarr;</a>
                </li>
            </ul>

        </div>

        <!-- Blog Sidebar Widgets Column -->
        <div class="col-md-4">

            <!-- Blog Search Well -->
            <div class="well">
                <h4>Blog Search</h4>
                <div class="input-group">
                    <input type="text" class="form-control">
                        <span class="input-group-btn">
                            <button class="btn btn-default" type="button">
                                <span class="glyphicon glyphicon-search"></span>
                            </button>
                        </span>
                </div>
                <!-- /.input-group -->
            </div>

            <!-- Blog Categories Well -->
            <div class="well">
                <h4>Blog Categories</h4>
                <div class="row">
                    <div class="col-lg-6">
                        <ul class="list-unstyled">
                            <li><a href="#">Category Name</a>
                            </li>
                            <li><a href="#">Category Name</a>
                            </li>
                            <li><a href="#">Category Name</a>
                            </li>
                            <li><a href="#">Category Name</a>
                            </li>
                        </ul>
                    </div>
                    <!-- /.col-lg-6 -->
                    <div class="col-lg-6">
                        <ul class="list-unstyled">
                            <li><a href="#">Category Name</a>
                            </li>
                            <li><a href="#">Category Name</a>
                            </li>
                            <li><a href="#">Category Name</a>
                            </li>
                            <li><a href="#">Category Name</a>
                            </li>
                        </ul>
                    </div>
                    <!-- /.col-lg-6 -->
                </div>
                <!-- /.row -->
            </div>

            <!-- Side Widget Well -->
            <div class="well">
                <h4>Side Widget Well</h4>
                <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Inventore, perspiciatis adipisci accusamus laudantium odit aliquam repellat tempore quos aspernatur vero.</p>
            </div>

        </div>

    </div>
    <!-- /.row -->

    <hr>

    <!-- Footer -->
    <footer>
        <div class="row">
            <div class="col-lg-12">
                <p>Copyright &copy; Your Website 2014</p>
            </div>
            <!-- /.col-lg-12 -->
        </div>
        <!-- /.row -->
    </footer>

</div>
<!-- /.container -->

<!-- jQuery Version 1.11.1 -->
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>

<!-- Bootstrap Core JavaScript -->
<script src="/public/js/bootstrap.min.js"></script>

</body>

</html>

Right now, our template is very static. We aren’t doing anything special so I won’t go over what’s in this file. Feel free to look it over. Start your server and try going to the homepage. You should see something similar to the image below.

Conclusion

We have now learned how to create templates. Feel free to mess around with this code and make any changes you’d like. Our templates are static. With handlebars installed, we can actually make them dynamic. In the next tutorial we’ll learn a little about databases that will store our blog posts.


Viewing latest article 9
Browse Latest Browse All 10

Trending Articles