Handlebars Include partial 两次,一次转义,一次渲染

Handlebars Include partial twice, once escaped and once rendered

我有一个车把部分,我想在我的页面上包含两次。一次作为正常 HTML 被解析和显示,一次作为转义 HTML 显示给用户(有点像 Bootstrap 文档,如下图所示):

在下划线模板中,它只是:

    {% examples/buttons %}
    <code>
        {%- examples/buttons %}
    </code>

如何在 Handlebars 中完成它?

我在 node.js 服务器上渲染这些文件并使用内置的 partials feature(这不起作用。我不知道如何使第二个看起来像喜欢告诉它转义 HTML):

    {{> examples/buttons }}
    <code>
        {{> examples/buttons }}
    </code>

比较 "stash" {{ 与 "triple-stash" {{{

Handlebars HTML-escapes values returned by a {{expression}}. If you don't want Handlebars to escape a value, use the "triple-stash", {{{.

http://handlebarsjs.com/#html-escaping

我花了几个小时寻找解决方案。这些天来,快速车把生态系统似乎非常休眠。问题的根源是您想要将相同的模板文件 (.hbs) 作为纯文本文件传递 并且 作为解释模板传递。

我想出的解决方案不涉及转义。可能有一些方法可以编写一个转义模板的助手,但我的建议是使用 Node 的 fs 来读取系统上的文件并将其存储为局部变量并将其传递给应用程序渲染函数。

在外部文件中:

var fs = require('fs');

var codeDir = './src/jquery/';
var exampleCode = {
 badge: {
  siteExample: fs.readFileSync(codeDir + 'badge/examples/site-example.js', 'utf8')
 }
};

module.exports = exampleCode;

app.js内:

// Render code example pages
app.get('/jquery', function (req, res) {
 var locals = {};

 res.render('jquery/', locals, function () {
  locals.code = codeExampleScripts;
  res.render('jquery/index', locals);
 });
});

这可以通过自定义块助手来完成:

// [this is in /lib/hbs-helpers.js file]
exports.escapedPartial = function (partials, partialName, data) {
     return partials[partialName](data.hash);
};

注册express-handlebars

// [this is in js file which starts the express app, probably app.js]
var expressHandlebars       = require( 'express-handlebars' );
var handlebarsHelpers       = require('./lib/hbs-helpers');

var hbs = expressHandlebars.create({
    defaultLayout: 'master',
    extname: ".hbs",
    helpers: handlebarsHelpers,
    partialsDir: "views/partials"
});

// Configuring view engine
app.engine('.hbs', hbs.engine);
app.set('view engine', '.hbs');

最后在 handlebars 模板内部使用(在某些 hbs 文件中,例如 button-docs.hbs)。 @exphbs.partials 必须通过,以便助手可以访问部分(可能有另一种更好的方法来访问这个全局,但是,我不知道):

    {{> examples/buttons foo="bar"}}
        <code>
{{escapedPartial @exphbs.partials "examples/buttons" foo="bar"}}
        </code>

Return 部分的 HTML 作为带有自定义助手的文本

没有用于输出部分文本转义内容的本机语法,但您可以创建一个 expression helper 来为您执行此操作。

在下面的示例中,助手 returns 部分的原始编译输出,甚至允许您使用 "triple-stash" {{{ 对其进行反转义以获得典型输出。

注意,helper的语法不如原生partial语法友好,必须传入当前上下文作为参数:

{{! unescaped HTML output (renders HTML as HTML) }}
{{{output "header" this}}}

{{! escaped HTML output (renders HTML as text) }}
{{output "header" this}}

$(function() {

  // Register a helper called "output"
  Handlebars.registerHelper('output', function(partial, context) {
    
    // Create compiler function for said partial
    var output = Handlebars.compile(Handlebars.partials[partial]);
    
    // Return compiled output using said context
    return output(context);
  });
  
  // Register a partial called "header"
  Handlebars.registerPartial('header', $("#partial-header").html());
  
  // Create compiler function for main template
  var template = Handlebars.compile($("#template").html());
  
  // Render compiled output as HTML to `#rendered` using provided context (JSON)
  $("#rendered").html(
    template(
      {
        "title": "My Cool Header"
      }
    )
  );

});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/handlebars.js/4.0.5/handlebars.min.js"></script>

<script id="template" type="text/x-handlebars-template">
    {{{output "header" this}}}
    {{output "header" this}}
</script>
<script id="partial-header" type="text/x-handlebars-template"> 
    <h1>{{title}}</h1>
</script>

<div id="rendered"></div>