I have a string received from an editor, which includes HTML tags, like this:
const htmlString = "<div>Account <span contenteditable="false">{{account}}</span></div>.
<div>Hello <span contenteditable="false">{{hello}}</span></div>"
In this content, there are two variables with the format {{account}} and {{hello}}.
In my database, I store variable data in the format { key: string, value: string, isDefault: boolean }:
[
{ "key" : "account", "value" : "", "isDefault" : true, },
{ "key" : "hello", "value" : "Hello everyone", "isDefault" : false }
]
First, I use a function to remove HTML tags:
const blockTags = /<(div|h1|h2|h3|h4|h5|h6|p|ul|ol|li|br)[^>]*>/gi;
const inlineTags = /</?(span|a|strong|em|b|i|u)[^>]*>/gi;
let content = htmlString.replace(blockTags, 'n').replace(/</(div|h1|h2|h3|h4|h5|h6|p)>/gi, 'n');
content = content.replace(inlineTags, '');
content = content.replace(/<[^>]+>/g, '');
content = content.replace(/ns*n/g, 'n').trim();
Then, I extract the variables:
const variables = (content.match(/{{(.*?)}}/gi) || []).map((item) => item.replace(/{{|}}/g, ''));
Finally, I use a function to replace all variables with their corresponding values from the database, if variable is default (isDefault = true), i replace by dynamic value based on config by my system rule:
const objVariables = variables.reduce((acc, { key, value, isDefault }) => {
acc[key] = { value, isDefault };
return acc;
}, {});
const result = content.replace(/{{(.*?)}}/g, (match, variable) => {
const variableData = objVariables[variable];
if (variableData && variableData.isDefault) {
if (variable === "account") {
return "ACCOUNT_NAME";
}
}
return variableData ? variableData.value : match;
});
I want to replace all variables in the HTML string with the values stored in the database, but I think my code isn’t the best solution and may be slow. I’m looking for an optimized solution or any suggestions.
2
Answers
I think you should just iterate over your variables and replace if they’re found in the string… There’s no need to strip tags.
EDIT:
Note that if you want to save your result with HTML, then this is the best option because it can also parse the variables in the HTML attributes like
<div id="account-{{account}}">
. Also, regardless of how the string is obtained, the code below works over a string, not the HTML itself.Note that in the example above the html was not even touched.
EDIT: Updated Answer
If you want only the text fragments (stripping all HTML tags), you can achieve almost the same way as the above function. See below:
But, if you want to retain the HTML (untouched) and just change the text fragments, you can do as below: