扩展HTML模板?

时间:2012-04-25 14:08:20

标签: javascript templates underscore.js

我正在创建一个Web应用程序框架,供我部门中的其他组使用,以标准化我们的Web应用程序的UI。它是用javascript编写的,使用HTML模板通过underscore.js。但是为了让应用程序完全可扩展,我希望他们能够在不修改源代码的情况下扩展HTML模板。


来源

templates.html

...
<script type="text/template" id="fooTemplate">
  <div class="foo">
  </div>
</script>
<script type="text/template" id="barTemplate">
  <p>Bar!</p>
</script>
...

实施

newTemplates.html

...
<!-- Only overwrite foo, not bar !-->
<script type="text/template" id="fooTemplate">
  <ul class="foo">
    <li class="bar">Blah!</li>
  </ul>
</script>
...

有没有办法直观地让用户扩展HTML模板而不强制他们覆盖文件并复制/粘贴他们没有修改的模板?

1 个答案:

答案 0 :(得分:1)

如果没有一堆服务器端处理来处理唯一性问题,您将无法使用id属性来识别模板。但您可以使用类来识别模板。

如果您将所有模板HTML文件按覆盖顺序混合在一起(首先是“基本”模板,之后是“子模板”),并使用class属性来识别模板:

<!-- templates.html -->
<script type="text/template" id="fooTemplate">
  <div class="foo">
  </div>
</script>
<script type="text/template" id="barTemplate">
  <p>Bar!</p>
</script>
<!-- newTemplates.html -->
<script type="text/template" id="fooTemplate">
  <ul class="foo">
    <li class="bar">Blah!</li>
  </ul>
</script>

然后你可以使用像

这样的东西
var foo = _.template($('.fooTemplate:last').html());
var bar = _.template($('.barTemplate:last').html());

访问您的模板。

演示:http://jsfiddle.net/ambiguous/gYHkF/


您还可以坚持使用id并尝试从newTemplates.html首先加载模板,如果找不到,则尝试回退到templates.html。如果您将模板文件加载到两个单独的变量中,但不将它们插入DOM

var $base = $('stuff from templates.html');
var $subs = $('stuff from newTemplates.html');

然后在$subs之前添加一个简单的函数来查找$base中的模板:

function tmpl(id) {
    var $t = $subs.filter('#' + id);
    if($t.length)
        return _.template($t.html());
    return _.template($base.filter('#' + id).html());
}

然后你可以这样做:

var foo = tmpl('fooTemplate');
var bar = tmpl('barTemplate');

并且正确的事情会发生。

演示:http://jsfiddle.net/ambiguous/EhhsL/

这种方法也可以很容易地缓存已编译的模板,不仅可以避免双重查找,还可以避免反复编译相同的内容:

function tmpl(id) {
    if(tmpl.cache.hasOwnProperty(id))
        return tmpl.cache[id];
    var $t = $subs.filter('#' + id);
    if($t.length)
        return tmpl.cache[id] = _.template($t.html());
    return tmpl.cache[id] = _.template($base.filter('#' + id).html());
}
tmpl.cache = { };

演示:http://jsfiddle.net/ambiguous/YpcJu/