如何使用Hogan.JS从外部文件加载模板?

9
我使用 Hogan.JS 作为JavaScript模板库。它可以从外部文件加载JavaScript模板。可以在一个外部JavaScript文件中外包几个模板。
有没有人知道怎么做呢?
我有下面的代码示例:
<!DOCTYPE html>
<html>
  <head>
    <title>Hogan.JS Test</title>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <script src="js/jquery-1.9.0.min.js"></script>
    <script src="js/hogan-2.0.0.min.js"></script>
    <script id="scriptTemplate" type="text/mustache">
      <p>Your text here: {{text}}</p>
    </script>
  </head>
  <body>
    <script>
      var data = {
        text: 'Hello World'
      };

      var template = $('#scriptTemplate').html();
      var compiledTemplate = Hogan.compile(template);
      var renderedTemplate = compiledTemplate.render(data);

      var box = document.createElement('div');
      box.innerHTML = renderedTemplate;
      document.body.insertBefore(box,document.body.childNodes[0]);
    </script>
  </body>
</html>

使用ID可以调用模板,但我总是需要一个单独的内联脚本。 :-(

在外部文件中如何实现这个功能?

3个回答

28

您有两种选择来加载外部模板:

  1. 预编译模板(我认为是 Hogan.js 中最好的功能)或
  2. 使用 require.jstext 插件 来加载模板字符串。

不幸的是,Hogan.js 模板的预编译文档不存在。如果您拥有Github repo的副本,则在bin目录中有一个名为hulk的脚本可以完成此工作。它需要安装nodejs以及一些npm模块(即已安装的noptmkdirp)。

一旦您安装了nodejs和这些模块,假设您有一个名为 Test.hogan 的模板文件:

<p>Your text here: {{text}}</p>

您可以使用以下命令预编译脚本:
hulk Test.hogan

导致以下文本:
if (!!!templates) var templates = {};
templates["Test"] = new Hogan.Template({code: function (c,p,i) { var t=this;t.b(i=i||"");t.b("<p>Your text here: ");t.b(t.v(t.f("text",c,p,0)));t.b("</p>");return t.fl(); },partials: {}, subs: {  }});

将这个内容保存到名为templates.js的文件中。

现在,在您的HTML页面中,您需要加载templates.js文件,它会创建一个全局对象templates,其中编译后的模板函数被存储在键值为"Test"的位置上。由于hogan.js是编译器(而且您的模板已经预编译),您也可以省略该文件,只需包含分发中提供的template.js文件即可。

<!DOCTYPE html>
<html>
  <head>
    <title>Hogan.JS Test</title>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <script src="js/template.js"></script>
    <script src="js/templates.js"></script>
  </head>
  <body>
    <script>
      var data = {
        text: 'Hello World'
      };

      var compiledTemplate = templates['Test'];
      var renderedTemplate = compiledTemplate.render(data);

      var box = document.createElement('div');
      box.innerHTML = renderedTemplate;
      document.body.insertBefore(box,document.body.childNodes[0]);
    </script>
  </body>
</html>

注意:我在使用当前的Github存储库的主分支时遇到了一些问题,因为它生成了一个使用不同构造函数的模板,而不是2.0.0模板版本中使用的构造函数。如果您使用hulk,请确保使用位于lib文件夹中的template.js文件。
或者,您可以使用require.js和文本插件。下载它们并将它们保存到您的js文件夹中。然后,您需要添加一个require语句来加载模板文本:
<!DOCTYPE html>
<html>
  <head>
    <script src="js/hogan-2.0.0.js"></script>
    <script src="js/require.js"></script>
  </head>
  <body>
    <script>
      var data = {
        text: 'Hello World'
      };

      require(['js/text!Test.hogan'], function(testHoganText) {
        // testHoganText contains the text of your template
        var compiled = Hogan.compile(testHoganText);
        var renderedTemplate = compiled.render(data);

        var box = document.createElement('div');
        box.innerHTML = renderedTemplate;
        document.body.insertBefore(box,document.body.childNodes[0]);
      });
    </script>
  </body>
</html>

5
太棒了!非常感谢。这应该写在官方的Hogan.js文档里! - Benny Code
1
只是一点小提示。编译模板中的 '!!!' 是什么意思?我似乎找不到任何解释。 - James Thomas
2
@JamesThomas 中的 ! 表示 逻辑非。三个连续的 ! 会将_假值_(0、false、""、null、undefined 和 NaN) 转换为 true,而_真值_(true、Object、Function、Array、非零数、非空字符串) 则变成 false。这仅是用于检查变量 templates 是否存在... 如果一个未定义的对象无法添加属性。 - BernaMariano

5

如果您不使用node或者不想依赖于require.js,还有另外一种方法可以很好地解决问题。

您可以简单地使用jQuery $ .get 来获取模板文件的路径。一个示例看起来像这样:

$.get('templates/book.hogan', function(templates){
            var extTemplate = $(templates).filter('#book-tpl').html();
            var template = Hogan.compile(extTemplate);
            var rendered = template.render(datum);
            $('.marketing').append(rendered);
});

模板可以简单地是一个 .html 文件(我只使用 .hogan),模板中的所有 html 应该用一个带有唯一 id 的 script 标签包装起来,这样你就可以在这里获取 id。Datum 来自于 on('typeahead:selected'),但这并不重要,我只是想解释一下,因为它在代码中没有其他参考。

0

我曾经有同样的问题,但最终采用了不同于Phuong的方法,我想分享一下。

在服务器端,我使用以下脚本编译模板并将其保存到文件中:

// template will be a string
var template = hogan.compile(
    '<span>{{text}}</span>',
    { asString: true }
);

// prepare the content of the file we are about to create
var content =
    'if(!templates) var templates = {};' +
    'templates.example = ' + template + ';';

// write to a file that will be called by the client
fs.writeFile('compiledTemplate.js', content, function(err){
    if(err){ console.log('Oops !') }
});

而在客户端,我会做:

<!DOCTYPE html>
<html>
  <head>
    <script src="js/hogan-2.0.0.js"></script>
    <script src="js/compiledTemplate.js"></script>
  </head>
  <body>
    <script>

      var data = {
        text: 'Hello World'
      };

      var template = new Hogan.Template(templates.example),
          html = template.render(data);

      var box = document.createElement('div');
      box.innerHTML = html;
      document.body.insertBefore(box,document.body.childNodes[0]);

    </script>
  </body>
</html>

希望能对你有所帮助!


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接