Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
ES6 template string parser
import parseTpl from './parse-es6-template';

parseTpl('${name} is now master of the ${galaxy}', { 
  name: 'John',
  galaxy: 'Milky Way',
});
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;
@mbrowne

This comment has been minimized.

Copy link

@mbrowne mbrowne commented Nov 17, 2017

Small note: in the regex, I think the backslash in front of the first { is unnecessary. Also, it will match things like ${foo{bar}. It might be better to use this:

/\${([^{]+)}/g

@jasongerbes

This comment has been minimized.

Copy link

@jasongerbes jasongerbes commented Aug 8, 2018

@mbrowne has a good point, but you'll need to change your regex to this for it to work /\${([^{]+[^}])}/g as you need to exclude the extra }

@catpea

This comment has been minimized.

Copy link

@catpea catpea commented Aug 31, 2020

I needed a quick and dirty version that would tolerate missing data. I renamed the parseTpl function to interpolate and the path resolution is baked in via a fault tolerant reducer. Thank you for helping me think through this, it is a very busy evening, but I had a lot of fun.

I am using it in the Open Source cataclysm which is a static html generator like Jekyll. I am writing it to have a generator that is more respectful of HTML, it is very early, but I will finish it.

function interpolate(t, c){return t.replace(/\${([^}]+)}/g,(m,p)=>p.split('.').reduce((a,f)=>a?a[f]:undefined,c)??m);}
interpolate('My ${a} is full of eels.',{a:'hovercraft'})
//> My hovercraft is full of eels.

interpolate('Answer to the Ultimate Question of Life, the Universe, and Everything is: ${robotic}',{robotic:parseInt(101010, 2)})
//> Answer to the Ultimate Question of Life, the Universe, and Everything is: 42

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}

interpolate('Simple arrays are kind of ${0}', ["supported!"])
//> Simple arrays are kind of supported!

interpolate('Including complex arrays... ${A.c.h.0.0.0}! and will make you very brave, if used in production, and bless you for being so mighty! <3', {A:{c:{h:[[['Achooo']]]}}})
//> Including complex arrays... Achooo! and will make you very brave, if used in production, and bless you for being so mighty! <3

interpolate('A more complex answer to the Ultimate Question of Life, the Universe, and Everything is still: ${human.answer}',
{human:{answer:['Love', 'Wisdom', 'Funnyness', 'Aardvark', 'Hugs'].map(word=>word.charCodeAt(0)).reduce((a,i)=>a^i)/2}})
//> A more complex answer to the Ultimate Question of Life, the Universe, and Everything is still: 42

interpolate('When variable data is not present the interpolator re-prints ${data} (leaves it alone, as it should be).',{})
//> When variable data is not present the interpolator re-prints ${data} (leaves it alone, as it should be).

Note: I edited this function to replace "||" with a "??" because when the value of a variable was 0 the system thought it didn't exist and it printed the ${} notation again.

In my case I was printing ${index} where the value of index variable was 0, and the system was like, "Well, zero is nothing, so, I am just going to reprint the ${index}". I apologize for that, but now we are using the nullish coalescing operator.

The ?? operator is mindful of 0 being an actual value and my program prints 0 instead of ${index}.

I updated the code above so you will not see the offending version that used "||" instead of "??".

@makmav

This comment has been minimized.

Copy link

@makmav makmav commented Oct 16, 2020

interpolate('My ${a} is full of eels.',{a:'hovercraft'})

${true}x -> truex

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.