Зарегистрируйтесь, чтобы продолжить обучение

Шаблонизация в Go Веб-разработка на Go

Представим, что мы разрабатываем видео-платформу, и нужно реализовать страницу со списком доступных фильмов. Страницы для браузера приходят с веб-приложения на Go. В этом случае нужно понять, как организовать хранение контента страниц, и как в них вставлять изменяющиеся данные, например, список фильмов.

В этом уроке мы рассмотрим, как работать с шаблонами HTML-страниц в Go-приложениях. Мы научимся хранить, подставлять динамические значения и возвращать в браузер готовые HTML-страницы.

Формирование HTML-страниц в веб-приложении

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

Когда пользователь заходит на веб-сайт, происходят следующие действия до отображения контента в веб-браузере:

  1. Веб-браузер отправляет GET HTTP-запрос по адресу веб-сайта
  2. Веб-приложение, ответственное за обработку запросов на этом адресе, формирует HTML-код и отправляет его в теле HTTP-ответа
  3. Веб-браузер получает HTML-код, анализирует и отображает его

set

HTML-страницы бывают двух типов:

  • Статические
  • Динамические

Статические HTML-страницы не меняются от запроса к запросу. Например, страница с информацией о компании. Такие страницы формируются один раз и хранятся на сервере. Когда пользователь заходит на сайт, веб-приложение отправляет ему HTML-код страницы без внесения изменений.

Динамические HTML-страницы имеют изменяющийся контент. Например, страница с фильмами в видео-платформе зависит от фильмов, которые хранятся в хранилище этого веб-приложения. Когда пользователь заходит на сайт, веб-приложение берет шаблон HTML-страницы, подставляет актуальный список фильмов и отправляет HTML-код пользователю. Таким образом, конечный HTML-код постоянно меняется в зависимости от количества фильмов в хранилище.

Работа с шаблонами и динамическим контентом — это распространенная задача в веб-разработке, поэтому существуют специальные инструменты для работы с ними. Такие инструменты называют шаблонизаторами. Рассмотрим подробнее, как выглядит работа шаблонизатора с шаблонами HTML-страниц.

Как работают шаблонизаторы

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

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

<!DOCTYPE html>
<html>
<body>

<h1>My Profile</h1>
<p>Name: {{.name}}</p>
<p>Email: {{.email}}</p>

</body>
</html>

На странице есть специальные места для вставки динамического контента. Такие места выделены двойными фигурными скобками. Например, {{.name}} означает место для вставки имени пользователя. Это специальный синтаксис для шаблонизатора в Go. Перед тем как отправить такой шаблон пользователю, веб-приложение заменит {{.name}} на имя текущего пользователя.

Например, если наше имя — John, а почта — john@doe.com, то после обработки веб-приложение вернет следующий HTML-код:

<!DOCTYPE html>
<html>
<body>

<h1>My Profile</h1>
<p>Name: John</p>
<p>Email: john@doe.com</p>

</body>
</html>

Использование шаблонизатора дает следующие преимущества:

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

Мы рассмотрели работу шаблонизаторов и теперь можем перейти к работе с HTML в Go Fiber.

Работа с HTML в Go Fiber

Начнем с реализации веб-страницы личного аккаунта. У нас есть шаблон веб-страницы. Когда пользователь запрашивает ее, Go веб-приложение подставляет информацию текущего пользователя в шаблон и возвращает готовую HTML-страницу.

В нашем веб-приложении шаблоны будут храниться в директории /template. Мы будем указывать путь до этой директории в коде веб-приложения, чтобы оно знало, откуда читать и формировать шаблоны. Структура файлов веб-приложения выглядит как:

.
├── go.mod
├── go.sum
├── main.go
└── template
    └── profile.tmpl

А код веб-приложения имеет следующий вид:

package main

import (
    "github.com/gofiber/fiber/v2"
    "github.com/gofiber/template/html"
    "github.com/sirupsen/logrus"
)

func main() {
    // Инициализируем стандартный Go-шаблонизатор
    // Указываем папку, в которой хранятся шаблоны
    // Указываем расширение файлов шаблонов
    viewsEngine := html.New("./template", ".tmpl")

    // Создаем новый экземпляр Fiber веб-приложения,
    // указывая наш шаблонизатор
    webApp := fiber.New(fiber.Config{
        Views: viewsEngine,
    })

    // Настраиваем обработчик для веб-страницы аккаунта пользователя
    webApp.Get("/profile", func(c *fiber.Ctx) error {
        return c.Render("profile", fiber.Map{
            "name":  "John",
            "email": "john@doe.com",
        })
    })

    logrus.Fatal(webApp.Listen(":80"))
}

Запускаем веб-приложение и переходим в веб-браузере на страницу http://localhost/profile. Мы видим следующий результат:

My Profile

Name: John

Email: john@doe.com

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

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

Мы рассмотрели шаблон с двумя динамическими подстановками: имя и электронная почта пользователя. Но что если нам требуется вывести список динамических данных неопределенного размера? Например, список фильмов в видео-платформе. Для этого в Go-шаблонизаторе используются специальные конструкции. Рассмотрим их.

Использование специальных конструкций в шаблонах

В шаблонах Go-шаблонизатора могут быть более сложные конструкции, чем просто подстановка конкретных данных. Шаблонизатор также поддерживает условные конструкции и циклы. В этом разделе мы рассмотрим, как использовать эти конструкции на примере видео-платформы.

Для начала создадим шаблон для страницы с видео-контентом. В шаблоне мы будем выводить список фильмов, которые пользователь может просмотреть. Для этого создадим файл template/film-list.tmpl со следующим содержимым:

<!DOCTYPE html>
<html>
<body>

<h1>Список фильмов</h1>

{{ range $film := . }}
<div>
    <h2>{{ $film.Title }}</h2>
    <p>
        {{ if $film.IsViewed }}
        Просмотрено ✅
        {{ else }}
        Не просмотрено ❌
        {{ end }}
    </p>
</div>
{{ end }}

</body>
</html>

В шаблоне мы используем две специальные конструкции: цикл range и условие if. В цикле range мы перебираем список фильмов, которые передаются в шаблон в качестве параметра. В условии if мы проверяем, просмотрен ли фильм пользователем. Если фильм просмотрен, то мы выводим веб-страницу с текстом «Просмотрено ✅», иначе — «Не просмотрено ❌».

Опишем код Go веб-приложения, которое будет возвращать веб-страницу со списком фильмов:

package main

import (
    "github.com/gofiber/fiber/v2"
    "github.com/gofiber/template/html"
    "github.com/sirupsen/logrus"
)

// Структура с информацией о фильме
type Film struct {
    Title    string
    IsViewed bool
}

// Для простоты описываем хранилище фильмов в коде
var films = []Film{
    {
        Title:    "The Shawshank Redemption",
        IsViewed: true,
    },
    {
        Title:    "The Godfather",
        IsViewed: true,
    },
    {
        Title:    "The Godfather: Part II",
        IsViewed: false,
    },
}

func main() {
    // Инициализируем стандартный Go-шаблонизатор
    // Указываем папку, в которой хранятся шаблоны
    // Указываем расширение файлов шаблонов
    viewsEngine := html.New("./template", ".tmpl")

    // Создаем новый экземпляр Fiber веб-приложения,
    // указывая наш шаблонизатор
    webApp := fiber.New(fiber.Config{
        Views: viewsEngine,
    })

    // Настраиваем обработчик для веб-страницы со списком фильмов
    webApp.Get("/films", func(c *fiber.Ctx) error {
        return c.Render("film-list", films)
    })

    logrus.Fatal(webApp.Listen(":80"))
}

Запускаем веб-приложение и переходим в веб-браузере на страницу http://localhost/films. Мы видим следующий результат:

Список фильмов

The Shawshank Redemption

Просмотрено ✅

The Godfather

Просмотрено ✅

The Godfather: Part II

Не просмотрено ❌

Мы создали веб-приложение на Go, которое возвращает веб-страницу со списком фильмов. Веб-страница создается на основе шаблона, который хранится в файле template/film-list.tmpl.

Шаблон веб-страницы содержит конструкцию-if и цикл. Это позволяет нам выводить столько фильмов, сколько у нас хранится в хранилище, не внося изменений в код веб-приложения.

Выводы

  • HTML — это язык разметки, по которому веб-браузеры строят и отображают контент для пользователей
  • При переходе по ссылке веб-браузер отправляет GET HTTP-запрос по адресу и отображает HTML-код, полученный в теле ответа
  • Шаблонизаторы позволяют создавать HTML-страницы на основе шаблонов, если подставлять в них динамические данные из веб-приложений
  • Go-шаблонизатор позволяет использовать как простые подстановки в виде конкретных переменных {{ .Name }}, так и сложные конструкции, например: циклы и условия {{ range .Films }} {{ .Title }} {{ end }}

Дополнительные материалы

  1. Go HTML Template package
  2. Fiber Templates
  3. Go Templates Examples

Аватары экспертов Хекслета

Остались вопросы? Задайте их в разделе «Обсуждение»

Вам ответят команда поддержки Хекслета или другие студенты

Для полного доступа к курсу нужен базовый план

Базовый план откроет полный доступ ко всем курсам, упражнениям и урокам Хекслета, проектам и пожизненный доступ к теории пройденных уроков. Подписку можно отменить в любой момент.

Получить доступ
1000
упражнений
2000+
часов теории
3200
тестов

Открыть доступ

Курсы программирования для новичков и опытных разработчиков. Начните обучение бесплатно

  • 130 курсов, 2000+ часов теории
  • 1000 практических заданий в браузере
  • 360 000 студентов
Отправляя форму, вы принимаете «Соглашение об обработке персональных данных» и условия «Оферты», а также соглашаетесь с «Условиями использования»

Наши выпускники работают в компаниях:

Логотип компании Альфа Банк
Логотип компании Aviasales
Логотип компании Yandex
Логотип компании Tinkoff

Используйте Хекслет по-максимуму!

  • Задавайте вопросы по уроку
  • Проверяйте знания в квизах
  • Проходите практику прямо в браузере
  • Отслеживайте свой прогресс

Зарегистрируйтесь или войдите в свой аккаунт

Отправляя форму, вы принимаете «Соглашение об обработке персональных данных» и условия «Оферты», а также соглашаетесь с «Условиями использования»
Изображение Тото

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