Как выполнить глубокую компиляцию содержимого вложенных рулей?

В проекте, над которым я работаю, используется система шаблонов Handlebars.js. Он считывает содержимое и при компиляции шаблона вставляет содержимое, где это необходимо:

<div class="content">
  <p>lorem ipsum</p>

  {{{ content }}}

</div>

В этом случае handlebars скомпилирован с объектом JS, у которого есть свойство content, представляющее собой строку текста или HTML (отсюда и тройные скобки).

Однако вполне возможно, что значение содержимого (будучи текстом или HTML) может также включать код интерполяции руля:

var contentPassedToHandlebars = {
  content: '<p>{{ foobar }}</p>',
  foobar: 'foo'
};

Который в настоящее время выводит <p>{{ foobar }}</p>, но я хотел бы получить <p>foo</p>.

Есть ли в руле средства для этого вложенного содержимого или требуется специальный помощник? ({{{custom_parse content}}})?

Для контекста этого вопроса

Ситуация возникла из-за системы сборки (metalsmith), которая считывает файлы как уценку, преобразует их в HTML, прикрепляет результат к свойству content объекта file, а затем анализирует шаблон руля, который вводит file.content в его вывод. Все это, и я надеялся, что есть решение для размещения рулей или интерполяции строк в уценке, чтобы файлы уценки могли иметь доступ к тем же переменным, к которым имеют доступ шаблоны (очевидно, более глобальные значения в config.json, а не значения, связанные с файлом строящийся объект).


person Sukima    schedule 02.10.2014    source источник
comment
Руль AFAIK не имеет таких возможностей. Кроме того, было бы сложно реализовать это с помощью помощников, даже если вы это сделаете, это не похоже на лучший подход. Я думаю, вам следует сначала попробовать создать RegExp для вашего корневого шаблона и сначала заменить все последовательности {{{ VAR_NAME }}}, а затем скомпилировать результат.   -  person Jevgeni    schedule 02.10.2014


Ответы (2)


Для этого нет встроенного способа. Вам придется управлять собственным процессом предварительного рендеринга или внутренним помощником.

В качестве решения я запустил предварительный рендер перед официальным рендерингом. Хотя код не является рулем, а является частью плагина metalsmith-templates, вот решение, которое я используется.

Это примерно переводится как:

var contentPassedToHandlebars = {
  content: '<p>{{ foobar }}</p>',
  foobar: 'foo'
};

var x = Handlebars.compile(contentPassedToHandlebars.content)(contentPassedToHandlebars);
contentPassedToHandlebars.content = x;

Handlebars.compile(realTemplateSource)(contentPassedToHandlebars);
person Sukima    schedule 02.10.2014

ИЛИ используйте это:

мастерская на месте

```
index.js
var inPlace = require('metalsmith-in-place')

....
.use(inPlace(true))
.....

Теперь, если вы напишете {{> footer }}, он сделает свою работу.

person Gaurav Kumar    schedule 17.11.2017