Синтаксис шаблонов

Последнее обновление: 02.03.2018

Рассмотрим некоторые базовые элементы синтаксиса шаблонов, например, условные конструкции и циклы.

Циклы

Пусть на стороне сервера в шаблон передается массив:

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 мы можем обращаться к текущему перебираемому объекту с помощью точки {{ . }}.

range in template in Go

Массив может не иметь данных. Если нам надо определить поведение на этот случай, то можно использовать подконструкцию {{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>
for cycle in template in golang

Условные конструкции

Если нам надо вывести в шаблоне некоторую разметку в зависимости от определенного условия, то можно использовать конструкцию {{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>
Помощь сайту
Юмани:
410011174743222
Перевод на карту
Номер карты:
4048415020898850