0

So, there is a ES6 literal ` - backquote mark to make multiline strings with variables inside, and I need to use it with template, initially described in HTML.

<div id="template">${value}</div>

JS:

var value = 'Hello, world!'

var template = document.getElementById('template');

// Magic to convert DOM element to template string `<div id="template">${value}</div>`

console.log(element)

>>> <div id="template">Hello, world!</div>

So, I need something in "Magic" line)

4
  • Does it only contain variables or could it contain more complex expressions like real template strings? Commented Jul 16, 2018 at 19:13
  • @Barmar, no, but, honestly, just two variables Commented Jul 16, 2018 at 19:14
  • 1
    You can't, unless you're willing to use eval: var template = eval("`" + document.getElementById('template').outerHTML + "`") Commented Jul 16, 2018 at 19:15
  • Is there some averseness to using a real templating system versus re-inventing the wheel? Commented Jul 16, 2018 at 19:41

3 Answers 3

1

eval() will do what you want, although if there are expressions more complex than variables it could be dangerous.

var value = 'Hello, world!'
var template = document.getElementById('template').outerHTML;

var element = template.replace(/\$\{(\w+)\}/g, function(match, varname) {
  return window[varname];
});
console.log(element);
<div id="template">${value}</div>

If you only allow global variables in the template, you can use a regular expression.

var value = 'Hello, world!'
var template = document.getElementById('template').outerHTML;
var element = eval('`' + template + '`');
console.log(element);
<div id="template">${value}</div>

However, I recommend not using variable references at all, this is usually more general than you need. Create an object that holds all the allowed template variables, and use templateVars[varname] rather than window[varname].

Sign up to request clarification or add additional context in comments.

3 Comments

console.log(element) prints Just "Hello, world!" without div, but I need both) Btw, It works with . outerHTML instead of textContent)
@MaxCore Honestly, a short solution to this question is pretty ugly, as it’s using eval and outerHTML. A safer solution would require tons of code. Maybe it’d be better to use some other approach, instead.
@Xufox I've added a version that uses a regexp.
1

You could create this with new Function: You would pass the stringed template string you want to be converted as the body of the function:

const value = 'Hello, world!';
const template = document.getElementById('template').outerHTML;
const func = new Function('value', `return \`${template}\``);
console.log(func(value));
<div id="template">${value}</div>

1 Comment

Using new Function is just a more verbose way of doing eval().
1

Since we're re-inventing templates here, it seems a lot safer to just write your own template function that mimics a string literals, eg:

(function() {

  let tpl = document.getElementById('template-1').innerHTML

  let template = function(tpl) {
    return function(values) {
      let str = tpl.toString() //copy it

      for( let key in values ) {
       str = str.replace(v, values[key])
      }

      return str
    }
  }

  let el = template(tpl)({
     '${value}': 'test'
   })

   console.log(el)

   // <div id="myDiv">This is a test</div>

})()

//html
<!doctype html>
<html>
  <head></head>
  <body>
    <div>Hello World!</div>
    <template id="template-1">
      <div id="myDiv">This is a ${value}</div>
    </template>
   <script type="text/javascript" src="main.js"></script>
 </body>
</html>

If you need to perform validation and escaping that can be done per value. The use of eval() is certainly not recommended and you're really not buying anything by using a string literal here other than obfuscating your code.

1 Comment

Man, you are the best, specially after you first comment to a question)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.