Source
/*
** Copyright (C) 2001-2025 Zabbix SIA
**
** This program is free software: you can redistribute it and/or modify it under the terms of
** the GNU Affero General Public License as published by the Free Software Foundation, version 3.
**
** This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
** without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
** See the GNU Affero General Public License for more details.
**
** You should have received a copy of the GNU Affero General Public License along with this program.
** If not, see <https://www.gnu.org/licenses/>.
**/
/*
* Template class implements token replacement logic for strings containing HTML and tokens.
*
* The following format is used for tokens: #{token_name}.
* When found in template String, token will be replaced with value of the key "token_name" of object passed to
* evaluate function. All occurrences of tokens are replaced by values from object with HTML entities escaped.
* Token name should be prefixed with character '*' to avoid escaping of HTML entities (for example, #{*test}).
* Backslash character (\\) can be used to escape token (such tokens will not be affected).
*
* Nested object properties could be used in templated by using square bracket token syntax (for example, #{a[b][c]}).
* Previous example will look for nested value a->b->c ({'a': {'b': {'c': 'value'}}}).
*/
class Template {
/**
* @type {string}
*/
#template;
/**
* @param {string} template
*/
constructor(template) {
this.#template = template;
}
/**
* Fill template with data defined in object.
*
* @param {Object} data
*
* @return {string}
*/
evaluate(data) {
let template = this.#template;
let result = '';
while (template.length > 0) {
const match = template.match(/(^|.|\r|\n)(#\{(.*?)\})/);
if (match) {
result += template.substring(0, match.index);
result += this.#match(match, data);
template = template.substring(match.index + match[0].length);
}
else {
result += template;