Синтаксис Jet

Jet — движок шаблонов. Поддерживает наследование, блоки и фильтры.

Документация разработчика

Вывод переменных

Двойные фигурные скобки выводят значение:

{{ note.Title }}
{{ user.Firstname }}

Доступ к полям структур, методам, элементам массивов и карт:

{{ user.Fullname() }}
{{ items[0] }}
{{ config["theme"] }}

Объявление переменных

{{ item := items[0] }}
{{ name := "Иван" }}

Комментарии

{* это комментарий, не попадёт в HTML *}

Условия

if / else / else if

{{ if note.Title }}
  <h1>{{ note.Title }}</h1>
{{ else }}
  <h1>Без заголовка</h1>
{{ end }}
{{ if len(items) > 0 }}
  Есть элементы
{{ else if len(items) == 0 }}
  Пусто
{{ end }}

Объявление в условии

{{ if value, ok := myMap["key"]; ok }}
  {{ value }}
{{ end }}

Тернарный оператор

{{ note.Title ? note.Title : "Заголовок не задан" }}

Циклы

range — перебор

{{ range item := items }}
  {{ item }}
{{ end }}

С индексом или ключом:

{{ range idx, item := items }}
  {{ idx }}: {{ item }}
{{ end }}

Блок else — если коллекция пуста:

{{ range item := items }}
  {{ item }}
{{ else }}
  Список пуст
{{ end }}

Срезы (slice) — начало:конец, конец не включается:

{{ range item := items[1:3] }}
  {{ item }}
{{ end }}

Операторы

Арифметика

+, -, *, /, %

{{ 1 + 2 * 3 }}
{{ (10 - 2) / 4 }}

Сравнение

==, !=, <, >, <=, >=

{{ if count > 0 }}...{{ end }}

Логические

&& (и), || (или), ! (не)

{{ if isAdmin && isActive }}...{{ end }}
{{ if !isDeleted }}...{{ end }}

Конкатенация строк

{{ "Привет, " + user.Name + "!" }}

Фильтры (пайплайны)

Фильтры преобразуют значения. Передаются через |:

{{ "ТЕКСТ" | lower }}
{{ name | upper }}

Цепочка фильтров:

{{ text | lower | trimSpace }}

Встроенные фильтры

Фильтр Описание
lower В нижний регистр
upper В верхний регистр
trimSpace Убрать пробелы по краям
split Разбить строку
replace Заменить подстроку
repeat Повторить строку
hasPrefix Начинается с...
hasSuffix Заканчивается на...

Экранирование

Фильтр Описание
html Экранировать HTML
url Экранировать для URL
unsafe / raw Без экранирования
json / writeJson Преобразовать в JSON
safeJs Безопасный вывод в JS

Функции

isset — проверка на существование

{{ isset(note.Title) ? note.Title : "Нет заголовка" }}

Работает и для проверки ключей в карте:

{{ if isset(config["theme"]) }}...{{ end }}

len — длина

{{ len(items) }}
{{ if len(text) > 100 }}...{{ end }}

Блоки

Блоки — фрагменты, которые вызываете в разных местах.

Определение блока

{{ block card(title, content) }}
  <div class="card">
    <h3>{{ title }}</h3>
    <p>{{ content }}</p>
  </div>
{{ end }}

Параметры по умолчанию:

{{ block button(text, type="primary") }}
  <button class="btn-{{ type }}">{{ text }}</button>
{{ end }}

Вызов блока

Важно: параметры передаются по имени, не по позиции. Без имени — получите false.

{* Правильно — именованные параметры *}
{{ yield card(title="Заголовок", content="Текст") }}

{* Неправильно — позиционные параметры *}
{{ yield card("Заголовок", "Текст") }}  {* title и content будут false *}

Порядок параметров неважен:

{{ yield card(content="Текст", title="Заголовок") }}  {* работает *}

Параметры с дефолтами можно не передавать:

{{ yield button(text="Отправить") }}  {* type="primary" по умолчанию *}
{{ yield button(text="Отмена", type="secondary") }}

Блок с вложенным контентом

Определение:

{{ block link(href) }}
  <a href="{{ href }}">{{ yield content }}</a>
{{ end }}

Вызов:

{{ yield link(href="https://example.com") content }}
  Перейти на сайт
{{ end }}

Рекурсивные блоки

{{ block menu() }}
  <ul>
    {{ range item := . }}
      <li>
        {{ item.Name }}
        {{ if len(item.Children) > 0 }}
          {{ yield menu() item.Children }}
        {{ end }}
      </li>
    {{ end }}
  </ul>
{{ end }}

{{ yield menu() navItems }}

Композиция шаблонов

import — импорт блоков

Загружает блоки из другого файла:

{{ import "blocks" }}
{{ yield main_layout() content }}
  ...
{{ end }}

include — вставка шаблона

Вставляет шаблон целиком с передачей данных:

{{ include "partials/user-card" user }}

Условная вставка:

{{ if ok := includeIfExists("sidebar"); !ok }}
  <p>Боковая панель не найдена</p>
{{ end }}

extends — наследование layout

Шаблон наследует layout и переопределяет блоки:

{{ extends "layouts/base" }}

{{ block title() }}Моя страница{{ end }}

{{ block content() }}
  <p>Контент страницы</p>
{{ end }}

extends должен быть первой строкой шаблона.

Полезные ссылки