JavaScript - Tagged Templates

Hello, future JavaScript wizards! Today, we're going to embark on an exciting journey into the world of Tagged Templates. Don't worry if you've never heard of them before – by the end of this lesson, you'll be tagging templates like a pro!

JavaScript - Tagged Templates

What Are Tagged Templates?

Tagged templates are a powerful feature introduced in ES6 (ECMAScript 2015) that allows you to parse template literals with a function. Now, I know that might sound a bit intimidating, but think of it as giving your template strings superpowers!

In simpler terms, tagged templates let you process a template string before it's finally rendered. It's like having a personal assistant who can modify your messages before you send them out.

Basic Syntax

Let's start with the basic syntax:

function myTag(strings, ...values) {
  // Your magic goes here
}

const result = myTag`Hello, ${name}!`;

In this example, myTag is our template tag function. It receives two types of arguments:

  1. An array of string literals
  2. The interpolated values (those inside ${})

Why Use Tagged Templates?

You might be wondering, "Why should I bother with tagged templates?" Well, let me tell you a little story.

Once upon a time, there was a young developer named Alex. Alex was building a messaging app and wanted to make sure no one could send harmful HTML in their messages. Tagged templates came to the rescue! Alex used them to sanitize user input and prevent potential security risks.

Tagged templates are super useful for:

  • Sanitizing user input
  • Internationalization (i18n)
  • Styling (like in styled-components for React)
  • And much more!

Examples of Tagged Templates

Let's dive into some examples to see tagged templates in action!

Example 1: A Simple Greeting

function greet(strings, ...values) {
  return `${strings[0]}${values[0].toUpperCase()}${strings[1]}`;
}

const name = "alice";
console.log(greet`Hello, ${name}!`);
// Output: Hello, ALICE!

In this example, our greet function takes the name and converts it to uppercase. The strings array contains ["Hello, ", "!"], and values array contains ["alice"].

Example 2: HTML Escaping

function safeHtml(strings, ...values) {
  const escapeHtml = (str) => {
    return str.replace(/&/g, "&")
              .replace(/</g, "&lt;")
              .replace(/>/g, "&gt;")
              .replace(/"/g, "&quot;")
              .replace(/'/g, "&#039;");
  };

  return strings.reduce((result, string, i) => {
    return result + string + (values[i] ? escapeHtml(values[i]) : '');
  }, '');
}

const userInput = '<script>alert("XSS attack!")</script>';
console.log(safeHtml`User input: ${userInput}`);
// Output: User input: &lt;script&gt;alert(&quot;XSS attack!&quot;)&lt;/script&gt;

This example shows how we can use tagged templates to escape potentially harmful HTML. Our safeHtml function replaces special characters with their HTML entity equivalents.

Example 3: Styling with Tagged Templates

function css(strings, ...values) {
  return strings.reduce((result, string, i) => {
    return result + string + (values[i] || '');
  }, '');
}

const color = 'red';
const fontSize = '20px';

const styles = css`
  color: ${color};
  font-size: ${fontSize};
`;

console.log(styles);
// Output: 
//   color: red;
//   font-size: 20px;

This example demonstrates how tagged templates can be used for styling, similar to how they're used in libraries like styled-components.

Advanced Usage: Tagged Template Methods

Tagged templates can also have methods attached to them. Let's look at an example:

function currency(strings, ...values) {
  const result = strings.reduce((acc, str, i) => {
    return acc + str + (values[i] || '');
  }, '');

  return {
    toString() {
      return result;
    },
    USD() {
      return '$' + result;
    },
    EUR() {
      return '€' + result;
    }
  };
}

const amount = 100;
const formatted = currency`${amount}`;

console.log(formatted.toString()); // Output: 100
console.log(formatted.USD()); // Output: $100
console.log(formatted.EUR()); // Output: €100

In this example, our currency tag returns an object with methods, allowing for flexible formatting options.

Conclusion

Tagged templates are a powerful feature in JavaScript that allow for complex string manipulation and processing. They're not just a fancy way to concatenate strings – they open up a world of possibilities for creating safer, more flexible, and more expressive code.

Remember, like any powerful tool, tagged templates should be used judiciously. They're great for specific use cases like sanitization, internationalization, or creating domain-specific languages, but for simple string interpolation, regular template literals are often sufficient.

Now that you've learned about tagged templates, why not try creating your own? Start small, maybe with a simple formatting function, and gradually work your way up to more complex use cases. Happy coding, future JavaScript masters!

Method Description
strings.raw Gives access to the raw strings in the template literals
String.raw A built-in tag function for getting the raw string form of template literals

Credits: Image by storyset