Как сгенерировать HTML с помощью шаблонов Golang
Ниже вы можете увидеть веб-страницу, которую мы создадим с помощью GO в данной статье :
Веб-страница является адаптивной, она адаптируется к разной ширине экрана, и когда вы нажимаете на один из «продуктов», вы увидите всплывающее окно с описанием продукта и кнопками.
Я сначала покажу вам программу, которая будет анализировать и отображать шаблоны, а затем выводить сгенерированный HTML-файл. После этого я покажу вам, как выглядят разные шаблоны, и расскажу о некоторых методах, которые я использовал в них.
Golang код
Вот программа Golang, которая сделает всю работу:
package main
import (
"bufio"
"bytes"
"html/template"
"os"
)
type product struct {
Img string
Name string
Price string
Stars float64
Reviews int
Description string
}
func subtr(a, b float64) float64 {
return a - b
}
func list(e ...float64) []float64 {
return e
}
func main() {
data := []product{
{"images/1.png", "strawberries", "$2.00", 4.0, 251, "Lorem ipsum dolor sit amet, consectetur adipiscing elit."},
{"images/2.png", "onions", "$2.80", 5.0, 123, "Morbi sit amet erat vitae purus consequat vehicula nec sit amet purus."},
{"images/3.png", "tomatoes", "$3.10", 4.5, 235, "Curabitur tristique odio et nibh auctor, ut sollicitudin justo condimentum."},
{"images/4.png", "courgette", "$1.20", 4.0, 251, "Phasellus at leo a purus consequat ornare ac aliquam quam."},
{"images/5.png", "broccoli", "$3.80", 3.5, 123, "Maecenas sed ante sagittis, dapibus dui quis, hendrerit orci."},
{"images/6.png", "potatoes", "$3.00", 2.5, 235, "Vivamus malesuada est et tellus porta, vel consectetur orci dapibus."},
}
allFiles := []string{"content.tmpl", "footer.tmpl", "header.tmpl", "page.tmpl"}
var allPaths []string
for _, tmpl := range allFiles {
allPaths = append(allPaths, "./templates/"+tmpl)
}
templates := template.Must(template.New("").Funcs(template.FuncMap{"subtr": subtr, "list": list}).ParseFiles(allPaths...))
var processed bytes.Buffer
templates.ExecuteTemplate(&processed, "page", data)
outputPath := "./static/index.html"
f, _ := os.Create(outputPath)
w := bufio.NewWriter(f)
w.WriteString(string(processed.Bytes()))
w.Flush()
}
В строках 3–8 мы импортируем необходимые пакеты. Пакеты bufio, bytes и os необходимы для вывода файла HTML.
Пакет html/template используется для работы с шаблонами.
В строках 10–17 мы определяем product — структуру для хранения данных о продукте. Убедитесь, что все свойства написаны заглавными буквами, т. е. что их можно экспортировать. Это необходимо при использовании структуры внутри шаблонов Golang.
Также обратите внимание, что количество звездочек — это число с плавающей запятой от 0 до 5. Причина, по которой мы используем тип float64 для этого числа, заключается в том, что шаблоны используют float64 для всех чисел с плавающей запятой.
В строках 19–25 я создал две функции. Первая функция, называемая subtr(), представляет собой простую функцию вычитания чисел с плавающей запятой, а вторая функция, называемая list(), используется для создания списка чисел с плавающей запятой.
В строках 29–36 мы определяем данные, которые будут отображаться в шаблонах. В этом примере данные жестко запрограммированы. В более реалистичных условиях эти данные, вероятно, будут храниться в какой-либо базе данных.
В строке 38 мы добавляем имена файлов всех шаблонов в слайс.
В строках 40–43 ко всем именам файлов добавляется имя каталога /templates/.
В строке 45 мы анализируем шаблоны с помощью ParseFiles(), обязательно добавляем две функции subtr и list с помощью template.FuncMap{} и проверяем правильность шаблонов с помощью template.Must().
В строках 47–48 мы отображаем шаблоны в байтовый буфер. Чтобы убедиться, что рендеринг начинается с шаблона страницы, мы используем ExecuteTemplates() со «страницей» в качестве аргумента. Здесь мы также передаем данные, которые мы определили средству визуализации.
В строках 50–54 обработанный байтовый буфер выводится в файл HTML с именем index.html в каталоге ./static.
Шаблоны для генерации HTML
Здесь мы обсудим все шаблоны, используемые для этого проекта.
Шаблон «page»(страница)
Это шаблон, который определяет полную веб-страницу. Он вызывает три других шаблона; header
, content
, and footer
(заголовок, содержимое и нижний колонтитул).
{{define "page"}}
{{template "header" -}}
{{template "content" . -}}
{{template "footer" -}}
{{end}}
В строке 1 необходимо определить страницу внутри этого шаблона, иначе метод ExecuteTemplates() ее не найдет.
Обратите внимание, что в строке 3 при вызове шаблона контента добавляется точка. Это сигнализирует обработчику шаблона, что предоставленные данные должны быть отправлены вместе с шаблоном контента. Это то же самое, что и передача параметров функции.
Шаблон «header»
Этот шаблон используется для отображения типичного заголовка HTML, который загружает шрифты, стили и код JavaScript.
{{define "header" -}}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.4/css/all.min.css">
<link rel="stylesheet" href="css/style.css">
<script src="js/script.js" defer></script>
</head>
<body>
{{end}}
Обратите внимание, что мы используем ключевые слова define и end для определения шаблона .
Также обратите внимание на знак «-» перед двойными закрывающими скобками. Этот знак указывает средству визуализации удалить пробелы и символы новой строки. По моему опыту, вам нужно поэкспериментировать с использование этих «-», чтобы лучше понять их использование.
Чтобы добиться желаемого результата, вам иногда нужно поставить «-» после двойных скобок, иногда перед двойными конечными скобками, а иногда и в обоих местах.
Шаблон «content»
Это шаблон, который отображает тело HTML-файла.
С данным шаблоном мы можем быстро создавать другие страницы с другим содержимым, но с тем же верхним и нижним колонтитулами, т. е. загружая те же CSS, JS, шрифты и т. д.
{{define "content" -}}
<div class="container">
<h3 class="title"> organic products </h3>
<div class="products-container">
{{range $index, $item :=.}}
<div class="product" data-name="p-{{$index}}">
<img src="{{$item.Img}}" alt="">
<h3>{{$item.Name}}</h3>
<div class="price">{{$item.Price}}</div>
</div>
{{end}}
</div>
</div>
<div class="products-preview">
{{range $index, $item:=.}}
<div class="preview" data-target="p-{{$index}}">
<i class="fas fa-times"></i>
<img src="{{$item.Img}}" alt="">
<h3>organic {{$item.Name}}</h3>
<div class="stars">
{{- $stars := list 1.0 2.0 3.0 4.0 5.0 -}}
{{- range $stars}}
{{$x:= subtr . 0.5}}
{{- if lt $item.Stars $x -}}
<i class="far fa-star"></i>
{{- else if lt $item.Stars . -}}
<i class="fas fa-star-half-alt"></i>
{{- else -}}
<i class="fas fa-star"></i>
{{- end -}}
{{end}}
<span>( {{$item.Reviews}} )</span>
</div>
<p>{{$item.Description}}</p>
<div class="price">{{$item.Price}}</div>
<div class="buttons">
<a href="#" class="buy">buy now</a>
<a href="#" class="cart">add to cart</a>
</div>
</div>
{{end}}
</div>
{{end}}
В строках 5–12 мы перебираем все продукты . Для каждого продукта мы создаем внутренние переменные шаблона $index и $item. Мы используем $index для атрибута имени данных. Из $item мы извлекаем свойства Img, Name и Price для использования в HTML.
В строках 16–42 мы делаем то же самое, что и выше, но также извлекаем свойства $Stars $Description и $Reviews из $item.
В строке 22 мы создаем список с именем $stars. Этот список содержит числа с плавающей запятой от 1,0 до 5,0. Они понадобятся нам для отображения рейтинга(звезд). Эти числа представляют собой пороговое значение для отображения каждой звезды.
Затем в строках 23–32 мы создаем цикл для отображения рейтинга(звезд). По сути, у нас есть три типа звезд, которые мы можем отображать: полные звезды, половина звезды и пустые звезды.
Шаблон «footer»
Здесь ничего особенного не происходит, кроме определения шаблона как нижнего колонтитула.
{{define "footer" -}}
</body>
</html>
{{end}}
Запуск генератора HTML и просмотр результата
Убедитесь, что файл main.go находится в каталоге, который также содержит два подкаталога с именами templates и static. Все вышеперечисленные шаблоны должны находиться в каталоге шаблонов. CSS, JS и изображения из исходного кода должны находиться в соответствующих подкаталогах статического каталога.
Просто введите go run main.go из нужного каталога в вашем терминале, чтобы запустить генератор. Впоследствии файл HTML будет сгенерирован и записан в статический каталог как index.html.
Теперь вы можете открыть файл index.html в своем браузере, и вы должны получить веб страницу, показанную в начале этой статьи.