grupoarrfug.com

Creating a Simple JavaScript Template Engine: A Comprehensive Guide

Written on

Understanding Template Engines

Even seasoned developers may struggle with certain interview questions. One such challenge arose when my friend Nancy faced a tough question during a job interview: she was tasked with creating a JavaScript template engine on the spot.

The request was particularly daunting as she was simply seeking employment. To clarify the question, she was instructed to add a render(obj) method to the String object that substitutes specific placeholders in a string with values from the provided object.

const template = 'My name is ${name}, age ${age}, I am a ${job.name}';

const employee = {

name: 'fatfish',

age: 100,

job: {

name: 'front end development'

}

};

const renderStr = template.render(employee);

console.log(renderStr); // Output: 'My name is fatfish, age 100, I am a front end development'

What Exactly is a Template Engine?

You may be familiar with template engines such as Nunjucks, which serve a similar purpose. Let’s explore an example using Nunjucks:

nunjucks.configure({ autoescape: true });

const template = 'My name is {{name}}, age {{age}}, I am a {{job.name}}';

const employee = {

name: 'fatfish',

age: 100,

job: {

name: 'front end development'

}

};

const renderStr = nunjucks.renderString(template, employee);

console.log(renderStr); // Output: 'My name is fatfish, age 100, I am a front end development'

Nancy's challenge was to implement something akin to this functionality, transitioning from ${name} to {{name}}.

Solution 1: Using Regular Expressions

My initial instinct was to leverage regular expressions for this task. By extracting variables from the string, we could simplify the problem.

Step 1: Extract Variables

String.prototype.render = function (obj) {

const template = this;

const variableRegex = /${([^${}]+)}/g;

template.replace(variableRegex, ($0, variable) => {

console.log(variable);

});

};

const template = 'My name is ${name}, age ${age}, I am a ${job.name}';

template.render();

This code captures the variables name, age, and job.name. The regex ([^{]+) focuses on capturing any characters except for $, {, or }.

Step 2: Retrieve Values from the Object

String.prototype.render = function (obj) {

const template = this;

const variableRegex = /${([^${}]+)}/g;

const getVariableValue = (variable) => {

variable = variable.split('.');

let variableValue = obj;

while (variable.length) {

variableValue = variableValue[variable.shift()];

}

return variableValue;

};

const renderStr = template.replace(variableRegex, ($0, variable) => {

return getVariableValue(variable);

});

return renderStr;

};

const template = 'My name is ${name}, age ${age}, I am a ${job.name}';

const employee = {

name: 'fatfish',

age: 100,

job: {

name: 'front end development'

}

};

const renderStr = template.render(employee);

console.log(renderStr); // Output: 'My name is fatfish, age 100, I am a front end development'

We've successfully created a simple template engine using regular expressions!

Solution 2: Utilizing eval

Let's review how template literals in ES6 work:

const name = 'fatfish';

const age = 100;

const job = {

name: 'front end development'

};

const renderString = My name is ${name}, age ${age}, I am a ${job.name};

console.log(renderString);

With eval, we can dynamically declare variables:

const employee = {

name: 'fatfish',

age: 100,

job: {

name: 'front end development'

}

};

eval('var { name, age, job } = employee');

console.log(name, age, job);

Combining these concepts, we can craft our second solution:

String.prototype.render = function (obj) {

const template = this;

eval(var { ${Object.keys(obj).join(',')} } = obj);

const renderStr = eval('`' + template + '`');

return renderStr;

};

const template = 'My name is ${name}, age ${age}, I am a ${job.name}';

const employee = {

name: 'fatfish',

age: 100,

job: {

name: 'front end development'

}

};

const renderStr = template.render(employee);

console.log(renderStr);

Solution 3: Using with

The with statement can also simplify our task:

const employee = {

name: 'fatfish',

age: 100,

job: {

name: 'front end development'

}

};

with (employee) {

console.log(name, age, job);

}

This approach is more concise, achieving similar results:

String.prototype.render = function (obj) {

with (obj) {

return eval('`' + this + '`');

}

};

const template = 'My name is ${name}, age ${age}, I am a ${job.name}';

const employee = {

name: 'fatfish',

age: 100,

job: {

name: 'front end development'

}

};

const renderStr = template.render(employee);

console.log(renderStr);

Conclusion

Thank you for taking the time to read this guide! I hope you found it enlightening and are eager to explore more high-quality content in the future.

For more engaging discussions, be sure to follow us on various platforms and join our community!

Share the page:

Twitter Facebook Reddit LinkIn

-----------------------

Recent Post:

A Deep Dive into Cosmic Voids: Origins and Mysteries

Explore the intriguing nature of cosmic voids, their origins, and significance in the structure of the universe.

Comprehensive Guide to My LeetCode Solutions in Golang

Explore my ongoing collection of Golang solutions for various LeetCode problems, complete with resources and video guides.

Navigating Bipolar Disorder: Understanding Support and Solitude

This article explores the complexities of bipolar disorder, emphasizing the importance of social support and the balance between solitude and isolation.

Best Bodyweight Exercise: The Side Plank Unveiled

Discover why the side plank is the ultimate bodyweight exercise for building strength, stability, and core engagement.

# The Intriguing Behavior of Dead Bodies in Water: Do They Sink or Float?

Explore the fascinating science behind whether dead bodies sink or float in water, including factors affecting buoyancy and density.

Understanding Arctic Changes: Implications for Global Climate

An exploration of how changes in the Arctic may foreshadow broader global climate impacts.

Encouraging Kids to Love Vegetables: 30 Effective Tips

Discover 30 creative strategies to help your children enjoy eating vegetables and develop healthy eating habits.

The Emergence of Two-Tower Models in Recommendation Systems

Exploring the innovative two-tower model that addresses biases in recommendation systems, enhancing their effectiveness.