What ya need there is a bit of templating

Avatar of Chris Coyier
Chris Coyier on

I had a fella write in to me the other day. He had some HTML, CSS, and JavaScript, and it just wasn’t behaving like he thought it ought to. The HTML had some placeholders in it and the JavaScript had some data in it, and the assumption was that the data would fill the placeholders.

To those of us with some degree of web knowledge, we can look at this and see why it’s not working like he thought it would. But I think it’s also valuable to try to see things from that perspective and then look at solutions that are hopefully as simple as the original problem seems to be.

The HTML was something like this…

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <title>Test</title>
  <link rel="stylesheet" href="test.css">
  <script src="data.js"></script>
</head>
<body>
  <section>
    <div>{company_name}</div>
  </section>
</body>
</html>

The JavaScript was like this…

var company_data = {
  "{company_name}" : "SOME COMPANY",
};

There is nothing invalid going on here.

That’s all perfectly valid code. It is linked up right. It will run. It just doesn’t do anything besides render {company_name} to the screen. The expectation is that it would render SOME COMPANY to the screen instead, replacing the {company_name} placeholder with the data from the JavaScript file.

Let’s fix it with a one-liner.

In this exact scenario, to display the correct company name, we need to select that element in the DOM and replace its content with our data. We could do that by adding this one extra line to the JavaScript:

var company_data = {
  "{company_name}": "SOME COMPANY"
};

document.querySelector("div").innerHTML = company_data["{company_name}"];

That’s not particularly re-usable or resiliant, but hey, it’s also not over-thinking or over-tooling it.

The expectation was templating

I think we can see at this point that what he hoped would happen is that this sort of templating would automatically happen. Provide an object with keys that match what is in the HTML, the content in that HTML is automatically swapped out. It just doesn’t work that way with raw web technologies.

No joke, there are hundreds of ways to go about handling this. Here’s a few off the top of my head:

  • Use a templating language like Handlebars or Mustache
  • Use a static site generator like Eleventy, which uses Liquid by default
  • Make an HTML <template> and write your own script to use it
  • Make a Web Component
  • Use a back-end language instead, or a language like Nunjucks to process ahead of time
  • Use a preprocessor like Pug

As a general preference, I’d say doing the templating server-side or during a build is ideal — why mess with the DOM if you don’t need to?

But just to ignore that advice for a second, here’s an example of doing it client-side with Handlebars, just so the fella from the original email has a working example of how that can work: