DEV Community

Glad Chinda
Glad Chinda

Posted on

Why don't you just put a tag on it

Hello there,
Do you have 3-5 minutes to spare? If so, let's have a brief discussion about Template Tags in JavaScript.

Background

In ES2015, a new string delimiter was introduced to the language for template literals. Template literal strings are delimited by a pair of back-ticks ().

Template literals were introduced to deal with challenges associated with formatting and representing strings, such as: creating multiline strings, string substitutions, etc.

String Substitution

Prior to template literals, constructing dynamic strings was a process that relied heavily on string concatenation. Here is what it looks like:

const person = {
  name: 'Glad Chinda',
  lang: 'JavaScript'
};

// String concatenation
const bio = person.name + ' knows how to code in ' + person.lang + '.';

console.log(bio); // "Glad Chinda knows how to code in JavaScript."

Having to chain all those disjointed fragments of the string using the + (concatenation) operator wasn't one of the coolest things.

However, with template literals, dynamic strings can be created via string substitution in a much more declarative way, like so:

const person = {
  name: 'Glad Chinda',
  lang: 'JavaScript'
};

// String substitution with template literal
const bio = `${person.name} knows how to code in ${person.lang}.`;

console.log(bio); // "Glad Chinda knows how to code in JavaScript."

Let's say we want all the substituted strings in the literal to be in uppercase. We could modify the template literal like so:

// String substitutions in uppercase
const bio =
  `${person.name.toUpperCase()} knows how to code in ${person.lang.toUpperCase()}.`;

console.log(bio); // "GLAD CHINDA knows how to code in JAVASCRIPT."

Calling the .toUpperCase() method on each substituted string of the template literal is way too verbose and degrades its readability.

We can do better, with a slightly modified template literal syntax. All we have to do is just put a tag on it, and it becomes a tagged template literal.
 

Template Tags

A template tag is simply a function that defines how a template literal should be transformed.

The syntax of a template tag is pretty straightforward.

  • The first argument is an array containing all the literal strings in the template literal.

  • The remaining arguments correspond with the string substitutions in the template literal.

It is important to note that the number of items in the first argument array is always higher than the number of remaining arguments by 1. Hence, if the first argument contains 5 literals, then there will be 4 remaining arguments.

Let's create a template tag called uppercase to transform our template literal as required.

function uppercase (literals, ...substitutions) {
  let finalString = '';

  for (let i = 0, len = substitutions.length; i < len; i++) {
    finalString += literals[i];
    finalString += String(substitutions[i]).toUpperCase();
  }

  finalString += literals[literals.length - 1];

  return finalString;
}

We will modify the template literal to use the uppercase template tag like so:

/**
 * Tagged template literal
 *
 * Equivalent to:
 *   uppercase(literals, substitution1, substitution2)
 *
 * where:
 *   literals => ['', ' knows how to code in ', '.'],
 *   substitution1 => person.name,
 *   substitution2 => person.lang
 */
const bio = uppercase`${person.name} knows how to code in ${person.lang}.`;

console.log(bio); // "GLAD CHINDA knows how to code in JAVASCRIPT."

Notice that applying the template tag like so:

uppercase`${person.name} knows how to code in ${person.lang}.`

is functionally equivalent to calling the template tag function like so:

uppercase(
  ['', ' knows how to code in ', '.'],
  person.name,
  person.lang
);

In summary, you can achieve so much more from a template literal if only you will be willing to just put a tag on it.

❤️ Like and Share

If you found this post insightful in any way please:

  • Like this post
  • Comment your feedback
  • Share with someone
  • Follow me on Twitter

Top comments (0)