Синтаксис 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 должен быть первой строкой шаблона.