Thor Correia
Thor Correia

Reputation: 1309

JavaScript user defined template literal formatting from object

I'd like to allow a user to define a template which is interpolated from an object. For example, I have the object:

const desc = {
    reagent: 'NaOH',
    mass: '25.6g',
};

I'd like the user to be able to define their own format string, such as '${mass} of ${reagent}', such that I can call some format(formatStr, desc) to obtain '25.6g of NaOH'.

Is this type of behavior built in?

Upvotes: 0

Views: 494

Answers (2)

Phil
Phil

Reputation: 3562

If you don't mind using a well-known utility library, then Lodash has a pretty comprehensive template engine built into it.

https://lodash.com/docs/4.17.15#template

Taken from their documentation:

// Use the "interpolate" delimiter to create a compiled template.
var compiled = _.template('hello <%= user %>!');
compiled({ 'user': 'fred' });

// => 'hello fred!'

// Use the ES template literal delimiter as an "interpolate" delimiter.
var compiled = _.template('hello ${ user }!');
compiled({ 'user': 'pebbles' });

// => 'hello pebbles!'

You can also specify your own custom delimiter:

// Use custom template delimiters.
_.templateSettings.interpolate = /{{([\s\S]+?)}}/g;
var compiled = _.template('hello {{ user }}!');
compiled({ 'user': 'mustache' });

// => 'hello mustache!'

If bundle size is a concern you can opt to only install the template method from Lodash: https://www.npmjs.com/package/lodash.template

Upvotes: 1

Thomas
Thomas

Reputation: 12637

As long as it's just insert field XY and no computation in there, it's fairly simple to build:

const desc = {
    reagent: 'NaOH',
    mass: '25.6g',
};

const formatStr = '${mass} of ${reagent}';

function format(tpl, args){
  return tpl.replace(/\$\{[^\}]+\}/g, (m) => args[m.slice(2, -1).trim()]);
}

console.log(format(formatStr, desc));

if you want to parse these placeholder and do computation in there, we're moving into the realm of evil().

Upvotes: 1

Related Questions