我不确定外面的东西是否符合你所说的。我需要类似的东西,并认为编写一个简单的文本替换脚本会比比较现有解决方案和学习使用一个更快。
该脚本尚未准备好生产(应该进行更多测试,并且 API 很奇怪),但它应该让您了解一种可以完成的方法。
这是它的设置方式:
在文档中存储模板
模板文本存储在具有type
“text/javascript”以外的属性的脚本标记中。每个模板都有一个唯一的 id 属性。
<script id="some_template" type="text/plain">
a valid template
</script>
浏览器不应该呈现这些。允许使用任何字符(除了</script>
),无需转义。
占位符
占位符如下所示:{@some_identifier}
.
<script id="image_template" type="text/plain">
<a href="{@img_url}"><img src="{@img_url}"></a>
</script>
每个占位符将替换为:
- 从另一个模板传入的值,
- 获取模板副本时传递给 JavaScript 函数的参数,或
- 如果没有找到替换值,则为空字符串。
在另一个模板中包含一个模板
“@@
伪标签”包括当前模板中另一个模板的内容。
<script id="photo_template" type="text/plain">
<@@ image_template></@@>
<div class="photo-caption">{@caption}</div>
</script>
photo_template
包括 image_template
. 所有包含替换发生在任何占位符替换之前,photo_template
和{@img_url}
占位符也是如此{@caption}
。
包含占位符替换
这就是“包装”的来源。理想情况下,占位符几乎总是被其他模板中的内容替换,而不是在获取模板副本时传入的值。
<script id="missing_photo_template" type="text/plain">
<@@ photo_template>
<@ img_url>notfound.png</@>
</@@>
</script>
missing_photo_template
包括photo_template
,为它提供一个替代品{@img_url}
,所以missing_photo_template
只有{@caption}
占位符。
JavaScript
API 现在很烂,但基本上主命名空间at
有两个函数,txt
和node
. 第一个获取模板副本作为文本,第二个获取副本作为元素(这意味着它应该有一个根节点,与我上面的一些示例不同)。
这里是:
/**
Atrocious Templates
*/
var at = (function(){
var rTemplate = /<@@\s*(.*?)>((?:[\w\W](?!<@@))*?)<\/@@>/gm,
rOption = /<@\s*(.*?)>([\w\W]*?)<\/@>/gm,
rValue = /\{@(.*?)\}/g,
rTag = /<(\w+)/i,
rSpace = /\s+/,
templates = {},
doc = document.implementation.createHTMLDocument('');
/**
Inlcude inner templates.
@private
@param {string} m0
The full inclusion text.
@param {string} m1
The ID of the included template.
@param {string} m2
Values passed to included template.
@return {string}
*/
function includeTemplates(m0, m1, m2) {
var opts = {};
m2.replace(rOption, function(m0, m1, m2) { opts[m1] = m2; });
return txt(m1, opts, true);
}
/**
Get text contents of a template.
@private
@param {string} id
The ID of the template.
@return {string}
*/
function get(id) {
if (templates[id]) return templates[id];
var last, t = document.getElementById(id).innerHTML;
while (last != t && (last = t)) t = t.replace(rTemplate, includeTemplates);
return (templates[id] = t);
}
/**
Get a text copy of a template.
@param {string} id
The ID of the template.
@param {Object.<string|function ():string>} options
Properties of this object will replace placeholder tokens.
Each property can be either a string, or a function which
returns a string.
@param {boolean=} noStrip
By default, placeholders for which no replacement text is
found are removed. Setting this to `true` overrides that
behavior, leaving non-replaced placeholders intact.
@return {string}
*/
function txt(id, options, noStrip) {
if (!options) options = {};
return get(id).replace(rValue, function(m0, m1) {
var v = options[m1];
return noStrip && !v && m0 || v && (v.call ? v() : v) || '';
});
}
/**
Get a node copy of a template.
@param {string} id
The ID of the template.
@param {Object.<string|function ():string>} options
Properties of this object will replace placeholder tokens.
@return {string}
*/
function node(id, options) {
var text = txt(id, options),
root = text.match(rTag)[1];
doc.open; doc.write(text); doc.close();
return doc.getElementsByTagName(root)[0];
}
// exports
return { txt: txt, node: node };
}());
同样,我不建议您在生产中使用它,因为它没有经过太多测试(尽管它似乎工作正常),但希望这会给您一些关于如何实现您想要的想法的想法。