Документация Толоки

Выражения и хелперы

Обратите внимание

Документация на русском языке может быть устаревшей. Самые последние изменения доступны в документации на английском языке.

Примечание

Справочник по настройке интерфейса описывает работу редактора HTML/JS/CSS. Вы также можете попробовать создать интерфейс задания в Конструкторе шаблонов.

Handlebars — это шаблонизатор, который упрощает создание HTML за счет использования шаблонов.

Шаблоны выглядят как обычный HTML-код, в который добавлены выражения Handlebars. Когда шаблон выполняется, выражения заменяются значениями входных параметров.

По умолчанию в проект подключается библиотека toloka-handlebars-templates. Она содержит набор удобных компонентов и предоставляет классы TolokaHandlebarsTask и TolokaHandlebarsTaskSuite, которые дополняют и расширяют базовые классы [TolokaTask](../js/task.md) и [TolokaTaskSuite](../js/tasksuite.md).

Выражения

Выражения заключены в двойные фигурные скобки. В этом случае их значение автоматически экранируется.

<input type="text" placeholder="{{i18n.hint}}" name="{{concat "field_" name}}" value="{{value}}">

Если нужно вывести неэкранированное значение вы можете:

  • Указать его в тройных скобках: {{{raw}}}

  • Написать свой хелпер, который будет возвращать значение в неэкранированном виде: return new Handlebars.SafeString(value)

    Внимание

    Учтите, что это небезопасно! Всегда проверяйте все входные данные, которые вы отображаете в шаблоне. Экранировать данные в хелпере можно с помощью метода Handlebars.Utils.escapeExpression .

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

Например, чтобы из кода в формате JSON

{
    "id": 123,
    "link": {
        "title": "<b>Toloka</b>",
        "url": "https://toloka.ai"
    }
}

подтянуть значения вложенных в link параметров title и url, укажите путь к ним через точку:

id: {{id}}<a href="{{link.url}}">{{link.title}}</a>

Комментарии тоже являются выражениями Handlebars: {{!комментарий}} или {{!-- комментарий --}}.

Хелперы

Хелперы — это функции, которым можно передать любое количество выражений. После обработки результата они возвращают HTML-код.

Свой хелпер можно зарегистрировать с помощью метода Handlebars.registerHelper. Например:

Хелпер для экранирования параметра title из приведенного выше кода в формате JSON:

Handlebars.registerHelper('escape', (title, url) => new Handlebars.SafeString(`<a href="${Handlebars.escapeExpression(url)}">${Handlebars.escapeExpression(title)}</a>`));

Вызов хелпера:

{{escape link.title link.url}}

Результат — HTML-код верстки, в которой будет экранирован параметр title, а добавленный в хелпере тег останется без изменений:

<a href="https://toloka.ai">&lt;b&gt;Toloka&lt;/b&gt;</a>

Хелперам можно передавать на вход другие хелперы, для этого их нужно заключить в круглые скобки:

{{or (equal title "Toloka") (equal title "Google")}}

Примечание

Прежде чем создавать собственный хелпер Handlebars, поищите нужный:

Блочные хелперы

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

Чтобы указать, что вы вызываете блочный хелпер, добавьте в его имя решетку: {{#if}}. В отличие от обычного хелпера, блочный хелпер нужно закрыть. Закрывается блочный хелпер так же, как и обычный тег: {{/if}}.

В Handlebars уже есть встроенные блочные хелперы: If, Unless, Each, With.

Подробнее про блочные хелперы

If

Вывод блока по условию. Если аргумент этого хелпера вернет значение false, то блок внутри хелпера не будет выполнен:

{{#if (equal id "123")}}
    ... {{!Блок кода только для id 123}}
{{else}}
    ... {{!Блок кода для всех остальных значений}}
{{/if}}

Unless

Хелпер обратный хелперу if. Блок будет выведен, если аргумент вернет значение false.

{{#unless (equal id "123")}}
    ... {{!Блок кода для всех значений id, отличных от 123}}
{{else}}
    ... {{!Блок кода только для id 123}}
{{/unless}}

Each

Хелпер для перебора списков. Чтобы обратиться к текущему элементу внутри списка, используйте this.

Примечание

Для обращения к элементу не из текущего блочного контекста необходимо перейти на вышестоящий уровень, используя ../

Например, для списка

{
    "id": 123,
    "links": [
        { "url": "https://toloka.ai", "title": "Toloka" },
        { "url": "https://google.com", "title": "Google" }
    ]
}

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

{{#each links}}
    ID: {{../id}}
    <a href="{{this.url}}">{{this.title}}</a>
{{/each}}

Внутри блока Each доступны вспомогательные выражения:

  • {{@key}} — название текущего ключа;
  • {{@index}} — текущий индекс;
  • {{@first}} — true, если это первый элемент массива;
  • {{@last}} — true, если это последний элемент массива.

Для приведенного в предыдущем примере списка хелпер

{{#each links}}
    Глобальный ID: {{../id}}
    {{@index}}: <a href="{{this.url}}">{{this.title}}</a>
    {{#unless @last}}<hr>{{/unless}}
{{/each}}

выведет ссылки, при этом:

  • ссылки будут пронумерованы;
  • после каждой ссылки, кроме последней, будет добавлен горизонтальный разделитель.

With

Позволяет перепривязать контекст.

Например, для кода

{
    "id": 123,
    "link": {
        "title": "<b>Toloka</b>",
        "url": "https://toloka.ai"
    }
}

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

ID: {{id}}
{{#with link}}
    <a href="{{url}}">{{title}}</a>
{{/with}}

Повторное использование шаблонов (partials)

Partials позволяют переиспользовать целые секции кода. Это обычные шаблоны, которые могут вызываться другими шаблонами. Например:

Необходимо в нескольких местах вывести однотипную верстку:

<h3>Поле</h3>
{{field type="input" name="field_name"}}

Чтобы избежать копирования кода, можно зарегистрировать новый partial:

Handlebars.registerPartial('formInput', '<h3>{{fieldTitle}}</h3>{{field type="input" name=fieldName}}');

Вызов шаблона для вставки верстки в форму:

{{> formInput fieldTitle="Поле 1" fieldName="my_field"}}
<p>Параграф с текстом</p>
{{> formInput fieldTitle="Поле 2" fieldName="some_other_field"}}

Результат:

<h3>Поле 1</h3>
{{field type="input" name="my_field"}}
<p>Параграф с текстом</p>
<h3>Поле 2</h3>
{{field type="input" name="some_other_field"}}