import parseTpl from './parse-es6-template';
parseTpl('${name} is now master of the ${galaxy}', {
name: 'John',
galaxy: 'Milky Way',
});
Last active
October 26, 2024 03:15
-
-
Save smeijer/6580740a0ff468960a5257108af1384e to your computer and use it in GitHub Desktop.
ES6 template string parser
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
function get(path, obj, fb = `$\{${path}}`) { | |
return path.split('.').reduce((res, key) => res[key] || fb, obj); | |
} | |
function parseTpl(template, map, fallback) { | |
return template.replace(/\$\{.+?}/g, (match) => { | |
const path = match.substr(2, match.length - 3).trim(); | |
return get(path, map, fallback); | |
}); | |
} | |
export default parseTpl; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Hey there, as per:
interpolate('Errors are kept to minimum: ${x.o.x.o.x.o.x.o.x.o.x.o.x.o}')
//> Errors are kept to minimum: ${x.o.x.o.x.o.x.o.x.o.x.o.x.o}
I wanted to print out references to missing variables, as opposed to cause trouble, I just wanted this little function to work without causing any issues.
I can see that you don't like that and would probably prefer for
${true}x
to result inx
, personally I hate that, because your request for the value of .true is lost, and you may not notice that your data object does not contain .true = "Interpolate with this."BEFORE I tell you what you want to hear, let me make a note about the Nullish Coalescing Operator (??), which you can read about here: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Nullish_coalescing_operator
OK, so what is SUPER UNCLEAR about the code, is the tail end with the
??
that is just an OR or what you are used to seeing as||
, except||
had a problem if the reference to .test was 0, then the function would see that as a miss, and return ${true} which is a way of signalling that interpolation failed.SO, with
||
instead of??
all works OK...interpolate('${true}x ${hello}', {hello:'world', true:'I think therefore I am!'})
//> "I think therefore I am!x world"
BUT, if true was 0 (zero or "falsey") then interpolate would act as if true had no value, meaning it would return the ${true}:
interpolate('${true}x ${hello}', {hello:'world', true:0})
//> "${true}x world"
NOW, with
??
zero is treated as truthy, becasue it is not undefined, it is just 0interpolate('${true}x ${hello}', {hello:'world', true:0})
//> "0x world"
See? that is what
??
does, it allows me to interpolate your data requests with falsey variables.I understand your question (but I am long-winded), here is what you were looking for:
USE THIS IF YOU DON'T WANT TO SEE ${true}:
I replaced m with '', right at the end, m, is the match! In your case ${true}, and I was just returning it so that you see it is unmatched, and then throw in .true = 'something' but what you expect is for ${true} to be interpolated with nothing or '', and that is what the code above does, ho ho.
Here is a slightly more expanded example:
interpolate('${true}x ${hello} ${C0FFEE}', {hello:'world', C0FFEE:0, true:undefined})
//> "x world 0"
Note how ${true} was understood, but since it is undefined, and you don't want to see it again, it has been removed now.
And note how ${C0FFEE} which is 0 actually does get interpolated because of the Nullish Coalescing Operator (as opposed to the ol'
||
)And that ${hello} works just as expected.
To use your example:
interpolate('${true}x',{a:'hovercraft'})
//> "x"
you just get x.
Ps.
And in the end I want to add that:
interpolate('Errors are kept to minimum: ${x.o.x.o.x.o.x.o.x.o.x.o.x.o}')
//> Errors are kept to minimum: ${x.o.x.o.x.o.x.o.x.o.x.o.x.o}
has changed behaviour now, it returns:
//> "Errors are kept to minimum: "
See it is no onger alerting you that ${x.o.x.o.x.o.x.o.x.o.x.o.x.o} was not resolved, or in your case it is no longer alerting you that ${true} was not resolved.
Ps. Ps.
I understand you put in true to mess with my function, but it is interpreted as as an object property, it is a name, and not a value. It happends here: p.split('.').reduce((a,f)=>a?a[f]:undefined,c) p is a string with the value "true" as matched by my regular expression /${([^}]+)}/
Thank You @makmav for your interest in my fantastic code,
I hope this message finds you well,
Now let us take a moment of serenity silence, and admire our new
Nullish Coalescing Operator because it is amazing, I am so excited to be evaluating falseys as true whoo hooo!!!
Ps. Ps. Ps.
🐈
${true}x -> x