how to delay interpolation of template strings?
Le 16 déc. 2014 à 09:27, Niloy Mondal <niloy.mondal84 at gmail.com> a écrit :
I want to define a template string using backquotes in a different file and then have it interpolated with actual values in a different file. How can I do it?
Just enclose it in a function:
function foo(a) {
return `some template ${a}`
}
foo("bar") // will evaluate `some template ${"bar"}`
Thanks, this would work.
How can I construct a template string dynamically? Like reading the template from a file/database and then interpolate it.
irony ... I think you would need to evaluate the template string inline in order to interpolate its result ...
OR
you just go for this method which also works down to ES3 engine: gist.github.com/WebReflection/8f227532143e63649804
Can this be considered for a feature request? Provision in the language to dynamically construct template strings and interpolate them.
An HTML attachment was scrubbed... URL: esdiscuss/attachments/20141216/629d9200/attachment
that's necessary for everything that has multi-language support ( at least the way it's done these days ) hence my snippet that makes interpolation/templating straight forward with dynamic strings.
Down the gist you also have CSP meta tags too to include it as inline resource once + it scales a bit more than what Alex shown above since you don't need to write logic in the string itself or name function arguments, you just pass the object and you are good to go.
Hope that helps but I'm also curious to know if there is actually a way using ES6 templates. Maybe we are missing something.
Can this be considered for a feature request? Provision in the language to dynamically construct template strings and interpolate them.
As pointed out by others, since template strings can contain arbitrary JS
expressions, what you're asking for is equivalent to eval
.
You want templates, which is something provided by many libraries (Handlebars, etc.). The language provides template strings as a syntactic feature.
Templates and template strings are very different. Don’t be fooled by the name into thinking that templates are some sort of natural feature addition to template strings; they’re in fact a different concept altogether.
I might be wrong and either way it's probably too ugly to be serious but couldn't you, using a template tag, do something like the following:
var template = compile`
Hello ${"first_name"}
`;
template({ first_name: "John" });
Actually, it would be cool if some sugar could be done for the example I just did:
var template = compile`
Hello ${{first_name}}
`;
template({ first_name: "John" });
This is starting to seem kind of promising (although { } vs. " " is of questionable value). But, what are the semantics of ${{}} in general, without the compile
tag?
Well syntactically speaking I don't think it's valid right now, if it were it would be an object literal but in my mind that is considerably less useful than what COULD be done there. If you were to take my example and simply remove the compile tag you'd end up with "Hello first_name";
You'll get a ReferenceError because it has the object literal { first_name }
, which is shorthand for { first_name: first_name }
, and there is
(presumably) no binding for first_name
.
Apologies for the probably futile extra precaution but, since someone might be confused already, I think it must be said that nobody should ever use ES6 interpolated strings like the following:
dom.innerHTML = `<div class="${className}"></div>`;
unless eventual bound references are not made safe elsewhere.
In a raw template like logic, like the suggested gist, it should also, eventually, be like the following:
dom.innerHTML = '<div class="${className}"></div>'.template({
className: safeForHTML(className)
});
Still in templates, when double curly braces are in place usually means
such safe HTML/sanitize operation is done automagically behind the scene
avoiding repeated safeForHTML
calls.
I hope the distinction is cleaner now.
Or just use tagged template strings to do the sanitization.
Le 16 déc. 2014 à 16:42, Matthew Robb <matthewwrobb at gmail.com> a écrit :
Actually, it would be cool if some sugar could be done for the example I just did:
var template = compile` Hello ${{first_name}} `; template({ first_name: "John" });
I guess you want sugar for the following valid ES6 code?
var template = _ => `
Hello ${_.first_name}
`;
template({ first_name: "John" });
You're right, I must be crazy for wanting my code to be readable and slightly resemble the syntax people have been using as defacto-standard for years now. I, and I am sure the greater web dev community, much prefer new language features to be completely foreign and difficult to make sense of in relation to what's already being done.
I don't mean to be snarky about it (and I apologize, I mean no offense) but sheesh... Aren't things like async-functions sugar for existing valid es6 code? Maybe it would be better if what gets passed to a template tag-function is not, by default, the values from the local-bindings. Perhaps there is a way to make template tags much more useful by allowing the function to determine more about the semantics of the string.
Sometimes this list really does make me think I am crazy or something.
An HTML attachment was scrubbed... URL: esdiscuss/attachments/20141216/91d39e93/attachment-0001
once you pass an object, can you tell me why the suggested gist would not work?
You don't want scope lookup in your strings because coming from elsewhere, and you want to pass an object.
So what is exactly the issue with 'Hello ${first_name}'.template({first_name: "John"}) ?
Is it because it's in the prototype? You are not going to for/in a string
(I hope) anyway ... but if that's the issue you can always grab the code
and make it a template
function, right ?
it's WTFPL code, go ahead!
OT this back-tick thing will mess up quite a bit on markdown ... oh well ...
The compile() tag wouldn’t work the way tagged templates are currently. The args
array would be initialized at compile()-time, and those same arguments would always be used no matter what you’d passed in to the returned function.
It would be cool if there were some sugar for this, but I don’t think tagged templates will get you there. Worse than that, you’d ideally be able to run “compiled” templates through tag functions (e.g. for markup sanitization), and it’s not clear how you’d do that from this. Maybe a new builtin like global.Template, maybe Reflect.compileTemplate, which would accept a template string as input (this wouldn’t really make sense unless it were somehow a “magic” function which processed templates differently though :()
An HTML attachment was scrubbed... URL: esdiscuss/attachments/20141216/2ba9dad8/attachment-0001
The main issue with it is, because of how you write it, you can’t really do anything useful with it. For instance, you can’t run a “compile()”’d template through a tag function — you can’t use useful expressions in template expressions, and in the current design there’s no real way around that, unless you’re willing to use eval()
or new Function()
to accomplish it.
do these strings come from a database or not? If so, how are you storing strings in such database, via static back-tick analysis or via just a textarea? 'cause in the second case you are good to go via multiline strings but in the first one I'm having hard time trying to figure out your real-world use case.
You are statically using ES6 template strings somewhere you'd like to store in the database or ... what?
Thanks for any further explanation
I want to define a template string using backquotes in a different file and then have it interpolated with actual values in a different file. How can I do it?