В данной статье мы разберем принцип отображения динамических данных из MySQL базы данных на некоторых HTML страницах нашего веб-приложения на Golang.

Содержание статьи

Вы научитесь:

Премиум 👑 канал по Golang

Рекомендуем вам супер TELEGRAM канал по Golang где собраны все материалы для качественного изучения языка. Удивите всех своими знаниями на собеседовании! 😎

Подписаться на канал

Уроки, статьи и Видео

Мы публикуем в паблике ВК и Telegram качественные обучающие материалы для быстрого изучения Go. Подпишитесь на нас в ВК и в Telegram. Поддержите сообщество Go программистов.

Go в ВК ЧАТ в Telegram


  • Передавать динамические данные в HTML шаблоны простым, масштабируемым и безопасным способом;
  • Использовать различные операторы и функции из пакета html/template для управления отображением динамических данных в шаблоне сайта;
  • Кэшировать шаблон, чтобы не тратить ресурсы на повторную обработку шаблона для каждого HTTP запроса;
  • Изящно обрабатывать возникшие ошибки рендеринга шаблонов во время работы;
  • Реализуем способ для передачи глобальных динамических данных на веб-страницы без повторения кода в обработчиках;
  • Создавать собственные функции для форматирования и отображения данных в HTML шаблонах.

Вывод заметок в HTML шаблоне

На данный момент обработчик showSnippet извлекает заметку models.Snippet из базы данных, а затем показывает его содержимое в виде обычного текстового HTTP ответа. Сейчас мы обновим текущий HTML шаблона, чтобы наши данные отображались на веб-странице следующим образом:

шаблоны html

Начнем с обработчика showSnippet и добавим код для рендеринга файла шаблона show.page.tmpl (которого мы создадим через минуту). Следующий код должен показаться знакомым по предыдущим урокам.

Затем нам нужно создать файл show.page.tmpl, содержащий HTML разметку для страницы отображения заметок. Но перед этим давайте немного поговорим о теории…

В ваших HTML шаблонах любые передаваемые в него динамические данные представлены символом точки . в начале.

В данном конкретном случае базовым типом точки будет структура models.Snippet. Если базовым типом точки является структура, вы можете отобразить (или получить) значение любого поля из неё, добавив точку в начале. Поскольку у структуры models.Snippet есть поле Title, можно получить заголовок заметки, указав {{.Title}} в наших шаблонах.

Создайте новый файл в ui/html/show.page.tmpl и добавьте следующую разметку:

Если вы перезапустите веб-приложение и перейдете на страницу http://127.0.0.1:4000/snippet?id=1 в браузере, вы увидите, что нужная заметка была получена из базы данных, передана шаблону, и её содержимое красиво отображено на экране.

Содержимое страницы с заметкой:

Создание сайта на Golang

Go-структура с данными для передачи в шаблон

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

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

Для этого создадим новый файл cmd/web/templates.go, содержащий структуру templateData.

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

Теперь данные нашей заметки из структуры models.Snippet переданы внутри структуры templateData. Чтобы получить данные из неё, нужно вызвать соответствующие названия полей следующим образом (файл ui/html/show.page.tmpl):

Попробуйте перезапустить приложение и обновите страницу http://127.0.0.1:4000/snippet?id=1. В браузере вы должны увидеть рендеринг той же страницы, что и раньше.

Защита от XSS-атак в Golang — Экранирование данных

Пакет html/template автоматически экранирует любые данные, находящиеся между тегами {{}}. Такое поведение помогает избежать атак с использованием межсайтовых сценариев (XSS) и поэтому мы используем именно пакет html/template вместо более простого пакета text/template.

Допустим кто-то взломал наше приложение и вместо обычного текста для заметки, он добавил туда вредоносный JavaScript код, что произойдет далее?

Пакет html\template обработает данный контент и выведет на экран пользователя следующее:

Пакет html/template также достаточно умен, чтобы выполнять экранирование в зависимости от обстоятельств. Он будет использовать соответствующие экранированные последовательности в зависимости от того, отображаются ли данные в части страницы, содержащей HTML, CSS или Javascript.

Шаблоны с вложенными шаблонами

Очень важно отметить, что при вызове одного шаблона из другого, точка . должна быть явно передана в вызываемый шаблон. Это делается через добавление данной точки в конец каждого вызова {{template}} или {{block}}.

Например:

Мы советуем выработать привычку использования точки всякий раз, когда вы вызываете шаблон с помощью {{template}} или {{block}}.

Вызов методов в шаблоне

Если у переданного в шаблон объекта есть методы, вы можете вызывать их (при условии, что они экспортируются и возвращают только одно значение — или одно значение и ошибку).

Например, если поле .Snippet.Created является типом time.Time, вы можете отобразить в шаблоне название дня недели, вызвав его метод Weekday() следующим образом:

Также, методу можно передать параметры. К примеру, вы можете использовать метод AddDate() чтобы увеличить текущее время на шесть месяцев:

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

HTML комментарии в шаблоне

Пакет html/template всегда удаляет любые HTML комментарии, которые вы оставляете в шаблонах, включая любые условные комментарии которые часто применяются фронтенд разработчиками.

Это необходимо во избежания XSS-атак при отображении динамического контента. Разрешение условных комментариев означало бы, что Go не всегда может предугадать, как браузер интерпретирует разметку на странице. Следовательно, не факт, что он сможет избежать все опасные сценарии. Для решения этой проблемы Go просто удаляет все HTML комментарии.

Скачать исходный код

В конце каждого урока вы можете скачать актуальную на данный момент версию сайта на Golang.

Скачать: snippetbox-23