У меня есть часть руля, которую я хочу включить дважды на мою страницу. Один раз как обычный HTML, который нужно проанализировать и отобразить, и один раз как экранированный HTML, который будет показан пользователю (как в документации по Bootstrap, как показано на рисунке ниже):

enter image description here

В шаблонах подчеркивания это будет просто:

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

Как я могу сделать это в руле?

Я отображаю эти файлы на сервере node.js и использую встроенную функцию партиалов (это не работает. Я не могу понять, как заставить второй выглядеть так, чтобы он избегал HTML):

    {{> examples/buttons }}
    <code>
        {{> examples/buttons }}
    </code>
3
cmcculloh 17 Дек 2015 в 19:23

5 ответов

Лучший ответ

Это можно сделать с помощью пользовательского помощника блока:

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

Зарегистрировано с помощью экспресс-руля:

// [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');

И, наконец, используется из самого шаблона руля (в некотором файле hbs, например, button-docs.hbs). @exphbs.partials должен быть пропущен, чтобы у помощника был доступ к частям (возможно, есть другой лучший способ получить доступ к этому глобальному объекту, но я этого не знаю):

    {{> examples/buttons foo="bar"}}
        <code>
{{escapedPartial @exphbs.partials "examples/buttons" foo="bar"}}
        </code>
0
cmcculloh 29 Дек 2015 в 13:50

Я часами искал решение этой проблемы. Экспресс рулевых экосистем кажется мне очень спящим в эти дни. Корень проблемы в том, что вы хотите передать тот же файл шаблона (.hbs), что и обычный текстовый файл и , в качестве интерпретируемого шаблона.

Решение, которое я придумала, не предполагает побега. Вероятно, есть способы написать помощник, который экранирует шаблон, но я рекомендую использовать fs Node для чтения файла в системе и сохранения его как локальной переменной и передачи его в функцию рендеринга приложения.

Внутри внешнего файла:

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);
	});
});
1
Interactive Llama 17 Дек 2015 в 16:37

Для этого варианта использования я смог просто использовать \:

{{> examples/buttons }}
<code>
    \{{> examples/buttons }}
</code>
-2
Anima-t3d 10 Янв 2018 в 04:26

Сравните "тайник" {{ и "тройной тайник" {{{

Handlebars HTML-экранирует значения, возвращаемые {{expression}}. если ты не хотите, чтобы Handlebars экранировали значение, используйте «тройной тайник», {{{.

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

0
gfullam 17 Дек 2015 в 16:28

Возврат частичного HTML в виде текста с помощью специального помощника

Нет собственного синтаксиса для вывода экранированного текста части, но вы можете создать помощник по выражению сделать это для вас.

В приведенном ниже примере помощник возвращает необработанный скомпилированный вывод партиала и даже позволяет вам удалить его с помощью «тройного тайника» {{{ для типичного вывода.

Обратите внимание, что синтаксис помощника не так дружелюбен, как собственный частичный синтаксис, и вы должны передать текущий контекст в качестве параметра:

{{! 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>
3
gfullam 18 Дек 2015 в 02:41