JavaScript Template Literals & Tagged Templates

String formation from variables in JavaScript had been pain all the time. Not anymore; JavaScript Template Literals will save a lot of your time. Let's see the working & benefits of JavaScript Template Literals.

JavaScript Template Literals & Tagged Templates

String formation from variables in JavaScript had been pain all the time. No more, JavaScript Template Literals and Tagged Templates will save a lot of your time. Let's see working and benefits of JavaScript Template Literals and Tagged Templates.

JavaScript Template literals

JavaScript Template literals are the Literals or Strings allowing Expression in between them. These are enclosed inside two back-ticks (`) and the expressions start with $ sign and then are enclosed in curly braces {}.

And the output of expression is placed at that position where the expression is embedded. For example:

let name = '';
console.log(`Hello ${name}!`);

name = 'World';
console.log(`Hello ${name}!`);

name = 'Pankaj';
console.log(`Hello ${name}!`);

generating the output like:

Hello !
Hello World!
Hello Pankaj!

So the template literal Hello ${name}! is equal to 'Hello ' + name + '!'.

That was the trivial usage of Template Literals. Going forward on advanced usage, the expressions can be anything which may return a String. If not convertible to String, then it will try to convert it to string and may give output like [object Object].

For example if you give { place: 'World', name: 'Pankaj'] } to the name variable above, you will get Hello [object Object]!

And the strings can have newlines and any character in between. Following is a valid example of Template Literal. On usage, this will preserve the spaces and tabs in the output as well.

const template = (name, profileUrl, pictureUrl) => `
<div>
  <p><a href="${profileUrl}">${name}</a></p>
  <img src="${pictureUrl}" style="max-height: 200px" />
</div>
`
template('Pankaj', '//pankaj.pro', 'https://avatars0.githubusercontent.com/u/251937?s=200&v=4');

Which on executing will give following output:

"
<div>
  <p><a href="//pankaj.pro">Pankaj</a></p>
  <img src="https://avatars0.githubusercontent.com/u/251937?s=200&v=4" />
</div>
"

which now can be used in any way, like following:

let div = document.createElement('div');
div.id = 'profile';
div.innerHTML = template('Pankaj', '//pankaj.pro', 'https://avatars0.githubusercontent.com/u/251937?s=200&v=4');
div.setAttribute('style', 'display: block; width: 200px; height: 200px;');
document.body.appendChild(div);

Now lets see how to render a list of links for navigation menu. Example markup is from Nav in Bootstrap 4.

const topLevel = [
  { label: 'Home', url: '/home' },
  { label: 'Products', url: '/products' },
  { label: 'Services', url: '/services' },
  { label: 'About', url: '/about-us' },
  { label: 'Contact', url: '/contact-us' },
];

const social = [
  { label: '<i class="fa fa-facebook-square"></i>', url: 'https://facebook.com/time2hack' },
  { label: '<i class="fa fa-twitter-square"></i>', url: 'https://twitter.com/time2hack' },
  { label: '<i class="fa fa-google-plus-square"></i>', url: 'https://plus.google.com/+Time2hack' },
]

const menu = (menuData) => `
<ul class="nav">
  ${menuData.map(item => `
    <li class="nav-item">
      <a class="nav-link" href="${item.url}">${item.label}</a>
    </li>
  `)}
</ul>
`;

And considering that we have these menus on header and footer, on executing the above code in following way; we will add it to page.

document.querySelector('body > header').innerHTML += menu(topLevel);
document.querySelector('body > footer').innerHTML += menu(social);

Tagged Templates

Tagged Templates are the template literals which are tagged some another function for further processing.

For example:

const tag = (parts, name, url) => {
    return `${parts[0]}__${name}__${parts[1]}__${url}__`;
}

const name = 'Pankaj';
const url = 'http://pankaj.pro';

console.log(tag`I am ${name} and you can reach me at ${url}`);

which will give following output:

I am __Pankaj__ and you can reach me at __http://pankaj.pro__

The expressions reaching as the parameters to the tagging function are already executed and hence you can do more of the text processing of the template parts.

With tagged templates, you can achieve more wide range of the templates' capabilities.

Let's take following example of unknown number of expressions and wrap all the expression parameters with code HTML tag:

const tag = (parts, ...params) => {
  const strParts = parts.slice();
  const exprParts = params.slice();
  const output = [];
  while(strParts.length) {
    output.push(strParts.shift());
    exprParts.length && output.push(`<code>${exprParts.shift()}</code>`);
  }
  return output.join('');
}

const name = 'Pankaj';
const url = 'http://pankaj.pro';

console.log(tag`I am ${name} and you can reach me at ${url}`);

which will generate the following output:

I am <code>Pankaj</code> and you can reach me at <code>http://pankaj.pro</code>

Execute JavaScript code inside ES6 templates - Time to Hack
ES6 templates are very powerful and can serve as a template engine. See its complex usage to execute JavaScript code inside ES6 templates with IIFE.
ToDo App with WebComponents and ShadowDOM - Time to Hack
Lets see WebComponents in action by building a ToDo App with WebComponents and ShadowDOM. This will build an understanding of using these in your Front End apps.

Conclusion

And with such power to JavaScript Template Literals we can easily remove the need of template engine if our needs/requirements are not too wide-range for templates.

Please let me know about your experiences and any problems you are facing with Template Literals through comments ? or on Twitter at @heypankaj_ and/or @time2hack

If you find this article helpful, please share it with others ?

Subscribe to the blog to receive new posts right to your inbox.