Истории успеха наших клиентов — лучшие проекты
Вход/ Регистрация

Как использовать шаблоны в Go

4560
13 минут чтения
Средний рейтинг статьи: 3.7

Golang на «своем борту» несет мощный универсальный шаблонизатор, позволяющий динамически формировать вывод как текстовой информации (например, электронное письмо, документ или просто консольная команда), так и целых веб-страниц.

Шаблонизация в Go состоит из двух базовых пакетов — у каждого свое предназначение:

  • text/template
  • html/template

Важно отметить, что оба пакета имеют абсолютно идентичный интерфейс, однако второй автоматически защищает вывод HTML от определенных видов атак — например, от injections.

Преобразование Go-шаблона в итоговый вывод выполняется за счет применения к шаблону соответствующей структуры данных. Входной текст для Golang шаблона представляется в любом формате в кодировке UTF-8.

VDS и VPS

Гибкие виртуальные серверы с почасовым
биллингом по всему миру: Россия, Азия и Европа.

Сущности шаблона

Используемый шаблон, как правило, привязывается к определенной структуре данных (например, struct), данные из которой будут появляться внутри шаблона.

Поэтому, любой шаблон формально состоит 3 типов базовых сущностей, которые «вынимают» из него нужные переменные и подставляют в вывод.

Действия (Actions)

Это фрагменты текста, заключенные в фигурные скобки {{ }}, в которых выполняется вычисление или подстановка некоторых данных. Именно за счет них текст внутри шаблона по своему наполнению становится динамическим.

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

Условия (Conditions)

К условиям относятся классические конструкции if-else, которые используются непосредственно внутри шаблона. Благодаря условиям можно добавлять или убирать из конечного вывода целые текстовые блоки, что существенно увеличивает возможности шаблонизации и гибкость генерации контента.

Циклы (Loops)

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

Управление шаблонами

Непосредственно в самом Go есть 3 наиболее часто используемые функции для управления шаблонами:

  • New. Создает новый шаблон, который впоследствии нужно будет определить.
  • Parse. Анализирует переданную строку, содержащую текст шаблона, после чего возвращает уже готовый к использованию шаблон.
  • Execute. Выполняет готовый шаблон (который прошел этап парсинга), применяя к нему указанную структуру данных, после чего записывает результат в заданную переменную

Кстати, еще существует функция ParseFiles для обработки не строки с содержимым шаблона, а целых файлов.

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

    

«Скомпилированный» с помощью функции Parse шаблон можно использовать повторно, но уже с данными из другой структуры. Например, вы могли бы продолжить функцию main из кода выше:

    

Обратите внимание, что внутри шаблона в фигурных скобках указываются переменные структуры, которая была передана в шаблон при его выполнении. При этом имя переменной указывается через точку, а название самой структуры как бы опускается:

    

Кстати, внутри шаблона можно напрямую обратиться к данным, которые были переданы при выполнении:

    

Особенности синтаксиса шаблонов

Статический текст

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

    

Статический текст внутри «Действия» (фигурных скобок)

Обычный статический текст можно усложнить дополнительными данными:

    

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

    

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

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

    

Как и с текстом, с числами тоже можно использовать маркеры обрезки:

    

Шаблонные переменные

Golang позволяет определять особые переменные, доступные только внутри шаблона.

Как и в самом Go, переменная сначала определяется с указанием имени и значения, а уже потом используется. Определение внутренней переменной происходит с помощью знака доллара:

    

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

Условные выражения

В шаблонах Go есть возможность ветвления на основе какой либо логики за счет классических для всех языков программирования условных операторов if / else:

    

В этом примере используется функция eq (equal), которая сравнивает переданное в шаблон значение (к которому мы обращаемся через точку) со строкой hello.

Также обратите внимание, что каждое ветвление завершается оператором end.

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

    

Циклы

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

    

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

    

В этом примере добавляются две новые переменные, которые обновляются каждую итерацию цикла — индекс и значение элемента.

Перед каждым элементом мы выводим запятую с пробелом, но только в том случае, когда индекс ($index) не равен нулю.

Шаблонные функции

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

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

    

В этом примере мы нарочно переименовали Go-функцию manipulate внутри шаблона в do_manipulation — если функционал языка позволяет, то почему бы это не сделать?

В любом случае, могли бы использовать и оригинальное название функции, просто продублировав его:

    

Работа с HTML-шаблонами в Go

Как уже было сказано ранее, в Go есть дополнительный пакет для работы с шаблонами на HTML — html/template.

Использование этого пакета, в отличие от стандартного text/template, защищает приложения от атак межсайтового скриптинга (XSS), поскольку Go предотвращает ввод каких-либо данных во время рендеринга.

Соответственно, импорт пакетов немного видоизменяется:

    

Пакет net/http потребуется для запуска HTTP-сервера на локальной машине, который необходим для теста дальнейшего примера.

Файл шаблона с HTML-разметкой

Лучшей практикой было бы хранение шаблона в отдельном файле. В нашем случае мы создадим файл с оригинальным расширением .html, хотя в своих проектах вы можете использовать абсолютно любое расширение — Golang не накладывает никаких ограничений.

Кстати, файл назовем классическим именем — index.html:

    

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

Теперь напишем минимальный Golang-код, запускающий HTTP-сервер и отправляющий результат выполнения шаблона в качестве ответа на любые запросы к серверу:

    

Подготовили для вас выгодные тарифы на облачные серверы

Cloud MSK 15

477 ₽/мес

Процессор
1 x 3.3 ГГц
Память
1 ГБ
NVMe
15 ГБ
Канал
1 Гбит/с
Публичный IP
Cloud MSK 30

657 ₽/мес

Процессор
1 x 3.3 ГГц
Память
2 ГБ
NVMe
30 ГБ
Канал
1 Гбит/с
Публичный IP

Заключение

Итак. Язык программирования Go предлагает встроенную поддержку для создания динамического контента или для отображения настраиваемого вывода — шаблоны.

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

Сама реализация предполагает несколько вариантов использования:

  • text/template
  • html/template

Помните, что любой шаблон проходит 3 стадии формирования, каждая из которых обеспечивается соответствующей функцией:

  • New. Создание шаблона
  • Parse. Анализ (парсинг) шаблона.
  • Execute. Выполнение шаблона. При этом эта стадия может иметь неограниченное число повторений.

Кстати, подробную информацию о доступных функциях и способах использования можно найти в официальной документации Golang — на страницах text/template и html/template соответственно.

4560
13 минут чтения
Средний рейтинг статьи: 3.7

Читайте также

Хотите внести свой вклад?
Участвуйте в нашей контент-программе за
вознаграждение или запросите нужную вам инструкцию
img-server