-1

I'm not trying to reinvent the wheel here, just playing around with a question that was put to me. How would I write a simple template engine function. My immediate answer was more old school but with ES6 and the new spread operator, got me thinking maybe there is a better way of doing this now using the spread operator. Anyone got any ides ? Or would I still have to loop through and find my delimiter like i was using below const delimiter = '{{ name }}';.

    const root = document.getElementById('root');
    const html = "<p>My name is {{ name }}</p>";

    var template = function(html){
      return function(data){
        for(var prop in data){
          var regx = "{{\\s?" + prop + "\\s?}}";
          html = html.replace(new RegExp(regx, "ig"), data[prop]);  
        }
        return html;
        }
    }

    var tmp = template(html);
    root.innerHTML = tmp({
      name: "John Doe"
    });;
me-me
  • 5,139
  • 13
  • 50
  • 91
  • 2
    I don't see any operations here that mimic the spread operator. – 4castle Feb 12 '18 at 21:25
  • What got you thinking about spread syntax? I can't see how it would be useful in a template engine. – Bergi Feb 12 '18 at 21:35
  • Take a look at [https://stackoverflow.com/questions/18673860/defining-a-html-template-to-append-using-jquery](https://stackoverflow.com/questions/18673860/defining-a-html-template-to-append-using-jquery). – takendarkk Feb 12 '18 at 21:42
  • I haven't used the spread operator but what I have seen is it allows you to be able to pass objects around using string templates ${string} I just thought I might be able to use it instead of looping through my string to find a delimiter but I guess not after reading more about the spread operator. I guess the only way is to loop through like I'm doing. – me-me Feb 12 '18 at 22:30

1 Answers1

0

Not with the spread operator, but I would use class instead of the function function, and Object.keys to generate one regular expression (for all keys), using the callback argument of replace:

class Template {
    constructor(html) {
        this.html = html;
    }
    resolve(data) {
        const regx = "{{\\s?(" + Object.keys(data).join('|') + ")\\s?}}";
        return this.html.replace(new RegExp(regx, "ig"), (m, prop) => data[prop])
    }
}

const delimiter = '{{ name }}',
    root = document.getElementById('root'),
    html = "<p>My name is {{ name }}</p>",
    tmp = new Template(html);

root.innerHTML = tmp.resolve({
    name: "John Doe"
});
<div id="root"></div>

Note that you should probably make sure that any special characters in the properties are escaped so they don't get interpreted by new RegExp. But as you did not do this in your solution, I left that out as well.

trincot
  • 317,000
  • 35
  • 244
  • 286