Spec-Zone.ru › Go

Пакет шаблон

  • import "text/template"
  • Обзор
  • Индекс
  • Примеры
  • Подкаталоги

Обзор

Пакет шаблон реализует шаблоны, управляемые данными, для генерации текстового вывода.

Для генерации HTML-вывода, см. html/template, который имеет тот же интерфейс, что и этот пакет, но автоматически защищает HTML-вывод от определенных атак.

Шаблоны выполняются, применяя их к структуре данных. Аннотации в шаблоне ссылаются на элементы структуры данных (обычно поле структуры или ключ в карте) для управления выполнением и получения значений для отображения. Выполнение шаблона проходит по структуре и устанавливает курсор, представленный точкой '.' и называемый "точкой", на значение в текущем месте структуры по мере выполнения.

Входной текст для шаблона — это текст в кодировке UTF-8 в любом формате. "Действия" — вычисления данных или управляющие структуры — разделяются "{{" и "}}"; весь текст вне действий копируется в выходные данные без изменений.

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

Вот тривиальный пример, который печатает "17 предметов изготовлены из шерсти".

type Inventory struct {
	Material string
	Count    uint
}
sweaters := Inventory{"wool", 17}
tmpl, err := template.New("test").Parse("{{.Count}} items are made of {{.Material}}")
if err != nil { panic(err) }
err = tmpl.Execute(os.Stdout, sweaters)
if err != nil { panic(err) }

Более сложные примеры приведены ниже.

Текст и пробелы

По умолчанию весь текст между действиями копируется дословно при выполнении шаблона. Например, строка " предметов изготовлены из " в приведенном выше примере появляется в стандартном выводе при запуске программы.

Однако для облегчения форматирования исходного кода шаблона, если левая разделитель действия (по умолчанию "{{") сразу следует за знаком минус и пробелом, все последующие пробелы обрезаются из непосредственно предшествующего текста. Аналогично, если правый разделитель ("}}") предшествует пробелу и знаку минус, все начальные пробелы обрезаются из непосредственно последующего текста. В этих маркерах обрезки пробелы должны быть присутствовать: "{{- 3}}" похоже на "{{3}}", но обрезает непосредственно предшествующий текст, в то время как "{{-3}}" анализируется как действие, содержащее число -3.

Например, при выполнении шаблона, исходный код которого

"{{23 -}} < {{- 45}}"

сгенерированный вывод будет

"23<45"

Для этой обрезки определение символов пробелов такое же, как и в Go: пробел, горизонтальная табуляция, возврат каретки и перевод строки.

Действия

Вот список действий. "Аргументы" и "конвейеры" — это вычисления данных, подробно определённые в соответствующих разделах, которые следуют.

{{/* a comment */}}
{{- /* a comment with white space trimmed from preceding and following text */ -}}
	A comment; discarded. May contain newlines.
	Comments do not nest and must start and end at the
	delimiters, as shown here.

{{pipeline}}
	The default textual representation (the same as would be
	printed by fmt.Print) of the value of the pipeline is copied
	to the output.

{{if pipeline}} T1 {{end}}
	If the value of the pipeline is empty, no output is generated;
	otherwise, T1 is executed. The empty values are false, 0, any
	nil pointer or interface value, and any array, slice, map, or
	string of length zero.
	Dot is unaffected.

{{if pipeline}} T1 {{else}} T0 {{end}}
	If the value of the pipeline is empty, T0 is executed;
	otherwise, T1 is executed. Dot is unaffected.

{{if pipeline}} T1 {{else if pipeline}} T0 {{end}}
	To simplify the appearance of if-else chains, the else action
	of an if may include another if directly; the effect is exactly
	the same as writing
		{{if pipeline}} T1 {{else}}{{if pipeline}} T0 {{end}}{{end}}

{{range pipeline}} T1 {{end}}
	The value of the pipeline must be an array, slice, map, or channel.
	If the value of the pipeline has length zero, nothing is output;
	otherwise, dot is set to the successive elements of the array,
	slice, or map and T1 is executed. If the value is a map and the
	keys are of basic type with a defined order, the elements will be
	visited in sorted key order.

{{range pipeline}} T1 {{else}} T0 {{end}}
	The value of the pipeline must be an array, slice, map, or channel.
	If the value of the pipeline has length zero, dot is unaffected and
	T0 is executed; otherwise, dot is set to the successive elements
	of the array, slice, or map and T1 is executed.

{{break}}
	The innermost {{range pipeline}} loop is ended early, stopping the
	current iteration and bypassing all remaining iterations.

{{continue}}
	The current iteration of the innermost {{range pipeline}} loop is
	stopped, and the loop starts the next iteration.

{{template "name"}}
	The template with the specified name is executed with nil data.

{{template "name" pipeline}}
	The template with the specified name is executed with dot set
	to the value of the pipeline.

{{block "name" pipeline}} T1 {{end}}
	A block is shorthand for defining a template
		{{define "name"}} T1 {{end}}
	and then executing it in place
		{{template "name" pipeline}}
	The typical use is to define a set of root templates that are
	then customized by redefining the block templates within.

{{with pipeline}} T1 {{end}}
	If the value of the pipeline is empty, no output is generated;
	otherwise, dot is set to the value of the pipeline and T1 is
	executed.

{{with pipeline}} T1 {{else}} T0 {{end}}
	If the value of the pipeline is empty, dot is unaffected and T0
	is executed; otherwise, dot is set to the value of the pipeline
	and T1 is executed.

{{with pipeline}} T1 {{else with pipeline}} T0 {{end}}
	To simplify the appearance of with-else chains, the else action
	of a with may include another with directly; the effect is exactly
	the same as writing
		{{with pipeline}} T1 {{else}}{{with pipeline}} T0 {{end}}{{end}}

Аргументы

Аргумент — простое значение, обозначаемое одним из следующего.

  • Булево, строковое, символьное, целочисленное, с плавающей точкой, мнимое или комплексное константы в синтаксисе Go. Они ведут себя как нетипированные константы Go. Обратите внимание, что, как и в Go, переполнение большой целочисленной константы при присваивании или передаче в функцию может зависеть от того, являются ли целые числа на целевой машине 32- или 64-разрядными.
  • Ключевое слово nil, представляющее нетипированный Go nil.
  • Символ '.' (точка): . Результат — значение точки.
  • Имя переменной, которое представляет собой (возможно, пустую) буквенно-цифровое строку, предваряемую знаком доллара, например $piOver2 или $. Результат — значение переменной. Переменные описаны ниже.
  • Имя поля данных, которое должно быть структурой, предваряемое точкой, например .Field Результат — значение поля. Вызовы полей могут быть цепными: .Field1.Field2 Поля также могут быть вычислены по переменным, включая цепочки: $x.Field1.Field2
  • Имя ключа данных, которое должно быть картой, предваряемое точкой, например .Key Результат — значение элемента карты, индексированного по ключу. Вызовы ключей могут быть цепными и совмещены с полями до любой глубины: .Field1.Key1.Field2.Key2 Хотя ключ должен быть буквенно-цифровым идентификатором, в отличие от имён полей, они не должны начинаться с большой буквы. Ключи также могут быть вычислены по переменным, включая цепочки: $x.key1.key2
  • Имя ниль-метода данных, предваряемого точкой, например .Method Результат — значение вызова метода с точкой в качестве получателя, dot.Method(). Такой метод должен иметь одно возвращаемое значение (любого типа) или два возвращаемых значения, второе из которых — ошибка. Если у него есть два и возвращённая ошибка не равна nil, выполнение завершается, и ошибка возвращается вызывающей стороне в качестве значения Execute. Вызовы методов могут быть цепными и объединены с полями и ключами любой глубины: .Field1.Key1.Method1.Field2.Key2.Method2 Методы также могут быть вычислены по переменным, включая цепочки: $x.Method1.Field
  • Имя ниль-функции, например fun Результат — значение вызова функции, fun(). Типы и значения возврата ведут себя так же, как в методах. Функции и имена функций описаны ниже.
  • Скобочный экземпляр одного из вышеперечисленных для группирования. К результату можно получить доступ с помощью вызова поля или ключа карты. print (.F1 arg1) (.F2 arg2) (.StructValuedMethod "arg").Field

Аргументы могут быть любого типа; если это указатели, реализация автоматически перенаправляет на базовый тип при необходимости. Если вычисление даёт значение функции, например, значение поля типа функции структуры, функция не вызывается автоматически, но её можно использовать как истинное значение для действия if и тому подобного. Чтобы вызвать её, используйте функцию call, определённую ниже.

Конвейеры

Конвейер — это возможно цепочка команд. Команда — простое значение (аргумент) или вызов функции или метода, возможно, с несколькими аргументами:

Argument
	The result is the value of evaluating the argument.
.Method [Argument...]
	The method can be alone or the last element of a chain but,
	unlike methods in the middle of a chain, it can take arguments.
	The result is the value of calling the method with the
	arguments:
		dot.Method(Argument1, etc.)
functionName [Argument...]
	The result is the value of calling the function associated
	with the name:
		function(Argument1, etc.)
	Functions and function names are described below.

Конвейер может быть «цепным», разделяя последовательность команд символами конвейера '|'. В цепном конвейере результат каждой команды передаётся в качестве последнего аргумента следующей команды. Результат последней команды в конвейере — значение конвейера.

Выход команды будет либо одним значением, либо двумя значениями, второе из которых имеет тип error. Если это второе значение присутствует и имеет ненулевое значение, выполнение завершается, и ошибка возвращается вызывающей стороне Execute.

Переменные

Конвейер внутри действия может инициализировать переменную для захвата результата. Инициализация имеет синтаксис

$variable := pipeline

где $переменная — имя переменной. Действие, объявляющее переменную, не производит никакого вывода.

Ранее объявленным переменным также можно присвоить значения, используя синтаксис

$variable = pipeline

Если действие «range» инициализирует переменную, переменная устанавливается на последовательные элементы итерации. Кроме того, «range» может объявить две переменные, разделённые запятой:

range $index, $element := pipeline

в этом случае $индекс и $элемент устанавливаются на последовательные значения индекса массива/слайса или ключа и элемента карты соответственно. Обратите внимание, что если есть только одна переменная, ей присваивается элемент; это противоположно соглашению в операторах диапазона Go.

Область действия переменной распространяется до действия «end» управляющей структуры («if», «with» или «range»), в которой она объявлена, или до конца шаблона, если такой управляющей структуры нет. Вызов шаблона не наследует переменные с точки своего вызова.

Когда начинается выполнение, $ устанавливается на аргумент данных, переданный в Execute, то есть на начальное значение точки.

Примеры

Вот несколько примеров шаблонов в одну строку, демонстрирующих конвейеры и переменные. Все они производят слово «вывод»:

{{"\"output\""}}
	A string constant.
{{`"output"`}}
	A raw string constant.
{{printf "%q" "output"}}
	A function call.
{{"output" | printf "%q"}}
	A function call whose final argument comes from the previous
	command.
{{printf "%q" (print "out" "put")}}
	A parenthesized argument.
{{"put" | printf "%s%s" "out" | printf "%q"}}
	A more elaborate call.
{{"output" | printf "%s" | printf "%q"}}
	A longer chain.
{{with "output"}}{{printf "%q" .}}{{end}}
	A with action using dot.
{{with $x := "output" | printf "%q"}}{{$x}}{{end}}
	A with action that creates and uses a variable.
{{with $x := "output"}}{{printf "%q" $x}}{{end}}
	A with action that uses the variable in another action.
{{with $x := "output"}}{{$x | printf "%q"}}{{end}}
	The same, but pipelined.

Функции

Во время выполнения функции находятся в двух картах функций: сначала в шаблоне, затем в глобальной карте функций. По умолчанию функции в шаблоне не определены, но метод Funcs может быть использован для их добавления.

Предопределённые глобальные функции имеют следующие имена.

and
	Returns the boolean AND of its arguments by returning the
	first empty argument or the last argument. That is,
	"and x y" behaves as "if x then y else x."
	Evaluation proceeds through the arguments left to right
	and returns when the result is determined.
call
	Returns the result of calling the first argument, which
	must be a function, with the remaining arguments as parameters.
	Thus "call .X.Y 1 2" is, in Go notation, dot.X.Y(1, 2) where
	Y is a func-valued field, map entry, or the like.
	The first argument must be the result of an evaluation
	that yields a value of function type (as distinct from
	a predefined function such as print). The function must
	return either one or two result values, the second of which
	is of type error. If the arguments don't match the function
	or the returned error value is non-nil, execution stops.
html
	Returns the escaped HTML equivalent of the textual
	representation of its arguments. This function is unavailable
	in html/template, with a few exceptions.
index
	Returns the result of indexing its first argument by the
	following arguments. Thus "index x 1 2 3" is, in Go syntax,
	x[1][2][3]. Each indexed item must be a map, slice, or array.
slice
	slice returns the result of slicing its first argument by the
	remaining arguments. Thus "slice x 1 2" is, in Go syntax, x[1:2],
	while "slice x" is x[:], "slice x 1" is x[1:], and "slice x 1 2 3"
	is x[1:2:3]. The first argument must be a string, slice, or array.
js
	Returns the escaped JavaScript equivalent of the textual
	representation of its arguments.
len
	Returns the integer length of its argument.
not
	Returns the boolean negation of its single argument.
or
	Returns the boolean OR of its arguments by returning the
	first non-empty argument or the last argument, that is,
	"or x y" behaves as "if x then x else y".
	Evaluation proceeds through the arguments left to right
	and returns when the result is determined.
print
	An alias for fmt.Sprint
printf
	An alias for fmt.Sprintf
println
	An alias for fmt.Sprintln
urlquery
	Returns the escaped value of the textual representation of
	its arguments in a form suitable for embedding in a URL query.
	This function is unavailable in html/template, with a few
	exceptions.

Булевы функции принимают любое нулевое значение как ложь и ненулевое значение как истину.

Также определён набор бинарных операторов сравнения, определённых как функции:

eq
	Returns the boolean truth of arg1 == arg2
ne
	Returns the boolean truth of arg1 != arg2
lt
	Returns the boolean truth of arg1 < arg2
le
	Returns the boolean truth of arg1 <= arg2
gt
	Returns the boolean truth of arg1 > arg2
ge
	Returns the boolean truth of arg1 >= arg2

Для более простых многосторонних тестов на равенство eq (только) принимает два или более аргумента и сравнивает второй и последующие с первым, возвращая, по сути,

arg1==arg2 || arg1==arg3 || arg1==arg4 ...

(В отличие от || в Go, однако, eq — это вызов функции, и все аргументы будут вычислены.)

Функции сравнения работают с любыми значениями, тип которых Go определяет как сравнимые. Для базовых типов, таких как целые числа, правила смягчаются: размер и точный тип игнорируются, поэтому любое целое число, со знаком или без знака, может быть сравнено с любым другим целым числом. (Сравнивается арифметическое значение, а не битовое представление, поэтому все отрицательные целые числа меньше всех беззнаковых целых чисел.) Однако, как обычно, нельзя сравнить int с float32 и так далее.

Связанные шаблоны

Каждый шаблон называется строкой, указанной при его создании. Также каждый шаблон связан с нулем или более другими шаблонами, которые он может вызывать по имени; такие связи являются транзитивными и образуют пространство имён шаблонов.

Шаблон может использовать вызов шаблона для создания экземпляра другого связанного шаблона; см. объяснение действия «шаблон» выше. Имя должно быть именем шаблона, связанного с шаблоном, содержащим вызов.

Вложенные определения шаблонов

При разборе шаблона может быть определён ещё один шаблон и связан с анализируемым шаблоном. Определения шаблонов должны появляться на верхнем уровне шаблона, подобно глобальным переменным в программе Go.

Синтаксис таких определений заключается в том, чтобы окружать каждое объявление шаблона действиями «определить» и «завершить».

Действие «определить» называет создаваемый шаблон, предоставив строковую константу. Вот простой пример:

{{define "T1"}}ONE{{end}}
{{define "T2"}}TWO{{end}}
{{define "T3"}}{{template "T1"}} {{template "T2"}}{{end}}
{{template "T3"}}

Это определяет два шаблона, T1 и T2, и третий T3, который вызывает два других при его выполнении. Наконец, он вызывает T3. Если выполняется этот шаблон, он произведёт текст

ONE TWO

По конструкции, шаблон может находиться только в одной связи. Если необходимо иметь шаблон, адресовываемый из нескольких ассоциаций, определение шаблона должно быть проанализировано несколько раз, чтобы создать различные значения *Template, или должно быть скопировано с помощью Template.Clone или Template.AddParseTree.

Parse может быть вызван несколько раз для сборки различных связанных шаблонов; см. ParseFiles, ParseGlob, Template.ParseFiles и Template.ParseGlob для простых способов разбора связанных шаблонов, хранящихся в файлах.

Шаблон может быть выполнен непосредственно или через Template.ExecuteTemplate, который выполняет связанный шаблон, идентифицированный по имени. Чтобы вызвать наш пример выше, мы могли бы написать,

err := tmpl.Execute(os.Stdout, "no data needed")
if err != nil {
	log.Fatalf("execution failed: %s", err)
}

или чтобы вызвать конкретный шаблон явно по имени,

err := tmpl.ExecuteTemplate(os.Stdout, "T2", "no data needed")
if err != nil {
	log.Fatalf("execution failed: %s", err)
}

Индекс

  • функция HTMLEscape(w io.Writer, b []byte)
  • функция HTMLEscapeString(s string) string
  • функция HTMLEscaper(args ...any) string
  • функция IsTrue(val any) (truth, ok bool)
  • функция JSEscape(w io.Writer, b []byte)
  • функция JSEscapeString(s string) string
  • функция JSEscaper(args ...any) string
  • функция URLQueryEscaper(args ...any) string
  • тип ExecError
  • функция (e ExecError) Error() string
  • функция (e ExecError) Unwrap() error
  • тип FuncMap
  • тип Template
  • функция Must(t *Template, err error) *Template
  • функция New(name string) *Template
  • функция ParseFS(fsys fs.FS, patterns ...string) (*Template, error)
  • функция ParseFiles(filenames ...string) (*Template, error)
  • функция ParseGlob(pattern string) (*Template, error)
  • функция (t *Template) AddParseTree(name string, tree *parse.Tree) (*Template, error)
  • функция (t *Template) Clone() (*Template, error)
  • функция (t *Template) DefinedTemplates() string
  • функция (t *Template) Delims(left, right string) *Template
  • функция (t *Template) Execute(wr io.Writer, data any) error
  • функция (t *Template) ExecuteTemplate(wr io.Writer, name string, data any) error
  • функция (t *Template) Funcs(funcMap FuncMap) *Template
  • функция (t *Template) Lookup(name string) *Template
  • функция (t *Template) Name() string
  • функция (t *Template) New(name string) *Template
  • функция (t *Template) Option(opt ...string) *Template
  • функция (t *Template) Parse(text string) (*Template, error)
  • функция (t *Template) ParseFS(fsys fs.FS, patterns ...string) (*Template, error)
  • функция (t *Template) ParseFiles(filenames ...string) (*Template, error)
  • функция (t *Template) ParseGlob(pattern string) (*Template, error)
  • функция (t *Template) Templates() []*Template

Примеры

Template
Template (Блок)
Template (Функция)
Template (Glob)
Template (Вспомогательные функции)
Template (Общий доступ)

Файлы пакета

doc.go exec.go funcs.go helper.go option.go template.go

функция HTMLEscape

func HTMLEscape(w io.Writer, b []byte)

HTMLEscape записывает в w экранированный HTML эквивалент обычного текста b.

функция HTMLEscapeString

func HTMLEscapeString(s string) string

HTMLEscapeString возвращает экранированный HTML эквивалент обычного текста s.

функция HTMLEscaper

func HTMLEscaper(args ...any) string

HTMLEscaper возвращает экранированный HTML эквивалент текстового представления своих аргументов.

функция IsTrue 1.6

func IsTrue(val any) (truth, ok bool)

IsTrue сообщает, является ли значение 'true', в смысле не нулевого значения своего типа, и имеет ли значение осмысленное значение истинности. Это определение истинности используется в операциях if и других.

функция JSEscape

func JSEscape(w io.Writer, b []byte)

JSEscape записывает в w экранированный JavaScript эквивалент обычного текста b.

функция JSEscapeString

func JSEscapeString(s string) string

JSEscapeString возвращает экранированный JavaScript эквивалент обычного текста s.

функция JSEscaper

func JSEscaper(args ...any) string

JSEscaper возвращает экранированный JavaScript эквивалент текстового представления своих аргументов.

функция URLQueryEscaper

func URLQueryEscaper(args ...any) string

URLQueryEscaper возвращает экранированное значение текстового представления своих аргументов в формате, подходящем для вставки в строку запроса URL.

тип ExecError 1.6

ExecError — это пользовательский тип ошибки, возвращаемый, когда Execute имеет ошибку при оценке шаблона. (Если возникает ошибка записи, возвращается фактическая ошибка; она не будет типа ExecError.)

type ExecError struct {
    Name string // Name of template.
    Err  error  // Pre-formatted error.
}

функция (ExecError) Error 1.6

func (e ExecError) Error() string

функция (ExecError) Unwrap 1.13

func (e ExecError) Unwrap() error

тип FuncMap

FuncMap — это тип отображения, определяющего соответствие между именами и функциями. Каждая функция должна иметь либо одно возвращаемое значение, либо два возвращаемых значения, из которых второе имеет тип error. В этом случае, если второе (ошибка) возвращаемое значение имеет значение не nil во время выполнения, выполнение завершается, и Execute возвращает эту ошибку.

Возвращаемые ошибками Execute ошибки обертывают основную ошибку; используйте errors.As для их распаковки.

Когда выполнение шаблона вызывает функцию со списком аргументов, этот список должен соответствовать типам параметров функции. Функции, предназначенные для применения к аргументам произвольного типа, могут использовать параметры типа interface{} или типа reflect.Value. Аналогично, функции, предназначенные для возвращения результата произвольного типа, могут возвращать interface{} или reflect.Value.

type FuncMap map[string]any

тип Template

Template — это представление обработанного шаблона. Поле *parse.Tree экспортируется только для использования в html/template и должно рассматриваться как неэкспортированное всеми остальными клиентами.

type Template struct {
    *parse.Tree
    // contains filtered or unexported fields
}

Пример

Код:

// Define a template.
const letter = `
Dear {{.Name}},
{{if .Attended}}
It was a pleasure to see you at the wedding.
{{- else}}
It is a shame you couldn't make it to the wedding.
{{- end}}
{{with .Gift -}}
Thank you for the lovely {{.}}.
{{end}}
Best wishes,
Josie
`

// Prepare some data to insert into the template.
type Recipient struct {
    Name, Gift string
    Attended   bool
}
var recipients = []Recipient{
    {"Aunt Mildred", "bone china tea set", true},
    {"Uncle John", "moleskin pants", false},
    {"Cousin Rodney", "", false},
}

// Create a new template and parse the letter into it.
t := template.Must(template.New("letter").Parse(letter))

// Execute the template for each recipient.
for _, r := range recipients {
    err := t.Execute(os.Stdout, r)
    if err != nil {
        log.Println("executing template:", err)
    }
}

Вывод:

Dear Aunt Mildred,

It was a pleasure to see you at the wedding.
Thank you for the lovely bone china tea set.

Best wishes,
Josie

Dear Uncle John,

It is a shame you couldn't make it to the wedding.
Thank you for the lovely moleskin pants.

Best wishes,
Josie

Dear Cousin Rodney,

It is a shame you couldn't make it to the wedding.

Best wishes,
Josie

Пример (Блок)

Код:

const (
    master  = `Names:{{block "list" .}}{{"\n"}}{{range .}}{{println "-" .}}{{end}}{{end}}`
    overlay = `{{define "list"}} {{join . ", "}}{{end}} `
)
var (
    funcs     = template.FuncMap{"join": strings.Join}
    guardians = []string{"Gamora", "Groot", "Nebula", "Rocket", "Star-Lord"}
)
masterTmpl, err := template.New("master").Funcs(funcs).Parse(master)
if err != nil {
    log.Fatal(err)
}
overlayTmpl, err := template.Must(masterTmpl.Clone()).Parse(overlay)
if err != nil {
    log.Fatal(err)
}
if err := masterTmpl.Execute(os.Stdout, guardians); err != nil {
    log.Fatal(err)
}
if err := overlayTmpl.Execute(os.Stdout, guardians); err != nil {
    log.Fatal(err)
}

Вывод:

Names:
- Gamora
- Groot
- Nebula
- Rocket
- Star-Lord
Names: Gamora, Groot, Nebula, Rocket, Star-Lord

Пример (Функция)

Этот пример демонстрирует пользовательскую функцию для обработки текста шаблона. Она устанавливает функцию strings.Title и использует её, чтобы сделать текст заголовка привлекательным в выводе шаблона.

Код:

// First we create a FuncMap with which to register the function.
funcMap := template.FuncMap{
    // The name "title" is what the function will be called in the template text.
    "title": strings.Title,
}

// A simple template definition to test our function.
// We print the input text several ways:
// - the original
// - title-cased
// - title-cased and then printed with %q
// - printed with %q and then title-cased.
const templateText = `
Input: {{printf "%q" .}}
Output 0: {{title .}}
Output 1: {{title . | printf "%q"}}
Output 2: {{printf "%q" . | title}}
`

// Create a template, add the function map, and parse the text.
tmpl, err := template.New("titleTest").Funcs(funcMap).Parse(templateText)
if err != nil {
    log.Fatalf("parsing: %s", err)
}

// Run the template to verify the output.
err = tmpl.Execute(os.Stdout, "the go programming language")
if err != nil {
    log.Fatalf("execution: %s", err)
}

Вывод:

Input: "the go programming language"
Output 0: The Go Programming Language
Output 1: "The Go Programming Language"
Output 2: "The Go Programming Language"

Пример (Glob)

Здесь мы демонстрируем загрузку набора шаблонов из каталога.

Код:

// Here we create a temporary directory and populate it with our sample
// template definition files; usually the template files would already
// exist in some location known to the program.
dir := createTestDir([]templateFile{
    // T0.tmpl is a plain template file that just invokes T1.
    {"T0.tmpl", `T0 invokes T1: ({{template "T1"}})`},
    // T1.tmpl defines a template, T1 that invokes T2.
    {"T1.tmpl", `{{define "T1"}}T1 invokes T2: ({{template "T2"}}){{end}}`},
    // T2.tmpl defines a template T2.
    {"T2.tmpl", `{{define "T2"}}This is T2{{end}}`},
})
// Clean up after the test; another quirk of running as an example.
defer os.RemoveAll(dir)

// pattern is the glob pattern used to find all the template files.
pattern := filepath.Join(dir, "*.tmpl")

// Here starts the example proper.
// T0.tmpl is the first name matched, so it becomes the starting template,
// the value returned by ParseGlob.
tmpl := template.Must(template.ParseGlob(pattern))

err := tmpl.Execute(os.Stdout, nil)
if err != nil {
    log.Fatalf("template execution: %s", err)
}

Вывод:

T0 invokes T1: (T1 invokes T2: (This is T2))

Пример (Вспомогательные функции)

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

Код:

// Here we create a temporary directory and populate it with our sample
// template definition files; usually the template files would already
// exist in some location known to the program.
dir := createTestDir([]templateFile{
    // T1.tmpl defines a template, T1 that invokes T2.
    {"T1.tmpl", `{{define "T1"}}T1 invokes T2: ({{template "T2"}}){{end}}`},
    // T2.tmpl defines a template T2.
    {"T2.tmpl", `{{define "T2"}}This is T2{{end}}`},
})
// Clean up after the test; another quirk of running as an example.
defer os.RemoveAll(dir)

// pattern is the glob pattern used to find all the template files.
pattern := filepath.Join(dir, "*.tmpl")

// Here starts the example proper.
// Load the helpers.
templates := template.Must(template.ParseGlob(pattern))
// Add one driver template to the bunch; we do this with an explicit template definition.
_, err := templates.Parse("{{define `driver1`}}Driver 1 calls T1: ({{template `T1`}})\n{{end}}")
if err != nil {
    log.Fatal("parsing driver1: ", err)
}
// Add another driver template.
_, err = templates.Parse("{{define `driver2`}}Driver 2 calls T2: ({{template `T2`}})\n{{end}}")
if err != nil {
    log.Fatal("parsing driver2: ", err)
}
// We load all the templates before execution. This package does not require
// that behavior but html/template's escaping does, so it's a good habit.
err = templates.ExecuteTemplate(os.Stdout, "driver1", nil)
if err != nil {
    log.Fatalf("driver1 execution: %s", err)
}
err = templates.ExecuteTemplate(os.Stdout, "driver2", nil)
if err != nil {
    log.Fatalf("driver2 execution: %s", err)
}

Вывод:

Driver 1 calls T1: (T1 invokes T2: (This is T2))
Driver 2 calls T2: (This is T2)

Пример (Общий доступ)

Этот пример демонстрирует, как использовать одну группу шаблонов-драйверов с отдельными наборами вспомогательных шаблонов.

Код:

// Here we create a temporary directory and populate it with our sample
// template definition files; usually the template files would already
// exist in some location known to the program.
dir := createTestDir([]templateFile{
    // T0.tmpl is a plain template file that just invokes T1.
    {"T0.tmpl", "T0 ({{.}} version) invokes T1: ({{template `T1`}})\n"},
    // T1.tmpl defines a template, T1 that invokes T2. Note T2 is not defined
    {"T1.tmpl", `{{define "T1"}}T1 invokes T2: ({{template "T2"}}){{end}}`},
})
// Clean up after the test; another quirk of running as an example.
defer os.RemoveAll(dir)

// pattern is the glob pattern used to find all the template files.
pattern := filepath.Join(dir, "*.tmpl")

// Here starts the example proper.
// Load the drivers.
drivers := template.Must(template.ParseGlob(pattern))

// We must define an implementation of the T2 template. First we clone
// the drivers, then add a definition of T2 to the template name space.

// 1. Clone the helper set to create a new name space from which to run them.
first, err := drivers.Clone()
if err != nil {
    log.Fatal("cloning helpers: ", err)
}
// 2. Define T2, version A, and parse it.
_, err = first.Parse("{{define `T2`}}T2, version A{{end}}")
if err != nil {
    log.Fatal("parsing T2: ", err)
}

// Now repeat the whole thing, using a different version of T2.
// 1. Clone the drivers.
second, err := drivers.Clone()
if err != nil {
    log.Fatal("cloning drivers: ", err)
}
// 2. Define T2, version B, and parse it.
_, err = second.Parse("{{define `T2`}}T2, version B{{end}}")
if err != nil {
    log.Fatal("parsing T2: ", err)
}

// Execute the templates in the reverse order to verify the
// first is unaffected by the second.
err = second.ExecuteTemplate(os.Stdout, "T0.tmpl", "second")
if err != nil {
    log.Fatalf("second execution: %s", err)
}
err = first.ExecuteTemplate(os.Stdout, "T0.tmpl", "first")
if err != nil {
    log.Fatalf("first: execution: %s", err)
}

Вывод:

T0 (second version) invokes T1: (T1 invokes T2: (T2, version B))
T0 (first version) invokes T1: (T1 invokes T2: (T2, version A))

функция Must

func Must(t *Template, err error) *Template

Must — это вспомогательная функция, которая оборачивает вызов функции, возвращающей (*Template, error), и вызывает панику, если ошибка не nil. Она предназначена для использования при инициализации переменных, таких как

var t = template.Must(template.New("name").Parse("text"))

функция New

func New(name string) *Template

New выделяет новый, неопределённый шаблон с заданным именем.

функция ParseFS 1.16

func ParseFS(fsys fs.FS, patterns ...string) (*Template, error)

ParseFS подобна Template.ParseFiles или Template.ParseGlob, но читает из файловой системы fsys вместо файловой системы хоста операционной системы. Она принимает список шаблонов соответствия (см. path.Match). (Обратите внимание, что большинство имён файлов служат шаблонами соответствия, соответствующими только себе.)

функция ParseFiles

func ParseFiles(filenames ...string) (*Template, error)

ParseFiles создаёт новый Template и обрабатывает определения шаблонов из именованных файлов. Имя возвращаемого шаблона будет иметь имя базового файла и обработанное содержимое первого файла. Должен быть хотя бы один файл. Если произошла ошибка, обработка останавливается, и возвращаемый *Template равен nil.

При обработке нескольких файлов с одинаковым именем в разных каталогах, последним указанный будет результатом. Например, ParseFiles("a/foo", "b/foo") сохраняет "b/foo" в качестве шаблона с именем "foo", а "a/foo" недоступен.

функция ParseGlob

func ParseGlob(pattern string) (*Template, error)

ParseGlob создаёт новый Template и обрабатывает определения шаблонов из файлов, идентифицируемых шаблоном. Файлы сопоставляются в соответствии с семантикой filepath.Match, и шаблон должен соответствовать хотя бы одному файлу. Возвращаемый шаблон будет иметь имя filepath.Base и (обработанное) содержимое первого файла, соответствующего шаблону. ParseGlob эквивалентно вызову ParseFiles со списком файлов, соответствующих шаблону.

При обработке нескольких файлов с одинаковым именем в разных каталогах, последним указанный будет результатом.

функция (*Template) AddParseTree

func (t *Template) AddParseTree(name string, tree *parse.Tree) (*Template, error)

AddParseTree связывает аргумент parse-дерево с шаблоном t, присваивая ему указанное имя. Если шаблон не определён, это дерево становится его определением. Если он определён и уже имеет это имя, существующее определение заменяется; в противном случае создаётся новый шаблон, определяется и возвращается.

функция (*Template) Clone

func (t *Template) Clone() (*Template, error)

Clone возвращает копию шаблона, включая все связанные шаблоны. Фактическое представление не копируется, но пространство имён связанных шаблонов — да, поэтому последующие вызовы Template.Parse в копии будут добавлять шаблоны в копию, а не в оригинал. Clone можно использовать для подготовки общих шаблонов и их использования с вариантами определений для других шаблонов путём добавления вариантов после создания копии.

функция (*Template) DefinedTemplates 1.5

func (t *Template) DefinedTemplates() string

DefinedTemplates возвращает строку, перечисляющую определенные шаблоны, с префиксом «; определенные шаблоны:». Если их нет, возвращается пустая строка. Для генерации сообщения об ошибке здесь и в html/template.

func (*Template) Delims

func (t *Template) Delims(left, right string) *Template

Delims устанавливает разделители действий на указанные строки, которые будут использоваться в последующих вызовах Template.Parse, Template.ParseFiles или Template.ParseGlob. Вложенные определения шаблонов будут наследовать настройки. Пустой разделитель соответствует соответствующему значению по умолчанию: {{ или }}. Возвращаемое значение — шаблон, поэтому вызовы могут быть объединены.

func (*Template) Execute

func (t *Template) Execute(wr io.Writer, data any) error

Execute применяет проанализированный шаблон к указанному объекту данных и записывает вывод в wr. Если при выполнении шаблона или записи его вывода возникает ошибка, выполнение прекращается, но частичные результаты могут быть уже записаны в писатель вывода. Шаблон можно безопасно выполнять параллельно, хотя при параллельном выполнении, если писатели вывода разделены, вывод может быть перемешан.

Если data — reflect.Value, шаблон применяется к конкретному значению, которое хранит reflect.Value, как в fmt.Print.

func (*Template) ExecuteTemplate

func (t *Template) ExecuteTemplate(wr io.Writer, name string, data any) error

ExecuteTemplate применяет шаблон, связанный с t, имеющий заданное имя, к указанному объекту данных и записывает вывод в wr. Если при выполнении шаблона или записи его вывода возникает ошибка, выполнение прекращается, но частичные результаты могут быть уже записаны в писатель вывода. Шаблон можно безопасно выполнять параллельно, хотя при параллельном выполнении, если писатели вывода разделены, вывод может быть перемешан.

func (*Template) Funcs

func (t *Template) Funcs(funcMap FuncMap) *Template

Funcs добавляет элементы аргументного отображения в отображение функций шаблона. Его необходимо вызвать до анализа шаблона. Он вызывает панику, если значение в отображении не является функцией с соответствующим типом возврата или если имя не может быть синтаксически использовано в качестве функции в шаблоне. Разрешается перезаписывать элементы отображения. Возвращаемое значение — шаблон, поэтому вызовы могут быть объединены.

func (*Template) Lookup

func (t *Template) Lookup(name string) *Template

Lookup возвращает шаблон с заданным именем, связанный с t. Возвращает nil, если такого шаблона нет или шаблон не определен.

func (*Template) Name

func (t *Template) Name() string

Name возвращает имя шаблона.

func (*Template) New

func (t *Template) New(name string) *Template

New выделяет новый, неопределенный шаблон, связанный с заданным и имеющий те же разделители. Связь, которая является транзитивной, позволяет одному шаблону вызывать другой с помощью действия {{template}}.

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

func (*Template) Option 1.5

func (t *Template) Option(opt ...string) *Template

Option устанавливает параметры для шаблона. Параметры описываются строками, либо простой строкой, либо «ключ=значение». В строке параметра может быть не более одного знака равенства. Если строка параметра не распознается или является недействительной, Option вызывает панику.

Известные параметры:

missingkey: Управление поведением при выполнении, если к отображению обращается с ключом, отсутствующим в отображении.

"missingkey=default" or "missingkey=invalid"
	The default behavior: Do nothing and continue execution.
	If printed, the result of the index operation is the string
	"<no value>".
"missingkey=zero"
	The operation returns the zero value for the map type's element.
"missingkey=error"
	Execution stops immediately with an error.

func (*Template) Parse

func (t *Template) Parse(text string) (*Template, error)

Parse анализирует текст как тело шаблона для t. Определения именованных шаблонов (выражения {{define ...}} или {{block ...}}) в тексте определяют дополнительные шаблоны, связанные с t, и удаляются из определения самого t.

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

func (*Template) ParseFS 1.16

func (t *Template) ParseFS(fsys fs.FS, patterns ...string) (*Template, error)

ParseFS подобен Template.ParseFiles или Template.ParseGlob, но считывает из файловой системы fsys вместо файловой системы хост-операционной системы. Принимает список шаблонов совпадения (см. path.Match). (Обратите внимание, что большинство имён файлов служат шаблонами совпадения, соответствующими только себе.)

func (*Template) ParseFiles

func (t *Template) ParseFiles(filenames ...string) (*Template, error)

ParseFiles анализирует указанные файлы и связывает полученные шаблоны с t. Если возникает ошибка, анализ останавливается, и возвращаемый шаблон равен nil; в противном случае — t. Должен быть хотя бы один файл. Поскольку шаблоны, созданные ParseFiles, именуются базовыми именами (см. filepath.Base) файлов аргументов, t обычно должен иметь имя одного из базовых имён файлов. Если это не так, в зависимости от содержимого t до вызова ParseFiles, t.Execute может завершиться неудачей. В этом случае используйте t.ExecuteTemplate для выполнения допустимого шаблона.

При анализе нескольких файлов с одинаковым именем в разных каталогах, последним указанным будет тот, который получится.

func (*Template) ParseGlob

func (t *Template) ParseGlob(pattern string) (*Template, error)

ParseGlob анализирует определения шаблонов в файлах, идентифицированных шаблоном, и связывает полученные шаблоны с t. Файлы сопоставляются в соответствии с семантикой filepath.Match, и шаблон должен соответствовать хотя бы одному файлу. ParseGlob эквивалентен вызову Template.ParseFiles со списком файлов, соответствующих шаблону.

При анализе нескольких файлов с одинаковым именем в разных каталогах, последним указанным будет тот, который получится.

func (*Template) Templates

func (t *Template) Templates() []*Template

Templates возвращает срез определенных шаблонов, связанных с t.

Подкаталоги

Имя Описание
..
parse Пакет parse строит деревья разбора для шаблонов, как определено в text/template и html/template.

© Google, Inc.
Licensed under the Creative Commons Attribution License 3.0.
http://golang.org/pkg/text/template/

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API