Passing data from server to a handlebars view

In this tutorial, we’re going to set up a node server, create some express handlebars views, and pass data from the server to these templates. In a real-life scenario, this data would most likely be fetched from a database. But we’ll not get into that in this tutorial. This is just to show you how handlebars views can be set up quickly and accept data from a server.

Initial Set up

Start by creating a project folder. Name it whatever you like, I called mine pass-data-to-handlebars. Launch your command terminal and go to the folder you created. I use Visual Studio Code‘s inline command terminal (which can be launched using Ctrl + `) when working on a NodeJS project. I just think it’s convenient. You may use a terminal of your choice. In your command terminal type

npm init

 

 

image of npm init prompts

You will be presented with a series of prompts. For now, just accept the defaults (hit Enter key through all prompts). You can modify these values in a file called package.json that will be created once this command has run successfully.

Next, let’s install express and nodemon. You can do this by running the following commands in the terminal

npm install express --save

npm install nodemon --save-dev

express will be used to set up a server. nodemon will watch server files for any changes and will automatically restart the server whenever these are saved – so that we don’t have to do it. Since nodemon is required only for development and is not an essential component of our project we append dev to its command. This means that it will be installed as a dev dependency. Once the commands have run successfully, you should see a node_modules folder in your project folder. This is where all your installed packages and their dependencies are saved. Next, let’s set up our server.

 

Setting up a Server

Create a file called index.js (the filename should be the same as the value of main in package.json). In index.js, add the following code to it.

var express = require('express'),

    http=require('http'),

    app=express();

//set port
app.set('port', process.env.PORT || 3000);

app.get('/', function(req, res){

    res.send('you should see this, if everything is set up correctly');

});

//start server
http.createServer(app).listen(app.get('port'), function () {

    console.log('Great things are anchored at port '+app.get('port'));

});

 

This is a basic server setup.

  • Required express and http
  • Created an express instance called app.
  • Set ‘port’ value to 3000.
  • Defined what happens on a GET request to our root (‘/’).
  • Created a server at ‘port’

In your terminal, type nodemon and hit Enter. nodemon will now watch all server-side files and restart the server whenever you make any changes.

Launch localhost:3000 in a browser. You should see the text that we specified in res.send. Our server is now up and running.

Configure Handlebars

Let’s move on to the main task and install express-handlebars. Run the command

npm install express-handlebars --save

 

Once installed, require express-handlebars in your index.js file, like so

var express = require('express'),

    http=require('http'),

    exphbs = require('express-handlebars'),

    app=express();

 

Before we can use handlebars as templates we need to configure it. Include the following code in your index.js

//set view engine

app.engine('.hbs', exphbs({

    defaultLayout:'default', //specifying the file name of our default template

    layoutsDir:"views/layouts/", //specifying the directory where layouts are saved

    extname:'.hbs' //defining file extension. if not specified, the default is 'handlebars'

}));

app.set('view engine', '.hbs');

 

Update your folder structure to look like this

.
|
|--views
|  |--layouts
|  |  |--default.hbs
|  |--main
|  |  |--index.hbs

In our handlebars configuration, we have specified default.hbs as the defaultLayout (note that the extension is not required when mentioning the file name). A default layout, in this case, is the HTML structure inside which our views will be injected.

image explaining default layout

Add the following HTML to default.hbs

<!DOCTYPE html>

<html lang="en">

    <head>

        <title>Data to handlebars</title>

    </head>

    <body>

        {{{body}}}

    </body>

</html>

 

What we’ve done here is defined the structure of all our pages. Anything that needs to change on a page will go in {{{body}}}. To pass a view inside {{{body}}}, go back to your index.js file and replace res.send  with res.render(‘main/index’)

app.get('/', function(req, res){

    res.render('main/index');

});

 

Now, whenever you go to the path ‘/’, the contents of ‘main/index’ will be injected in {{{body}}} and should be visible on the screen. Test it out by adding some dummy text in ‘main/index’ and refreshing localhost:3000.

Next step is passing data to our view. And now that we have everything in place, doing that is as easy as

app.get('/', function(req, res){

    var data='Hello from server';

    res.render('main/index', {

        data

    });

});

 

To receive and display this data inside your view, use the same variable name you passed in res.render. In you ‘main/index.hbs’ include

{{data}}

 

If you refresh localhost:3000, you should see ‘Hello from server’. And that’s it. That’s how easy it is to pass data to a handlebars view.

Next Step

Instead of passing a string, try passing an object (e.g. data = {prop1: ‘objprop1’, prop2: ‘objprop2′}. In your view, you’ll need to access it using data.prop1 or data.prop2. You can also try passing an array and populate it using handlebars’ helpers like each.

Conclusion

In this tutorial, we learned how to configure express-handlebars for our project and then pass data from the server to a view. express-handlebars comes with useful helpers like each and if that can be used to display, modify, validate data in your view. It also lets you create custom helpers.

Documentation for express-handlebars

Make a Quote Generator using Vue: Part 1

Vue is one of the frameworks that’s often talked about (and compared with) Angular and React. These comparisons are often not very helpful and leave you more confused than before.

To correctly and fully understand what a framework can do for me I prefer trying it out first hand. And that’s what we’re here to do today. We’re here to get understand what Vue can do us. And don’t worry, we will not going to through endless pages of documentation. We’ll use it to make an app. I believe in learning by doing and so to start learning Vue we’ll create a simple quote generator app. This app will be very similar to Behappy.me’s quote generator.

demo image of quote generator

 

Note: If you are already familiar with Vue and would just like to learn about the quote generator, skip to the end of this part, copy the HTML, CSS from Setting up HTML section, and js from Preparing Data section below. You can then proceed to the next part. I’d still suggest you go over this part as well – it’ll hardly take a couple of minutes and you’ll learn a thing or two.

The first step would be to list the main components of Behappy.

Quote Generator’s components

  1. The input field for your quote and its author
  2. A selection mechanism for font and background color (I’m skipping the stamps for now but they shouldn’t be too different from what we do for font and background color)
  3. Live preview

That’s all the components. Now, that we know what we need to include let’s see how to do it. It’s time to launch our editors, get some coffee, and get ready for magic on your screen!

Including Vue JS

First, include Vue JS into your project. You can do this by adding https://cdn.jsdelivr.net/npm/vue’ within script tag in the head of your document. I know it is a better practice to include all scripts before the end of the body. But Vue JS is the hero of our project. I want to ensure that I have it loaded before anything else. Moreover, our project is going to be very small so it hardly makes any difference.

Setup for a Vue project

Include a div with an id of ‘app’.  Inside your javascript, create a Vue object called app. include a property el: ‘#app’.

Notice how the value of el is the id of the div you created. What this does is, it allows the div #app and all it’s children to communicate with the data in the Vue object called app.

Don’t worry, It’s not as complex as it sounds. We’ll discuss it in detail in the next step. For now, make sure that your code looks something like this.

<body>
    <div id = "app"></div>
    
    <script type="text/javascript>
        var app = new Vue({
            e1: '#app',
        });
    </script>
</body>

 

Binding with Vue

For understanding what I meant in the previous step, let’s add a textarea and include attribute v-model = “message”. This is what they call a directive in such frameworks. For angular these directives start with ng-, for Vue, they start with v-. Think of directives are power-ups for your HTML. These are used to make your HTML do smart things.

Now create a div and add {{message}} inside it.

The last thing to do is, inside our app object, create a new item called data. This is a Vue specific object property. Vue refers to this for any data that may be used within your HTML element specified as el. Inside data, let’s add message: ‘test message’

 

<div id = "app">
    <textarea v-model="message"></textarea>
    <div>{{message}}</div>
<div>
<script type="text/javascript>
    var app = new Vue({
        e1: '#app',
        data: {
            message: 'test message',
        }
    });
</script>

 

If you launch your project you should see ‘test message’ inside the text area and as the content of the div. Interesting, right? Vue has taken the value of message from data and passed it on as a form value inside the textarea using v-model and the content of the div.

All you did was use the directive v-model in your textarea, set {{message}} as the content of your div, and added message to your data object. Vue has tied them all together. This is going to be helpful in our app that has ‘live preview’. Changing the quote or background color will update the preview.

If you’re wondering – this binding works both ways. If you were to change the value of the message property the value of the textarea and the div would update too! Go to you Developer’s console, type app.message = “Vue is awesome!” and hit enter. Voila! the text in the textarea and the div changed too. This kind of two way binding is one of the salient features of Vue. When using Vue you no longer have to worry about keeping your variables up-to-date or accepting values from the input. The values are automatically updated.

Now that we know how the binding works let’s get the data ready. Once that’s in place all we’ll need to do is bind it to our HTML using Vue directives.

 

Step 1: Preparing data

We need a default message that will hold the quote, author’s name, background and font colors, and font styles. Apart from these, we’ll also set up properties for currentBackgroundColor, currentFontColor, currentFont. You’ll understand why we need these as we go along.

var app = new Vue({
    el:'#app',
    data:{
        message:'To live is the rarest thing in the world. Most people exist, that is all.',
        author:'Oscar Wilde',
        currentBackgroundColor:'#FFFFAA',
        currentFontColor:'#888888',
        currentFont:'Shadows Into Light',
        themes: [
            { backgroundColor:'#FFFFAA', fontColor:'#888888'},
            { backgroundColor:'#F1A9A0', fontColor:'#FFFFFF'},
            { backgroundColor:'#E4F1FE', fontColor:'#888888'},
            { backgroundColor:'#A2DED0', fontColor:'#FFFFFF'},
            { backgroundColor:'#FDE3A7', fontColor:'#888888'},
        ],
        fonts: [
            'Shadows Into Light',
            'Permanent Marker',
            'Kaushan Script',
            'Great Vibes',
            'Courgette'
       ]
    }
});

You may choose different values for colors and fonts. That does not affect the implementation in any way. Notice how the backgroundColor and fontColor are clubbed as a single unit. This allows you to pair a specific background color with a specific font color – avoiding cases where text me be illegible (imagine black text over black background).

Also, don’t forget to include the fonts you wish to use in your quote generator. If you want to go with the ones I have used then just add the following to the head of your document.

<link href="https://fonts.googleapis.com/css?family=Courgette|Great+Vibes|Indie+Flower|Kaushan+Script|Permanent+Marker|Shadows+Into+Light" rel="stylesheet">

With our data ready, the next step is to set up our HTML.

Step 2: Setting up HTML

Nothing fancy here. You can simply copy-paste the code from below. I have not included any directives yet because I’d like to go over each one individually so you understand it better.

<div id="controls">

    <h1>Enter Quote</h1>

    <textarea id="inputQuote" spellcheck="false" maxlength="80"></textarea>

    <input id="inputAuthor" type="text" spellcheck="false" maxlength="20">


    <h1>Select Font</h1>

    <ul class="optionsList" id="fontsList">

        <li> //font options to be displayed here </li>

    </ul>


    <h1>Select Color</h1>

    <ul class="optionsList">

        <li> //background color options will appear here </li>

    </ul>

</div>


<div id="preview">

    <div id="main">

        <div id="quote"> //the message updates here </div>

        <div id="author"> //author's name updates here </div>

    </div>

</div>

 

Step 3: Some CSS

Also, just so the project is easier to work with, here’s the CSS for it. If you’d like to write up your own, that’s great.  But for those of you who want to focus on VueJS, for now, copy-paste the CSS in your stylesheet.

body{
    border: 0;
    font-size: 100%;
    vertical-align: baseline;
    line-height: 1;
    font-family: Arial, Helvetica, sans-serif;
}

#app{
    display: flex;
    justify-content: space-around;
}

#inputQuote{
    width: 300px;
    height: 50px;
    padding: 15px;
    display: block;
    font-family: Arial, Helvetica, sans-serif;
    margin-bottom: 15px;
    resize: none;
}

#inputAuthor{
    width: 300px;
    padding: 15px;
    margin-bottom: 15px;
}

.optionsList{
    display: flex;
    list-style: none;
    padding: 0px;
}

.optionsList li{
    width: 100px;
    height: 40px;
    margin: 10px;
    padding-top: 10px 0 0 10px;
}

#fontsList li{
    border: 1px solid
}

#main{
    width: 400px;
    height: 400px;
    padding: 20px 40px;
}

#quote, #author{
    max-width: 100%;
    font-family: inherit;
    font-size: 4vw;
    margin: auto;
    text-align: left;
    word-wrap: break-word;
    margin-bottom: 15px;
}

#author{
    font-size: 2vw;
}

Conclusion

We’ve see how Vue let’s the data in our Vue object communicate with our HTML. In the next part, we’ll learn about various Vue directives to auto-populate values of background color and font in our HTML, and add inline styles and interaction. See you there!

Make a Quote Generator using Vue: Part 2

In the previous part, we learned about how data defined in a Vue object can be used inside our HTML. We then went on to include values for font family and background color in our Vue object. We set up our basic HTML and CSS.

In this part, our task is to help our HTML interact with our data. We can do this by using Vue directives. Let’s see how it is done.

Step 4: Vue’s v-model directive

Let’s go ahead and get over with the most obvious ones – message and author. In the previous part, we discussed how v-model can be used to bind data for form elements. All you have to do is include v-model=”message” for the textarea and v-model=”author” for the input field. Type {{message}} inside the #quote div and {{author}} inside the #author div within #preview.

 

<div id="controls">

    <h1>Enter Quote</h1>

    <textarea v-model="message" id="inputQuote" spellcheck="false" maxlength="80"></textarea>

    <input v-model="author" id="inputAuthor" type="text" spellcheck="false" maxlength="20">

</div>
.
.
.

<div id="preview">

    <div id="main">

    <div id="quote"> {{ message }} </div>

    <div id="author"> {{ author }} </div>

</div>

To test it out, type in a message or author’s name. The text should update in the Preview section on the right. Once you’ve made sure that it works well, move on to the next part.

Step 5: Vue’s v-for directive

Let’s populate our list of fonts. Vue has a directive v-for that can help us out here. Think of v-for as a for loop for HTML. To use it include v-for=”font in fonts” in the li tag of #fontsList as shown below

<ul class="optionsList" id="fontsList">
    
    <li v-for="font in fonts">{{ font }}</li>

</ul>

Here, font is the iterator and fonts is the name of the data array. {{font}} displays the current iterator’s value i.e. the font’s name inside the li tag. Just like {{message}} displayed the message text inside the #quote div.

An improvement over this would be to display these font labels in their respective font styles. We can do that by setting styles for each li tag inline. v-bind:style let’s us to specify inline styles for an HTML element.

 

<ul class="optionsList" id="fontsList">
 
    <li v-for="font in fonts" v-bind:style="{fontFamily: font}">{{ font }}</li>

</ul>

 

v-bind:style takes the value of an iterator and assigns it to the fontFamily for each li tag. I’d like to take a minute and appreciate how simple and elegant this is. Trying to achieve this in a traditional way would mean applying styles separately to each li or using JS to apply styles to each li. In contrast, Vue let us apply styles to an element while rendering it – all in a single line.

We can use v-bind:style to list our background colors as well. You can update the li for background colors like so

<ul class="optionsList">

    <li v-for="theme in themes" v-bind:style="{backgroundColor: theme.backgroundColor}></li>

</ul>

theme contains two properties – backgroundColor and fontColor. We use theme’s backgroundColor property and assign it to the style backgroundColor. This should list all of you background colors.

Our next step will be to set the font family, background color, and font color for our preview. This is where currentBackgroundColor, currentFontColor, and currentFont we defined in our data, will be used. We’ll use the v-bind:style, again, to do this.

<div id="main" v-bind:style="{backgroundColor: currentBackgroundColor,

color: currentFontColor,

fontFamily: currentFont}">

    <div id="quote">{{ message }}</div>

    <div id="author">- {{ author }}</div>

</div>

Launch your app again and check if everything is working fine. Let’s go ahead and add a way for this app to update to user’s selection.

Step 5: Adding interaction

In the previous step, we defined the styles for preview using the currentBackgroundColor, currentFontColor, and currentFont properties. These properties are defined in our data and so Vue will react to and re-render and relevant HTML, if these properties are changed.

So, we’ll need to somehow update the values of currentBackgroundColor, currentFontColor, and currentFont properties based on user’s selection. We don’t need to do this for message and author because the v-model directive handles it for us. It’s designed specifically with the intention of keeping the app aware of the freshest form data.

For non-form elements, we can use v-on:click. In your li tag for fonts add v-on:click=”currentFont = font”.

<ul class="optionsList" id="fontsList">
    <li v-for="font in fonts" v-bind:style="{fontFamily: font}" v-on:click="currentFont=font">
        {{ font }}
    </li>
</ul>

This tells the app to set the currentFont to the font value for that li tag when the user clicks on it. Try it out, when you click a font option the font in the #preview should update instantly. Similarly, we can update the code for background color.

<ul class="optionsList">
    <li v-for="theme in themes" 
        v-bind:style="{backgroundColor: theme.backgroundColor}
        v-on:click="currentBackgroundColor=theme.backgroundColor, currentFontColor=theme.fontColor"></li>
</ul>

Notice that we set the currentBackgroundColor and the currentFontColor here. Again, test it out. Works brilliantly, doesn’t it? You quote generator with a live preview is now ready.

Next Steps

You’ll agree that this still is a very basic quote generator. Even though we’ve mostly achieved what Behappy does, I’m sure you can think of ways to improve it. How about adding those stamps we left out at the beginning. Small hint: try using Font Awesome (or your favorite icon font) for this (instead of images). Icon fonts will render better and it’ll essentially be like loading text instead of trying to manage image icons. If you want to allow your users to download their quote as an image, check out html2Canvas created by Niklas von Hertzen. It’s an amazing library that takes your HTML elements and adds them to an HTML canvas. You can use this canvas to download its contents as an image.

Conclusion

We’ve created a very simple project and it does not even begin to measure Vue’s full capabilities. Vue has a lot more to offer. From conditional rendering, to state transitions, to custom directives – the list just goes on. And their documentation is full of detailed explanations and examples. Don’t forget to check it out.

I will not compare Vue with Angular or React because I don’t think it would be fair. They all have features that set them apart and they may have limitations that might undesirable for your project. The best way to asses this is to test it yourself.

CSS Grid image gallery in under 10 minutes

In this tutorial, we’ll use the CSS grid to create a classic three-column responsive image gallery. We’ll go through some very basic properties related to it. This is a beginner level tutorial and barely scratches the surface of what you could do with it. Before we begin, let’s refresh our understanding of CSS grid.

What is CSS Grid?

  • It is a display property. Using it is as simple as
    div{ display: grid; }
  • It converts your element into a grid and lets you place elements inside and/or across the cells of this grid.css grid simple example
  • A good example of where it can really shine is an image gallery or a product listing on a shopping website.
  • What makes the grid a hot commodity in the CSS market is that it has made the lives of developers a lot easier. What used to be done using tables, float and arbitrarily added padding can now be achieved easily using the grid. Making a layout responsive is unbelievably easy too!

Now then, let’s get started!

Step 1:

Set up your HTML. I’ve created an unordered list with an id #gallery and added 9 list items that contain images.

 

<body>

    <ul id="gallery">

        <li><img src="1.jpeg"></li>

        <li><img src="2.jpeg"></li>

        <li><img src="3.jpeg"></li>

        <li><img src="4.jpeg"></li>

        <li><img src="5.jpeg"></li>

        <li><img src="6.jpeg"></li>

        <li><img src="7.jpeg"></li>

        <li><img src="8.jpeg"></li>

        <li><img src="9.jpeg"></li>

    </ul>

</body>

With that out of the way, we can start working on the real stuff. Let’s head to our stylesheet.

Step 2:

In your stylesheet, declare the display property for #gallery as grid. If you now go to Developer tools (Select F12 on your keyboard), to the Elements tab, and the <ul id=gallery> element. You can see a dotted border around this. This simply indicated that the browser now identifies this as a grid element.

 

img{

    /* to ensure that the images are contained within their grid cells */
    width: 100%; 

}

#gallery{

    /* cosmetic css, resetting defaults for a ul element 

    it's alright if you do not include this. */

    list-style: none;

    padding: 0px;

    /* grid details */

    display: grid;
}

 

Step 3:

We define the number of columns we want this grid to have. For this, we use the grid-template-columns property. grid-template-columns is used to define the columns of your grid. You can use pixel widths, fractional units, or auto.

Since all three columns are going to be identical, let’s use repeat(3, 1fr). This basically means, repeat the column of 1 fractional unit thrice. Look how compact and elegant this is! To fully appreciate the beauty of this, head back to the Developer tools. Select <ul id=gallery> element. On the right, in the Styles tab, you should have grid-template-columnsrepeat(3, 1fr);. Try changing the 3 to 2 or 4, the number of columns changes. Now, instead of 1fr, try using 100 px. This fixes the width of each column to 100 px as opposed to earlier where the columns stretched to occupy entire width. The great thing is, it keeps the width of all your columns equal (unless you specify otherwise).

If the images seem to be too close together, add grid-column-gap: 10px; and grid-row-gap: 10px;. These, as their names suggest, add a specified gap between columns and rows respectively. Your styles for #gallery should look like this

 

#gallery{ 

    /* cosmetic css, resetting defaults for a ul element 

    it's alright if you do not include this. */ 

    list-style: none;

    padding: 0px;

    /* grid details */

    display: grid;

    grid-template-columns: repeat(3, 1fr);

    grid-column-gap: 10px;

    grid-row-gap: 10px;

}

And that’s it. you’re done. Your image gallery in the form of a 3 column grid is ready. Has it been 10 minutes, yet? Hardly! Let’s go ahead and make this gallery responsive.

Step 4:

Making a grid responsive is just a matter of changing the number of columns in your grid-template-columns. We will consider break-points 1024 px and 768 px.

@media screen and (max-width: 1024px){

    #gallery{

        /* for iPad landscape, the gallery will have 2 columns */

        grid-template-columns: repeat(2, 1fr);

    }

}

@media screen and (max-width: 768px){

    #gallery{

        /* for iPad landscape, the gallery will have 2 columns */

        grid-template-columns: 1fr;

    }

}

Congratulations! You’ve just created your own responsive image gallery. You this approach you can build a product listing page as well. Go ahead, give it a try.

Conclusion:

CSS grid is a great tool to create, well, grid-based components very easily. Making grids responsive isn’t all that tough either. Also, it has lots more to offer. For e.g. grid-template-areas let you easily set and modify the layout of a component. I’ve seen tutorials attempting to create the layout of entire websites using CSS grid. You could consider the layout as a grid and place your headers, and wrappers, and footers in this grid. But is it a good approach? We’ll cover this in one of the future tutorials.