Шпаргалка по конвейерам и функциям в html/template (Go)
Конвейеры позволяют последовательно применять функции к данным в шаблонах.
Синтаксис:
{{value | function1 | function2 | ...}}
Примеры:
<!-- Простой конвейер -->
<p>{{.Name | upper}}</p>
<!-- Множественные функции -->
<p>{{.Title | trim | lower | trunc 50}}</p>
<!-- С аргументами -->
<p>{{.Date | format "2006-01-02"}}</p>
<!-- Вложенные конвейеры -->
<p>{{.Description | trunc 100 | html}}</p>
Встроенные функции
1. Строковые функции
{{"hello" | title}} <!-- Hello -->
{{"HELLO" | lower}} <!-- hello -->
{{"hello" | upper}} <!-- HELLO -->
{{" hello " | trim}} <!-- hello -->
{{"hello" | repeat 3}} <!-- hellohellohello -->
2. HTML-функции
{{"<script>" | html}} <!-- Экранирование HTML -->
{{"<b>safe</b>" | html}} <!-- <b>safe</b> -->
{{"<b>safe</b>" | safeHTML}} <!-- <b>safe</b> (без экранирования) -->
3. Функции для коллекций
{{len .Items}} <!-- Длина массива/слайса/мапы -->
{{index .Users 0}} <!-- Первый элемент -->
{{index .Map "key"}} <!-- Значение по ключу -->
{{slice .List 1 3}} <!-- Подслайс -->
4. Логические функции
{{if eq .A .B}}...{{end}} <!-- Равно -->
{{if ne .A .B}}...{{end}} <!-- Не равно -->
{{if lt .A .B}}...{{end}} <!-- Меньше -->
{{if le .A .B}}...{{end}} <!-- Меньше или равно -->
{{if gt .A .B}}...{{end}} <!-- Больше -->
{{if ge .A .B}}...{{end}} <!-- Больше или равно -->
{{if and .A .B}}...{{end}} <!-- Логическое И -->
{{if or .A .B}}...{{end}} <!-- Логическое ИЛИ -->
{{if not .A}}...{{end}} <!-- Логическое НЕ -->
5. Математические функции
{{add 1 2}} <!-- 3 -->
{{sub 5 2}} <!-- 3 -->
{{mul 3 4}} <!-- 12 -->
{{div 10 2}} <!-- 5 -->
{{mod 10 3}} <!-- 1 -->
6. Функции форматирования
{{printf "%s - %d" .Name .Age}} <!-- Форматированная строка -->
{{.Price | printf "$%.2f"}} <!-- Форматирование числа -->
{{.Date | date "2006-01-02"}} <!-- Форматирование даты -->
Пользовательские функции
Регистрация функций:
funcMap := template.FuncMap{
"upper": strings.ToUpper,
"trunc": func(s string, max int) string {
if len(s) > max {
return s[:max] + "..."
}
return s
},
"add": func(a, b int) int { return a + b },
"contains": strings.Contains,
"now": time.Now,
}
tmpl := template.New("").Funcs(funcMap)
Использование в шаблоне:
{{.Title | trunc 50 | upper}}
{{add .Value 10}}
{{if contains .Description "important"}}Important!{{end}}
{{now | date "2006-01-02"}}
Примеры сложных конвейеров
1. Обработка текста
{{.UserComment | trim | trunc 200 | html}}
2. Форматирование данных
{{.CreatedAt | date "02.01.2006" | printf "Created: %s"}}
3. Работа с коллекциями
{{range .Items | sortBy "Name" | limit 10}}
{{.Name | upper}}
{{end}}
4. Условные конвейеры
{{if .Price | gt 100}}
<p class="expensive">{{.Price | printf "$%.2f"}}</p>
{{else}}
<p>{{.Price | printf "$%.2f"}}</p>
{{end}}
Полезные комбинации
Безопасный вывод HTML:
{{.UserContent | sanitizeHTML | safeHTML}}
Форматирование денежных значений:
{{.Amount | div 100 | printf "$%.2f"}}
Сортировка и фильтрация:
{{range .Products | filter "category" "electronics" | sortBy "price"}}
{{.Name}} - {{.Price | printf "$%.2f"}}
{{end}}
Ограничения
- Функции должны возвращать только одно значение (и опционально ошибку)
- Невозможно передавать функции как аргументы
- Нет поддержки сложных операций с каналами
- Автоматическое экранирование применяется к конечному результату
Лучшие практики
- Выносите сложную логику в Go-код, а не в шаблоны
- Используйте конвейеры для читаемости, но не переусердствуйте
- Документируйте пользовательские функции
- Тестируйте шаблоны с разными входными данными
- Избегайте побочных эффектов в функциях