Solución:
Puede usar una función de plantilla simple usando expresiones regulares,
var replacer = function(tpl, data) {
var re = /$(([^)]+)?)/g, match;
while(match = re.exec(tpl)) {
tpl = tpl.replace(match[0], data[match[1]])
re.lastIndex = 0;
}
return tpl;
}
usar como
var result = replacer(html, { "title" : "my title", "text" : "text is this" });
jsfiddle
detalle aquí
EDITAR
En realidad, como torazaburo mencionó en el comentario, se puede refactorizar como
var replacer = function(tpl, data) {
return tpl.replace(/$(([^)]+)?)/g, function($1, $2) { return data[$2]; });
}
jsfiddle
espero que esto ayude
Esta solución utiliza cadenas de plantillas para hacer todo lo que desee.
Esta solución tiene la ventaja de que, en contraste con la estrategia ingenua de reemplazo de plantillas basada en expresiones regulares, como se propone en otra respuesta, admite cálculos arbitrarios, como en
replacer("My name is ${name.toUpperCase()}", {name: "Bob"});
En esta versión de replacer
, usamos new Function
para crear una función que tome las propiedades del objeto como parámetros y devuelva la plantilla pasada evaluada como una cadena de plantilla. Luego invocamos esa función con los valores de las propiedades del objeto.
function replacer(template, obj) {
var keys = Object.keys(obj);
var func = Function(...keys, "return `" + template + "`;");
return func(...keys.map(k => obj[k]));
}
Definimos la plantilla usando ${}
para sustituciones (en lugar de $()
), pero escapando como ${
para evitar la evaluación. (También podríamos especificarlo como un literal de cadena regular, pero luego perderíamos la capacidad de múltiples líneas).
var html = `<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document ${title}</title> <!-- escape $ -->
</head>
<body>
<h1>Test file, ${text}</h1> <!-- escape $ -->
</body>
</html>`;
Ahora las cosas funcionan exactamente como quieres:
replacer(html, { "title" : "my title", "text" : "text is this" });
Ejemplo simple:
> replacer("My name is ${name}", {name: "Bob"})
< "My name is Bob"
A continuación, se muestra un ejemplo de campos calculados:
> replacer("My name is ${name.toUpperCase()}", {name: "Bob"})
< "My name is BOB"
o incluso
> replacer("My name is ${last ? lastName : firstName}",
{lastName: "Jones", firstName: "Bob", last: true})
< "My name is Jones"
Dado que está utilizando una cadena de plantilla ES6, puede usar una función llamada ‘cadenas de plantilla etiquetadas’. Al utilizar cadenas de plantilla etiquetadas, puede modificar la salida de una cadena de plantilla. Usted crea una cadena de plantilla etiquetada colocando una ‘etiqueta’ delante de la cadena de plantilla, la ‘etiqueta’ es una referencia a un método que recibirá las partes de la cadena en una lista como primer argumento y los valores de interpolación como argumentos restantes. La página MDN en cadenas de plantilla ya proporciona una ‘etiqueta’ de cadena de plantilla de ejemplo que podemos usar:
function template(strings, ...keys) {
return (function(...values) {
var dict = values[values.length - 1] || {};
var result = [strings[0]];
keys.forEach(function(key, i) {
var value = Number.isInteger(key) ? values[key] : dict[key];
result.push(value, strings[i + 1]);
});
return result.join('');
});
}
Usas la ‘etiqueta’ llamando a:
var tagged = template`<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document ${'title'}</title>
</head>
<body>
<h1>Test file, ${'text'}</h1>
</body>
</html>`;
Observe que la interpolación de variables usa la sintaxis ${'key'}
en lugar de $(key)
. Ahora puede llamar a la función producida para obtener el resultado deseado:
tagged({ "title" : "my title", "text" : "text is this" });
Ejecute el ejemplo de código en es6console