How to make a simple JS templating framework
Tags: webdev, javascript, tutorial
Published: 2021-01-03 03:08:39

To make a JS framework for templating it is actually much easier than you may think. All it really is, is a way to replace text with a corresponding value. Lets say I have the text,
~~~
Hello I am name
~~~
And I want to replace name with Bob, with this,
~~~js
"Hello I am name".replace("name", "bob")
// Hello I am bob
~~~
We are just using the _replace_ function that comes in the prototype of a string. Lets say we have a list variables for the template,
~~~js
{
  name: 'Joe',
  age: 42,
  favorateColor: 'red',
}
~~~
And we have the template as,
~~~
{name} is {age} and {name}'s favorite color is {favorateColor}. {unknown}
~~~
Here is how we would accomplish this:
1. First loop through each key in the object
1. Replace each template with the corresponding value
1. Remove templates with undefined values

This is how we would do that

~~~js
var values = {
  name: 'Joe',
  age: 42,
  favorateColor: 'red',
}

var template = "{name} is {age} and {name}'s favorite color is {favorateColor}. {unknown}"

// replace each {value} of values
for (var value in values) {
  template = template.replace(RegExp('{' + value + '}', 'g'), values[value])
}

// Replace templates where the variable was not found
template = template.replace(/{\w+}/g, '')
~~~

Output:
~~~
Joe is 42 and Joe's favorite color is red.
~~~

We were able to replace the templates with the correct values and remove the {unknown} template. Notice we used the RegExp function when replacing the templates because it allows us to add the 'g' flag called global to replace every match instead of just one.

This is a nice little trick to replace the variables but there is no logic in these templates. If we had a template variable that was a Boolean being true or false, we could not show or hide text based on the state of the variable, it would just show true or false.

To make a little more useful templating framework, we could evaluate JavaScript within the { and } and replace it with the output of the evaluation. We could do something like this:
~~~
You are {age < 18 ? 'a child' : 'an adult'}
~~~
If you were to execute the JavaScript between the brackets, you would get "You are a child" if age is less than 18 and "You are an adult" if age is 18.

To accomplish this we would have to go through each template one at a time until there is no templates left. Here is a solution:

~~~js
var age = 20;
var template = "You are {age < 18 ? 'a child' : 'an adult'}"
var ex = /{(.+)}/ // Regex to match templates

// Keep on going until the match of the template is null
while(template.match(ex)){
  var match = template.match(ex); // get the match
  
  // replace the entire template with the result from the evaluation of match[1]
  // match[1] is the JS inside the { and }
  template = template.replace(match[0], eval(match[1]));
}

// You are an adult
~~~

That is the start to a simple templating framework but you should add features such as safe evaluations if there is an error when it is executed. Feel free to change the regular expression to something that you prefer. Its a simple concept that can be modified and used for complex applications.

Here is the above code in a function
~~~js
function myFramework(template){
  var ex = /{(.+)}/
  while(template.match(ex)){
    var match = template.match(ex);
    template = template.replace(match[0], eval(match[1]));
  }
  return template;
}
~~~

Comment if you have any suggestions or ideas for this templating strategy.