4 ms·
I'm so glad to see this and projects like this getting attention. I'm responsible for several tools at my current job using nothing but straight JS, including a
by errantspark 7y ago
I'm so glad to see this and projects like this getting attention. I'm responsible for several tools at my current job using nothing but straight JS, including a couple which have had a significant (positive) impact on the special projects team here.
I love JS. I love it's ubiquity (F12 in any browser and you've got a REPL). I love the freedom I have when I write in it to do whatever the fuck I want and shoot myself in the foot in all sorts of strange ways. It's a very expressive language that lends itself to all sorts of fun. I love being able to inline C functions as WASM. I love manually managing memory with typed arrays. I love the filth of it all. It's liberating to give up all your dignity and just fling mud with a big grin on your face because your ridiculous 5 lines are a functional standin for a templating engine.
let applyTemplate = template => object => {
let keys = Object.keys(object)
return new Function('input' , `let {${keys.join(',')}} = input
return \`${template}\``)(object)
}
- baxuz 7y agoI'm having trouble reasoning about this code, can you show me how it's used?
- arexxbifs 7y agoIt creates a function returning a function, where the argument to the first (which is a template) is used as a closure in the second (which takes a dict of values). The last function called in turn creates a function using the Function constructor, which, since it takes a string argument as the function body, allows the expansion of the values dict into variables and thus the population of the template string: applyTemplate("aaa ${v}")({"v":"yo"}) --> "aaa yo"
- baxuz 7y agoHow come you haven't used tagged template literals? These would fit this use case: https://codeburst.io/javascript-es6-tagged-template-literals-a45c26e54761 https://codeburst.io/javascript-es6-tagged-template-literals...
- arexxbifs 7y agoIt's not my code :) However, tagged template literals won't allow dict expansion the way this solution does. Also, a template literal is evaluated at the time of assignment. This will allow you to re-use an arbitrary template string with any matching values: tpl = applyTemplate("Hello ${a}"); tpl({"a": "you"}); // --> Hello you tpl({"a": "dude"}); // --> Hello dude
- errantspark 7y agoYou did a better job of explaining my code than I would have done! Thank you.
- arexxbifs 7y agoThanks! My pleasure :-)
- skrebbel 7y agoWoa there! Why would JavaScript have `with` if you weren't intended to use it‽ How about: let applyTemplate = template => object => { with(object) { return eval("`"+template+"`"); } }
- dgb23 7y agoFrom the MDN docs: > Use of the with statement is not recommended, as it may be the source of confusing bugs and compatibility issues. See the "Ambiguity Contra" paragraph in the "Description" section below for details. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/with https://developer.mozilla.org/en-US/docs/Web/JavaScript/Refe...
- madeofpalk 7y agoThat's the joke? Use of new Function and eval is also generally not recommended.
- bigblind 7y ago"Living a little" is not recommended, because it may lead to confusing situations.
- bregma 7y agoIt's just so beautiful. I can't stop looking.
- madeofpalk 7y agolove to use eval!
- dukoid 7y agoI am using simple JS function that builds a DOM fragment in a safe way as a template engine replacement: https://github.com/stefanhaustein/notemplate/blob/master/src/notemplate.js https://github.com/stefanhaustein/notemplate/blob/master/src... Allowed me to implement TodoMVC in less than 150 LOC. Usage examples start here: https://github.com/stefanhaustein/notemplate/blob/2ee22e392df139f3e787f0e47c1c01280ab97926/demo/todomvc/js/app.js#L56 https://github.com/stefanhaustein/notemplate/blob/2ee22e392d...
- err4nt 7y agoI've been doing something very similar for templating static HTML sites amongst other things - you can interpret any string as a JS template string: function jstsEngine(string = '', environment = {}) { return new Function( ...Object.keys(environment), 'output={}', 'return [`' + string + '`, output]' )(...Object.values(environment)) } Link with examples: https://github.com/tomhodgins/jsts-engine https://github.com/tomhodgins/jsts-engine
- errantspark 7y agoThat's what I'm using it for as well! I believe our functions here are isomorphic, though I'm a couple lines shorter ;) You've got an excellent username btw. <3
- err4nt 7y ago<3 you have a nice username too :D