Simple implementation of the Javascript string template, javascript string

Source: Internet
Author: User

Simple implementation of the Javascript string template, javascript string

This was due to a problem I encountered when I was the first real website in my life two years ago.

The website uses the frontend and backend separation method to return JSON data from the backend REST interface and then render the data on the page from the front end.

Like many beginners of Javascript, I used concatenated strings to embed JSON data into HTML. At the beginning, the number of codes was small and acceptable for the time being. However, when the page structure is complex, its weakness becomes intolerable:

  1. Inconsistent writing. Every time you write a variable, you need to break it down and insert a plus (+) and ". Error-prone.
  2. It cannot be reused. HTML fragments are discrete data and it is difficult to extract duplicate parts.
  3. The <template> tag cannot be used well. This is a new tag added in HTML5. We strongly recommend that you add an HTML template to the <template> tag to simplify the code.
  4. At that time, I felt like this:

Is TMD teasing me?

To solve this problem, I temporarily put down my project and spent half an hour implementing an extremely simple string template.

Requirement Description

Implement a render (template, context) method to fill the placeholders in the template with context. Requirements:

There is no need for control flow components (such as loops and conditions), as long as there is a variable replacement function.
Cascade variables can also be expanded.
Escape separator {And} should not be rendered, and blank characters are allowed between the separator and the variable
Example:

render('My name is {name}', {  name: 'hsfzxjy'}); // My name is hsfzxjyrender('I am in {profile.location}', {  name: 'hsfzxjy',  profile: {    location: 'Guangzhou'  }}); // I am in Guangzhourender('{ greeting }. \\{ This block will not be rendered }', {  greeting: 'Hi'}); // Hi. { This block will not be rendered }

Implementation

Write down the function framework first:

function render(template, context) {}

Obviously, the first thing to do is to match the placeholders in the template.

Matching placeholder

The matching must be done by a regular expression. So what should this regular expression look like?

Based on the descriptions of requirements 1 and 2, we can write:

var reg = /\{([^\{\}]+)\}/g;

As for requirement 3, the first concept I thought of was forward matching. Unfortunately, Javascript does not support it, so I had to use a compromise:

Var reg = /(\\)? \ {([^ \ {\} \] + )(\\)? \}/G; // if the value of the first or third group is not empty, do not render the current Code. The Code should be like this: function render (template, context) {var tokenReg = /(\\)? \ {([^ \ {\} \] + )(\\)? \}/G; return template. replace (tokenReg, function (word, slash1, token, slash2) {if (slash1 | slash2) {// match the return word character. replace ('\', ''); // If the separator is escaped, It is not rendered }//...})}

Placeholder replacement

Well, the regular expression is determined. The next step is to replace the regular expression.

Based on requirement 2, the template engine must be able to render both level 1 variables and multi-level variables. What should we do?

In fact, it is very simple: Separate the tokens by., and perform step-by-step search:

Var variables = token. replace (/\ s/g ,''). split ('. '); // cut tokenvar currentObject = context; var I, length, variable; // query contextfor (I = 0, length = variables. length, variable = variables [I]; I <length; ++ I) currentObject = currentObject [variable]; return currentObject;

However, it is possible that the variable specified by the token does not exist, and the above Code will report an error. For better experience, the Code should have a certain degree of fault tolerance ability:

Var variables = token. replace (/\ s/g ,''). split ('. '); // cut tokenvar currentObject = context; var I, length, variable; for (I = 0, length = variables. length, variable = variables [I]; I <length; ++ I) {currentObject = currentObject [variable]; if (currentObject = undefined | currentObject = null) return ''; // if the current index object does not exist, an empty string is directly returned .} Return currentObject;

After all the code is combined, the final version is obtained:

function render(template, context) {  var tokenReg = /(\\)?\{([^\{\}\\]+)(\\)?\}/g;  return template.replace(tokenReg, function (word, slash1, token, slash2) {    if (slash1 || slash2) {       return word.replace('\\', '');    }    var variables = token.replace(/\s/g, '').split('.');    var currentObject = context;    var i, length, variable;    for (i = 0, length = variables.length, variable = variables[i]; i < length; ++i) {      currentObject = currentObject[variable];      if (currentObject === undefined || currentObject === null) return '';    }    return currentObject;  })}

Except for blank rows, there are 17 rows in total.

Attaches a function to the String prototype chain.

Even we can achieve some cool effects by modifying the prototype chain:

String.prototype.render = function (context) {  return render(this, context);};

Then we can call it like this:

"{greeting}! My name is { author.name }.".render({  greeting: "Hi",  author: {    name: "hsfzxjy"  }});// Hi! My name is hsfzxjy.

Articles you may be interested in:
  • Javascript template Technology
  • JavaScript dynamic addition of table rows using templates and tags
  • JS template Implementation Method
  • AngularJS getting started tutorial (2): AngularJS Template
  • Details about the Javascript template engine mustache. js
  • Explore how to use the Javascript template engine mustache. js

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.