Лучшая система шаблонов в Go
- четверг, 22 августа 2024 г. в 00:00:08
Привет, Хабр!
В этой статье хочу поговорить про, пожалуй, мою самую любимую библиотеку для Go. Это Jet templates. Библиотека, которая очень упрощает работу с шаблонами(templates) в Go.
Работать со встроенными шаблонами в Го я очень не люблю. Прописывание мап, неудобная работа в самих шаблонах. Jet это решает.
Для того, чтобы сделать мапу с данными для шаблона, необходимо написать всего одну строку:
data := make(jet.Varmap)
А для того, чтобы что-то туда записать, необходимо написать так:
data.Set("data", any)
Теперь о том, как это использовать:
views := jet.NewHTMLSet(pathToTemplates) // Получаем абсолютно все шаблоны по
// этому пути
Чтобы отрендерить определенный шаблон, необходимо написать это:
t, err := tc.GetTemplate(templateName) // Получаем определенный шаблон
// обработка ошибки
err = t.Execute(w, data, nil) // где w - ResponseWriter, data - jet.Varmap с данными.
Тут важно, что данные необходимо поставить на второе место в аргументах, а не на третье, хотя название третьего аргумента и называется "data", надо ставить на "variables"
Но, по надобности, можете написать и собственную структуру с данными и тогда уже ставьте ее на третье место:
data := struct {
Data string
}{
Data: "hello",
}
err = t.Execute(w, nil, data)
Вот самый простой пример использования jet:
package main
import (
"log"
"net/http"
"github.com/CloudyKit/jet"
)
func main() {
http.HandleFunc("/hello", func(w http.ResponseWriter, r *http.Request) {
set := jet.NewHTMLSet("./templates")
data := make(jet.VarMap)
t, err := set.GetTemplate("hello.html")
if err != nil {
log.Fatal(err)
}
data.Set("message", "Hello World!")
t.Execute(w, data, nil)
})
log.Fatal(http.ListenAndServe(":8080", nil))
}
Обработка должна происходить в http-хэндлере, но ее можно вынести в отдельный пакет “render” и передавать туда необходимые данные по типу "w ResponseWriter, data jet.Varmap, templateName string" и уже это вызывать из хэндлера.
Я использую встроенный в стандартный пакет net/http “ResponseWriter”, но как это делается в том же GoFiber - не знаю, думаю в его fiber.Ctx это быть должно
Много, о чем можно рассказать, поэтому если понадобится, то читайте тут: https://github.com/CloudyKit/jet/wiki/3.-Jet-template-syntax
Начну с использования данных, которые были переданы
Пусть у нас будет data с message равным “Hello World!”
data.Set("message", "Hello World!")
Теперь в шаблоне в двойных фигурных скобках пишем название переменной, которую записали в data:
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title></title>
<link href="css/style.css" rel="stylesheet" />
</head>
<body>
<div>{{message}}</div>
</body>
</html>
Наша страница:
Но, представим, Вам захотелось использовать собственно написанную структуру:
data := struct {
Data string
}{
Data: "hello",
}
err = t.Execute(w, nil, data)
Тогда в шаблоне, чтобы получить данные поля Data из структуры, необходимо добавить точку в начале:
<div>{{.Data}</div>
Для прохода по массиву, который Вы передали в шаблон, можно использовать “range”:
{{range keyOrIndex, value := array}}
Ваши действия
{{end}}
Но, можно обойтись и без индекса:
{{range value := array}}
Ваши действия
{{end}}
Скажу даже больше, можно убрать все и оставить только массив:
{{range array}}
<p>Выводим текущий элемент: {{.}}</p>
{{end}}
Еще можно легко работать с layouts. Для этого надо создать файл с содержимым лэйаута, например такой:
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title></title>
<link href="css/style.css" rel="stylesheet" />
</head>
<body>
{{yield body()}}
</body>
</html>
“yield” вызывает кусок кода из другого файла. Давайте теперь создадим еще один файл с содержимым body():
{{extends "путь к вашему layout"}}
{{block body()}}
<div>Что-то<div>
{{end}}
Таких файлов с содержимым body может быть неограниченное кол-во. Вы можете создавать и другие блоки и распологать их в другом месте, например не в body, а в title с одноименным названием
Теперь, если у Вас много шаблонов с одинаковым началом, Вы можете вынести это все в layout и подключаться из разных файлов.
Надеюсь, Вы открыли для себя эту замечательную библиотеку и Вам станет легче писать шаблоны в Go. Это и еще многое читайте в офиц. репозитории Jet templates: https://github.com/CloudyKit/jet/