Как бы вы встраивали атомарные части в объект данных шаблона - PullRequest
0 голосов
/ 25 мая 2018

Я использую руль и собираюсь с Йоманом и Глотком.

Я хочу иметь некоторые глобализированные партиалы, которые могут быть вложены или вставлены в другой партиал, вызывая его в контексте объекта данных.

Простым примером этого будет список ссылок, на которые я мог бы ссылаться внутри контента по всему сайту.Причиной этого является необходимость последовательности.Если, например, если у меня есть ссылка в тексте на странице, на которую я ссылаюсь 15 раз по всему веб-сайту, но потом понимаю, что мне нужно добавить товарный знак или изменить текст, я хочу обновить ее один раз, а не 15 раз.

Это пример того, что я хочу сделать.Определите глобальные данные в файле json:

links.json

{
  "apple": {
    "linktext": "apple",
    "target": "_blank",
    "href": "http://www.apple.com"
  },
  "blog-article-foo-bar": {
    "linktext": "foo bar",
    "href": "http://www.foobar.com"
  },
  "dell": {
    "linktext": "dell",
    "target": "_parent",
    "href": "http://www.dell.com"
  }
}

Создание частичного из этого содержимого с использованием простого или сложного шаблона:

links.hbs

<a href="{{href}}" {{#if target}}target="{{target}}"{{/target}}>{{linktext}}</a>

И сможете встроить это частичное в другое, ссылаясь на него каким-то образом.Это не сработало, но я читал о пользовательских помощниках, но не могу понять, как мне перехватить частичное и связать его с другим частичным.

text.json

{
  "text": "If you need a computer, go to {{> link link.apple}}."
}

text.hbs

<p>
{{text}}
</p>

compiled.html

<p>
If you need a computer, go to <a href="http://www.apple.com" target="_blank">apple</a>.
</p>

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

Ответы [ 2 ]

0 голосов
/ 14 июня 2018

Спасибо за пример @doowb, ваш код работал, но не за то, что я пытался сделать.Я действительно хотел что-то более сложное, но я упростил свой вопрос, не зная, что это будет проблемой.Код, который вы предоставили, работал (я думаю, после небольшой настройки) для простого рендеринга шаблона, но мои шаблоны используют такие помощники, как #each и #if, которые и вызвали проблему.Где помощники были в моем шаблоне, я получил асинхронные заполнители.Например: <a $ASYNC$1$3...> Позже я узнал, что это связано с тем, как отображаются частичные данные.Понимание того, что привело меня к подвыражениям и приведенному ниже решению.

Сохраняя мой пример выше с некоторыми изменениями, я смог объединить партиалы.

Во-первых, я упростил заполнитель в text.json, по сути, до уникального идентификатора, вместо того, чтобы пытаться отрисовывать частичное там.

В шаблоне hbs, который я рендерил, например,страницу или что-то еще, я включил помощник вставки с 3 аргументами.Первые два являются подвыражениями, каждое из которых возвращает сглаженные частичные значения в виде строк.Ключевым моментом здесь является то, что подвыражения обрабатывают и возвращают результат перед завершением текущего процесса с помощью помощника.Таким образом, два сплющенных шаблона затем отправляются помощнику вместе с заполнителем для поиска.

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

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

Первый аргумент

(partial "link" link.apple)

Возвращает

'<a href="http://www.apple.com" target="_blank">apple</a>'

SecondАргумент

(partial "text" text.text-example)

Возвращает

'<p class="text font--variant">If you need a computer, go to {{linkToApple}}.</p>'

Третий аргумент

'linkToApple'

text.json

{
    "text-example": {
        "elm": "quote",
        "classes": [
            "text",
            "font--variant"
        ],
        "text": "If you need a computer, go to {{linkToApple}}."
    }
}

text.hbs

 <{{elm}} class="{{#eachIndex classes}}{{#isnt index 0}} {{/isnt}}{{item}}{{/eachIndex}}">{{text}}</{{elm}}>

compile.hbs

 {{insert (partial "link" link.apple) (partial "text" text) 'linkToApple' }}

compile.html

 <p class="text font--variant">If you need a computer, go to <a href="http://www.apple.com" target="_blank">apple</a>.</p>

gulpfile.js

app.helper('insert', function(child, parent, name) {
    const merged = parent.replace(new RegExp('\{\{(?:\\s+)?(' + name + ')(?:\\s+)?\}\}', 'g'), child);
    const html = new handlebars.SafeString(merged);
    return html;
});

Надеюсь, это поможет кому-то еще.Я знаю, что это может использовать улучшения, я постараюсь обновить его, когда вернусь к очистке файла gulp.

0 голосов
/ 26 мая 2018

Есть некоторая информация о помощниках руля в их документах , но не так много.

Поскольку вы пытаетесь использовать синтаксис руля в значении свойства в контексте (например,text), руль не будет отображать значение, так как он уже отображает шаблон.Вы можете создать свой собственный помощник, который будет отображать значение следующим образом:

Handlebars.registerHelper('render', function(template, options) {
  // first compile the template
  const fn = Handlebars.compile(template);

  // render the compiled template passing the current context (this) to
  // ensure the same context is use
  const str = fn(this);

  // SafeString is used to allow HTML to be returned without escaping it
  return new Handlebars.SafeString(str);
});

Тогда вы будете использовать помощник в своих шаблонах следующим образом:

{{render text}}
...