Рассмотрим некоторые базовые элементы синтаксиса шаблонов, например, условные конструкции и циклы.
Пусть на стороне сервера в шаблон передается массив:
package main import ( "fmt" "net/http" "html/template" ) type ViewData struct{ Title string Users []string } func main() { data := ViewData{ Title : "Users List", Users : []string{ "Tom", "Bob", "Sam", }, } http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { tmpl, _ := template.ParseFiles("templates/index.html") tmpl.Execute(w, data) }) fmt.Println("Server is listening...") http.ListenAndServe(":8181", nil) }
Для вывода массива в шаблоне используется конструкция {{range массив}} {{end}}
. После слова range указывается перебираемый массив:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>{{ .Title}}</title> </head> <body> <h1>{{ .Title}}</h1> <ul> {{range .Users}} <li><b>{{ . }}</b></li> {{end}} </ul> </body> </html>
Внутри конструкции range мы можем обращаться к текущему перебираемому объекту с помощью точки {{ . }}
.
Массив может не иметь данных. Если нам надо определить поведение на этот случай, то можно использовать подконструкцию {{else}}
:
<ul> {{range .Users}} <li><b>{{ . }}</b></li> {{else}} <li><b>no rows</b></li> {{end}} </ul>
Данные в массиве могут представлять сложные данные:
package main import ( "fmt" "net/http" "html/template" ) type ViewData struct{ Title string Users []User } type User struct{ Name string Age int } func main() { data := ViewData{ Title : "Users List", Users : []User{ User{Name: "Tom", Age: 21}, User{Name: "Kate", Age: 23}, User{Name: "Alice", Age: 25}, }, } http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { tmpl, _ := template.ParseFiles("templates/index.html") tmpl.Execute(w, data) }) fmt.Println("Server is listening...") http.ListenAndServe(":8181", nil) }
Вывод этих данных в шаблоне:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>{{ .Title}}</title> </head> <body> <h1>{{ .Title}}</h1> <ul> {{range .Users}} <li> <div><b>{{ .Name }}</b>: {{ .Age }}</div> </li> {{end}} </ul> </body> </html>
Если нам надо вывести в шаблоне некоторую разметку в зависимости от определенного условия, то можно использовать конструкцию {{if условие}}{{end}}
.
После ключевого слова if идет условие, которое должно возващать значение типа bool: true или false.
Например, передадим из сервера в шаблон данные, которые содержат логическое выражение:
package main import ( "fmt" "net/http" "html/template" ) type ViewData struct{ Available bool } func main() { data := ViewData{ Available: true, } http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { tmpl, _ := template.ParseFiles("templates/index.html") tmpl.Execute(w, data) }) fmt.Println("Server is listening...") http.ListenAndServe(":8181", nil) }
Определим в шаблоне следующий код:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Available</title> </head> <body> <div> {{if .Available}} <p>Available</p> {{end}} </div> </body> </html>
То есть если переменная Available равна true, то будет выводиться разметка <p>Available</p>
. Если пременная равна
false, то ничего не будет выводиться.
С помощью конструкции {{else}}
можно определить разметку html, которая выводится, если условие в if равно false:
<div> {{if .Available}} <p>Available</p> {{else}} <p>Not Available</p> {{end}} </div>
Также мы можем в if сравнивать значения. Например, пусть сервер передает в шаблон текущий час:
package main import ( "fmt" "net/http" "html/template" "time" ) type ViewData struct{ Hour int } func main() { data := ViewData{ Hour: time.Now().Hour(), } http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { tmpl, _ := template.ParseFiles("templates/index.html") tmpl.Execute(w, data) }) fmt.Println("Server is listening...") http.ListenAndServe(":8181", nil) }
С помощью метода time.Now().Hour()
здесь получаем текущий час.
В шаблоне определим следующую конструкцию:
<div> {{if lt .Hour 12 }} <p>Доброе утро</p> {{else}} <p>Добрый день</p> {{end}} </div>
В данном случае сравнивается значение текущего часа с числом 12, и в зависимости от значения выводим тот или иной текст.
Оператор lt можно расшифровать как "less than", то есть меньше чем. То есть фактически это аналог операции
<
. Он сравнивает два значения и возвращает true,
если первое значение менльше второго. Иначе возвращается значение false.
Подобным образом мы можем использовать еще ряд операторов, которые аналогичны стандартным операторам сравнения:
eq
: возвращает true, если два значения равны
ne
: возвращает true, если два значения НЕ равны
le
: возвращает true, если первое значение меньше или равно второму
gt
: возвращает true, если первое значение больше второго
ge
: возвращает true, если первое значение больше или равно второму
Кроме того, есть ряд операторов, которые аналогичны логическим операторам:
and
: возвращает true, если два выражения равны true
or
: возвращает true, если хотя бы одно из двух выражений равно true
not
: возвращает true, если выражение возвращает false
Применение некоторых операторов:
<div> {{if or (gt 2 1) (lt 5 7)}} <p>Первый вариант</p> {{else}} <p>Второй вариант</p> {{end}} </div>