I use a JSON file for mon phrases so I don't have to type them and maybe in the future they can be translated. So for example in my main code I want to say You don't have the permission to use ${mand_name}
. This works perfectly fine hardcoded into my .js file but ultimately I want this to be in a JSON file, which does not allow any variables to be inserted.
Does anyone know a solution to my problem?
EDIT: Thanks for the suggestions. I guess string.replace would be my best option here. Wish there was some built in feature that'd convert variables in a JSON string to variables declared in that JS file.
I use a JSON file for mon phrases so I don't have to type them and maybe in the future they can be translated. So for example in my main code I want to say You don't have the permission to use ${mand_name}
. This works perfectly fine hardcoded into my .js file but ultimately I want this to be in a JSON file, which does not allow any variables to be inserted.
Does anyone know a solution to my problem?
EDIT: Thanks for the suggestions. I guess string.replace would be my best option here. Wish there was some built in feature that'd convert variables in a JSON string to variables declared in that JS file.
Share Improve this question edited Sep 9, 2018 at 14:31 Galaxy asked Sep 8, 2018 at 19:37 GalaxyGalaxy 331 silver badge5 bronze badges 1-
you need to have the
mandName
as a key in the JSON file and refer to it that way. suck as import fileconst name = require('./name.json')
and use the name JSON object like${name.mandName}
– MrPickles Commented Sep 8, 2018 at 19:45
6 Answers
Reset to default 3You cannot treat template string literals in JSON files like in Javascript "code". You said it yourself. But: You could use a template engine for this - or just simple String.replace()
.
Example for a template engine: https://github./janl/mustache.js
With Mustache (as an example) your code will look like this
var trans = {
mand_name: "dump"
};
var output = Mustache.render("You don't have the permission to use {{mand_name}}", trans);
With simple String.replace()
:
var str = "You don't have the permission to use %mand_name%";
console.log(str.replace('%mand_name%', 'dump'));
You can simply use placeholders. The following function replaces the placeholders with user-defined values:
const messages = {
msgName: 'Foo is :foo: and bar is :bar:!'
}
function _(key, placeholders) {
return messages[key].replace(/:(\w+):/g, function(__, item) {
return placeholders[item] || item;
});
}
Usage:
_('msgName', { foo: 'one', bar: 'two' })
// "Foo is one and bar is two!"
It's just an example. You can change the placeholders style and the function behavior the way you want!
You can use config npm module and separate your JSON files according to your environment.
./name.json
{
mand: "this is the output of 'mand'"
}
./Node.js
cost names = require('./name.json');
console.log('name === ', name.mand);
// name === this is the output of 'mand'
So the main challenge is getting separated file with string constants when some of them being parametrizable, right?
JSON format itself operates on strings(numbers, booleans, lists and hashmap) and knows nothing about substitution and parameters.
You are also unable to use template strings like you don't have permission to do ${actionName}
since template strings are interpolated immediately.
So what can you do?
Writing your own parser that takes config data from JSON file, parse a string, find a reference to variable and substitute it with value. Simple example:
const varPattern = /\${([^{}]+)}/g; function replaceVarWithValue(templateStr, params) { return templateStr.replace(varPattern, (fullMatch, varName) => params[varName] || fullMatch); }
or you can use any npm package aimed on localization like i18n so it would handle templates for you
Basically you can implement a function parse
which, given a text and a dictionary, it could replace any ocurrence of each dictionary key:
const parse = (template, textMap) => {
let output = template
for (let [id, text] of Object.entries(textMap)) {
output = output.replace(new RegExp(`\\$\{${id}}`, 'mg'), text)
}
return output
}
const textMap = {
mandName: 'grep',
foo: 'hello',
bar: 'world'
}
const parsed = parse('mand "${mandName}" said "${foo} ${bar}"', textMap)
console.log(parsed)
BTW, I would suggest you that you should use some existing string templating engine like string-template to avoid reinventing the wheel.