У меня есть часть руля, которую я хочу включить дважды на мою страницу. Один раз как обычный HTML, который нужно проанализировать и отобразить, и один раз как экранированный HTML, который будет показан пользователю (как в документации по Bootstrap, как показано на рисунке ниже):
В шаблонах подчеркивания это будет просто:
{% examples/buttons %}
<code>
{%- examples/buttons %}
</code>
Как я могу сделать это в руле?
Я отображаю эти файлы на сервере node.js и использую встроенную функцию партиалов (это не работает. Я не могу понять, как заставить второй выглядеть так, чтобы он избегал HTML):
{{> examples/buttons }}
<code>
{{> examples/buttons }}
</code>
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>
Я часами искал решение этой проблемы. Экспресс рулевых экосистем кажется мне очень спящим в эти дни. Корень проблемы в том, что вы хотите передать тот же файл шаблона (.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);
});
});
Для этого варианта использования я смог просто использовать \
:
{{> examples/buttons }}
<code>
\{{> examples/buttons }}
</code>
Сравните "тайник" {{
и "тройной тайник" {{{
Handlebars HTML-экранирует значения, возвращаемые
{{expression}}
. если ты не хотите, чтобы Handlebars экранировали значение, используйте «тройной тайник»,{{{
.
http://handlebarsjs.com/#html-escaping
Возврат частичного 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>
Похожие вопросы
Новые вопросы
javascript
По вопросам программирования на ECMAScript (JavaScript / JS) и его различных диалектах / реализациях (кроме ActionScript). Включите все соответствующие теги в свой вопрос; например, [node.js], [jquery], [json] и т. д.