One place for hosting & domains

      Template

      How To Use EJS to Template Your Node Application


      Introduction

      When creating quick on-the-fly Node applications, an easy and fast way to template our application is sometimes necessary.

      Jade comes as the view engine for Express by default but Jade syntax can be overly complex for many use cases. EJS is one alternative does that job well and is very easy to set up. Let’s take a look at how we can create a simple application and use EJS to include repeatable parts of our site (partials) and pass data to our views.

      Setting up the Demo App

      We will be making two pages for our application with one page with full width and the other with a sidebar.

      Get the code: You can find a git repo of the complete demo code on GitHub here

      File Structure

      Here are the files we’ll need for our application. We’ll do our templating inside of the views folder and the rest is pretty standard Node practices.

      - views
      ----- partials
      ---------- footer.ejs
      ---------- head.ejs
      ---------- header.ejs
      ----- pages
      ---------- index.ejs
      ---------- about.ejs
      - package.json
      - server.js
      

      package.json will hold our Node application information and the dependencies we need (express and EJS). server.js will hold our Express server setup, configuration. We’ll define our routes to our pages here.

      Node Setup

      Let’s go into our package.json file and set up our project there.

      package.json

      {
        "name": "node-ejs",
        "main": "server.js",
        "dependencies": {
          "ejs": "^3.1.5",
          "express": "^4.17.1"
        }
      }
      

      All we will need is Express and EJS. Now we have to install the dependencies we just defined. Go ahead and run:

      With all of our dependencies installed, let’s configure our application to use EJS and set up our routes for the two pages we need: the index page (full width) and the about page (sidebar). We will do all of this inside our server.js file.

      server.js

      // load the things we need
      var express = require('express');
      var app = express();
      
      // set the view engine to ejs
      app.set('view engine', 'ejs');
      
      // use res.render to load up an ejs view file
      
      // index page 
      app.get("https://www.digitalocean.com/", function(req, res) {
          res.render('pages/index');
      });
      
      // about page 
      app.get('/about', function(req, res) {
          res.render('pages/about');
      });
      
      app.listen(8080);
      console.log('8080 is the magic port');
      

      Here we define our application and set it to show on port 8080. We also have to set EJS as the view engine for our Express application using app.set('view engine', 'ejs');. Notice how we send a view to the user by using res.render(). It is important to note that res.render() will look in a views folder for the view. So we only have to define pages/index since the full path is views/pages/index.

      Start Up our Server

      Go ahead and start the server using:

      Now we can see our application in the browser at http://localhost:8080 and http://localhost:8080/about. Our application is set up and we have to define our view files and see how EJS works there.

      Create the EJS Partials

      Like a lot of the applications we build, there will be a lot of code that is reused. We’ll call those partials and define three files we’ll use across all of our site: head.ejs, header.ejs, and footer.ejs. Let’s make those files now.

      views/partials/head.ejs

      <meta charset="UTF-8">
      <title>EJS Is Fun</title>
      
      <!-- CSS (load bootstrap from a CDN) -->
      <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.5.2/css/bootstrap.min.css">
      <style>
          body { padding-top:50px; }
      </style>
      

      views/partials/header.ejs

      <nav class="navbar navbar-expand-lg navbar-light bg-light">
        <a class="navbar-brand" href="https://www.digitalocean.com/">EJS Is Fun</a>
        <ul class="navbar-nav mr-auto">
          <li class="nav-item">
            <a class="nav-link" href="https://www.digitalocean.com/">Home</a>
          </li>
          <li class="nav-item">
            <a class="nav-link" href="http://www.digitalocean.com/about">About</a>
          </li>
        </ul>
      </nav>
      

      views/partials/footer.ejs

      <p class="text-center text-muted">© Copyright 2020 The Awesome People</p>
      

      Add the EJS Partials to Views

      We have our partials defined now. All we have to do is include them in our views. Let’s go into index.ejs and about.ejs and use the include syntax to add the partials.

      Syntax for including an EJS Partial

      Use <%- include('RELATIVE/PATH/TO/FILE') %> to embed an EJS partial in another file.

      • The hyphen <%- instead of just <% to tell EJS to render raw HTML.
      • The path to the partial is relative to the current file.

      views/pages/index.ejs

      <!DOCTYPE html>
      <html lang="en">
      <head>
          <%- include('../partials/head'); %>
      </head>
      <body class="container">
      
      <header>
          <%- include('../partials/header'); %>
      </header>
      
      <main>
          <div class="jumbotron">
              <h1>This is great</h1>
              <p>Welcome to templating using EJS</p>
          </div>
      </main>
      
      <footer>
          <%- include('../partials/footer'); %>
      </footer>
      
      </body>
      </html>
      

      Now we can see our defined view in the browser at http://localhost:8080. node-ejs-templating-index

      For the about page, we also add a bootstrap sidebar to demonstrate how partials can be structured to reuse across different templates and pages.

      views/pages/about.ejs

      <!DOCTYPE html>
      <html lang="en">
      <head>
          <%- include('../partials/head'); %>
      </head>
      <body class="container">
      
      <header>
          <%- include('../partials/header'); %>
      </header>
      
      <main>
      <div class="row">
          <div class="col-sm-8">
              <div class="jumbotron">
                  <h1>This is great</h1>
                  <p>Welcome to templating using EJS</p>
              </div>
          </div>
      
          <div class="col-sm-4">
              <div class="well">
                  <h3>Look I'm A Sidebar!</h3>
              </div>
          </div>
      
      </div>
      </main>
      
      <footer>
          <%- include('../partials/footer'); %>
      </footer>
      
      </body>
      </html>
      

      If we visit http://localhost:8080/about, we can see our about page with a sidebar! node-ejs-templating-about

      Now we can start using EJS for passing data from our Node application to our views.

      Pass Data to Views and Partials

      Let’s define some basic variables and a list to pass to our home page. Go back into your server.js file and add the following inside your app.get("https://www.digitalocean.com/") route.

      server.js

      // index page 
      app.get("https://www.digitalocean.com/", function(req, res) {
          var mascots = [
              { name: 'Sammy', organization: "DigitalOcean", birth_year: 2012},
              { name: 'Tux', organization: "Linux", birth_year: 1996},
              { name: 'Moby Dock', organization: "Docker", birth_year: 2013}
          ];
          var tagline = "No programming concept is complete without a cute animal mascot.";
      
          res.render('pages/index', {
              mascots: mascots,
              tagline: tagline
          });
      });
      

      We have created a list called mascots and a simple string called tagline. Let’s go into our index.ejs file and use them.

      Render a Single Variable in EJS

      To echo a single variable, we just use <%= tagline %>. Let’s add this to our index.ejs file:

      views/pages/index.ejs

      ...
      <h2>Variable</h2>
      <p><%= tagline %></p>
      ...
      

      Loop Over Data in EJS

      To loop over our data, we will use .forEach. Let’s add this to our view file:

      views/pages/index.ejs

      ...
      <ul>
          <% mascots.forEach(function(mascot) { %>
              <li>
                  <strong><%= mascot.name %></strong>
                  representing <%= mascot.organization %>, born <%= mascot.birth_year %>
              </li>
          <% }); %>
      </ul>
      ...
      

      Now we can see in our browser the new information we have added!

      node-ejs-templating-rendered

      Pass Data to a Partial in EJS

      The EJS partial has access to all the same data as the parent view. But be careful: If you are referencing a variable in a partial, it needs to be defined in every view that uses the partial or it will throw an error.

      You can also define and pass variables to an EJS partial in the include syntax like this:

      views/pages/about.ejs

      ...
      <header>
          <%- include('../partials/header', {variant:'compact'}); %>
      </header>
      ...
      

      But you need to again be careful about assuming a variable has been defined.

      If you want to reference a variable in a partial that may not always be defined, and give it a default value, you can do so like this:

      views/partials/header.ejs

      ...
      <em>Variant: <%= typeof variant != 'undefined' ? variant : 'default' %></em>
      ...
      

      In the line above, the EJS code is rendering the value of variant if it’s defined, and default if not.

      Conclusion

      EJS lets us spin up quick applications when we don’t need anything too complex. By using partials and having the ability to easily pass variables to our views, we can build some great applications quickly.

      For more reference on EJS see the official docs here.



      Source link

      Understanding Template Literals in JavaScript


      The author selected the COVID-19 Relief Fund to receive a donation as part of the Write for DOnations program.

      Introduction

      The 2015 edition of the ECMAScript specification (ES6) added template literals to the JavaScript language. Template literals are a new form of making strings in JavaScript that add a lot of powerful new capabilities, such as creating multi-line strings more easily and using placeholders to embed expressions in a string. In addition, an advanced feature called tagged template literals allows you to perform operations on the expressions within a string. All of these capabilities increase your options for string manipulation as a developer, letting you generate dynamic strings that could be used for URLs or functions that customize HTML elements.

      In this article, you will go over the differences between single/double-quoted strings and template literals, running through the various ways to declare strings of different shape, including multi-line strings and dynamic strings that change depending on the value of a variable or expression. You will then learn about tagged templates and see some real-world examples of projects using them.

      Declaring Strings

      This section will review how to declare strings with single quotes and double quotes, and will then show you how to do the same with template literals.

      In JavaScript, a string can be written with single quotes (' '):

      const single="Every day is a good day when you paint."
      

      A string can also be written with double quotes (" "):

      const double = "Be so very light. Be a gentle whisper."
      

      There is no major difference in JavaScript between single- or double-quoted strings, unlike other languages that might allow interpolation in one type of string but not the other. In this context, interpolation refers to the evaluation of a placeholder as a dynamic part of a string.

      The use of single- or double-quoted strings mostly comes down to personal preference and convention, but used in conjunction, each type of string only needs to escape its own type of quote:

      // Escaping a single quote in a single-quoted string
      const single=""We don"t make mistakes. We just have happy accidents." - Bob Ross'
      
      // Escaping a double quote in a double-quoted string
      const double = ""We don't make mistakes. We just have happy accidents." - Bob Ross"
      
      console.log(single);
      console.log(double);
      

      The result of the log() method here will print the same two strings to the console:

      Output

      "We don't make mistakes. We just have happy accidents." - Bob Ross "We don't make mistakes. We just have happy accidents." - Bob Ross

      Template literals, on the other hand, are written by surrounding the string with the backtick character, or grave accent (`):

      const template = `Find freedom on this canvas.`
      

      They do not need to escape single or double quotes:

      const template = `"We don't make mistakes. We just have happy accidents." - Bob Ross`
      

      However, they do still need to escape backticks:

      const template = `Template literals use the ` character.`
      

      Template literals can do everything that regular strings can, so you could possibly replace all strings in your project with them and have the same functionality. However, the most common convention in codebases is to only use template literals when using the additional capabilities of template literals, and consistently using the single or double quotes for all other simple strings. Following this standard will make your code easier to read if examined by another developer.

      Now that you’ve seen how to declare strings with single quotes, double quotes, and backticks, you can move on to the first advantage of template literals: writing multi-line strings.

      Multi-line Strings

      In this section, you will first run through the way strings with multiple lines were declared before ES6, then see how template literals make this easier.

      Originally, if you wanted to write a string that spans multiple lines in your text editor, you would use the concatenation operator. However, this was not always a straight-forward process. The following string concatenation seemed to run over multiple lines:

      const address="Homer J. Simpson" + 
        '742 Evergreen Terrace' + 
        'Springfield'
      

      This might allow you to break up the string into smaller lines and include it over multiple lines in the text editor, but it has no effect on the output of the string. In this case, the strings will all be on one line and not separated by newlines or spaces. If you logged address to the console, you would get the following:

      Output

      Homer J. Simpson742 Evergreen TerraceSpringfield

      You can use the backslash character () to continue the string onto multiple lines:

      const address="Homer J. Simpson
        742 Evergreen Terrace
        Springfield"
      

      This will retain any indentation as whitespace, but the string will still be on one line in the output:

      Output

      Homer J. Simpson 742 Evergreen Terrace Springfield

      Using the newline character (n), you can create a true multi-line string:

      const address="Homer J. Simpsonn" + 
        '742 Evergreen Terracen' + 
        'Springfield'
      

      When logged to the console, this will display the following:

      Output

      Homer J. Simpson 742 Evergreen Terrace Springfield

      Using newline characters to designate multi-line strings can be counterintuitive, however. In contrast, creating a multi-line string with template literals can be much more straight-forward. There is no need to concatenate, use newline characters, or use backslashes. Just pressing ENTER and writing the string across multiple lines works by default:

      const address = `Homer J. Simpson
      742 Evergreen Terrace
      Springfield`
      

      The output of logging this to the console is the same as the input:

      Output

      Homer J. Simpson 742 Evergreen Terrace Springfield

      Any indentation will be preserved, so it’s important not to indent any additional lines in the string if that is not desired. For example, consider the following:

      const address = `Homer J. Simpson
                       742 Evergreen Terrace
                       Springfield`
      

      Although this style of writing the line might make the code more human readable, the output will not be:

      Output

      Homer J. Simpson 742 Evergreen Terrace Springfield

      With multi-line strings now covered, the next section will deal with how expressions are interpolated into their values with the different string declarations.

      Expression Interpolation

      In strings before ES6, concatenation was used to create a dynamic string with variables or expressions:

      const method = 'concatenation'
      const dynamicString = 'This string is using ' + method + '.'
      

      When logged to the console, this will yield the following:

      Output

      This string is using concatenation.

      With template literals, an expression can be embedded in a placeholder. A placeholder is represented by ${}, with anything within the curly brackets treated as JavaScript and anything outside the brackets treated as a string:

      const method = 'interpolation'
      const dynamicString = `This string is using ${method}.`
      

      When dynamicString is logged to the console, the console will show the following:

      Output

      This string is using interpolation.

      One common example of embedding values in a string might be for creating dynamic URLs. With concatenation, this can be cumbersome. For example, the following declares a function to generate an OAuth access string:

      function createOAuthString(host, clientId, scope) {
        return host + '/login/oauth/authorize?client_id=' + clientId + '&scope=" + scope
      }
      
      createOAuthString("https://github.com', 'abc123', 'repo,user')
      

      Logging this function will yield the following URL to the console:

      Output

      https://github.com/login/oauth/authorize?client_id=abc123&scope=repo,user

      Using string interpolation, you no longer have to keep track of opening and closing strings and concatenation operator placement. Here is the same example with template literals:

      function createOAuthString(host, clientId, scope) {
        return `${host}/login/oauth/authorize?client_id=${clientId}&scope=${scope}`
      }
      
      createOAuthString('https://github.com', 'abc123', 'repo,user')
      

      This will have the same output as the concatenation example:

      Output

      https://github.com/login/oauth/authorize?client_id=abc123&scope=repo,user

      You can also use the trim() method on a template literal to remove any whitespace at the beginning or end of the string. For example, the following uses an arrow function to create an HTML <li> element with a customized link:

      const menuItem = (url, link) =>
        `
      <li>
        <a href="https://www.digitalocean.com/${url}">${link}</a>
      </li>
      `.trim()
      
      menuItem('https://google.com', 'Google')
      

      The result will be trimmed of all the whitespace, ensuring that the element will be rendered correctly:

      Output

      <li> <a href="https://google.com">Google</a> </li>

      Entire expressions can be interpolated, not just variables, such as in this example of the sum of two numbers:

      const sum = (x, y) => x + y
      const x = 5
      const y = 100
      const string = `The sum of ${x} and ${y} is ${sum(x, y)}.`
      
      console.log(string)
      

      This code defines the sum function and the variables x and y, then uses both the function and the variables in a string. The logged result will show the following:

      Output

      The sum of 5 and 100 is 105.

      This can be particularly useful with ternary operators, which allow conditionals within a string:

      const age = 19
      const message = `You can ${age < 21 ? 'not' : ''} view this page`
      console.log(message)
      

      The logged message here will change depnding on whether the value of age is over or under 21. Since it is 19 in this example, the following output will be logged:

      Output

      You can not view this page

      Now you have an idea of how template literals can be useful when used to interpolate expressions. The next section will take this a step further by examining tagged template literals to work with the expressions passed into placeholders.

      Tagged Template Literals

      An advanced feature of template literals is the use of tagged template literals, sometimes referred to as template tags. A tagged template starts with a tag function that parses a template literal, allowing you more control over manipulating and returning a dynamic string.

      In this example, you’ll create a tag function to use as the function operating on a tagged template. The string literals are the first parameter of the function, named strings here, and any expressions interpolated into the string are packed into the second parameter using rest parameters. You can console out the parameter to see what they will contain:

      function tag(strings, ...expressions) {
        console.log(strings)
        console.log(expressions)
      }
      

      Use the tag function as the tagged template function and parse the string as follows:

      const string = tag`This is a string with ${true} and ${false} and ${100} interpolated inside.`
      

      Since you’re console logging strings and expressions, this will be the output:

      Output

      (4) ["This is a string with ", " and ", " and ", " interpolated inside." (3) [true, false, 100]

      The first parameter, strings, is an array containing all the string literals:

      • "This is a string with "
      • " and "
      • " and "
      • " interpolated inside."

      There is also a raw property available on this argument at strings.raw, which contains the strings without any escape sequences being processed. For example, /n would just be the character /n and not be escaped into a newline.

      The second parameter, ...expressions, is a rest parameter array consisting of all the expressions:

      The string literals and expressions are passed as parameters to the tagged template function tag. Note that the tagged template does not need to return a string; it can operate on those values and return any type of value. For example, we can have the function ignore everything and return null, as in this returnsNull function:

      function returnsNull(strings, ...expressions) {
        return null
      }
      
      const string = returnsNull`Does this work?`
      console.log(string)
      

      Logging the string variable will return:

      Output

      null

      An example of an action that can be performed in tagged templates is applying some change to both sides of each expression, such as if you wanted to wrap each expression in an HTML tag. Create a bold function that will add <strong> and </strong> to each expression:

      function bold(strings, ...expressions) {
        let finalString = ''
      
        // Loop through all expressions
        expressions.forEach((value, i) => {
          finalString += `${strings[i]}<strong>${value}</strong>`
        })
      
        // Add the last string literal
        finalString += strings[strings.length - 1]
      
        return finalString
      }
      
      const string = bold`This is a string with ${true} and ${false} and ${100} interpolated inside.`
      
      console.log(string)
      

      This code uses the forEach method to loop over the expressions array and add the bolding element:

      Output

      This is a string with <strong>true</strong> and <strong>false</strong> and <strong>100</strong> interpolated inside.

      There are a few examples of tagged template literals in popular JavaScript libraries. The graphql-tag library uses the gql tagged template to parse GraphQL query strings into the abstract syntax tree (AST) that GraphQL understands:

      import gql from 'graphql-tag'
      
      // A query to retrieve the first and last name from user 5
      const query = gql`
        {
          user(id: 5) {
            firstName
            lastName
          }
        }
      `
      

      Another library that uses tagged template functions is styled-components, which allows you to create new React components from regular DOM elements and apply additional CSS styles to them:

      import styled from 'styled-components'
      
      const Button = styled.button`
        color: magenta;
      `
      
      // <Button> can now be used as a custom component
      

      You can also use the built-in String.raw method on tagged template literals to prevent any escape sequences from being processed:

      const rawString = String.raw`I want to write /n without it being escaped.`
      console.log(rawString)
      

      This will log the following:

      Output

      I want to write /n without it being escaped.

      Conclusion

      In this article, you reviewed single- and double-quoted string literals and you learned about template literals and tagged template literals. Template literals make a lot of common string tasks simpler by interpolating expressions in strings and creating multi-line strings without any concatenation or escaping. Template tags are also a useful advanced feature of template literals that many popular libraries have used, such as GraphQL and styled-components.

      To learn more about strings in JavaScript, read How To Work with Strings in JavaScript and How To Index, Split, and Manipulate Strings in JavaScript.



      Source link