Функция ParseFiles в Go Template для анализа нескольких файлов

Что произойдет, если я передам два или более файла функции ParseFiles в Go Template?

func (*Template) ParseFiles

Это помогает говорит:

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

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

Но я все еще не уверен, какие различия будут влиять на результат, поскольку

MyTempl.ParseFiles(tf1)

vs.

MyTempl.ParseFiles(tf1, tf2)

Будет ли содержимое tf2 добавлено к содержимому tf1?


person xpt    schedule 07.07.2017    source источник


Ответы (1)


Сначала немного о концепции "шаблона":

Значение template.Template - это "представление проанализированного шаблона" . Но формулировка здесь немного «несовершенная». Значение template.Template может быть (и обычно является) коллекцией нескольких связанных шаблонов. template.Template имеет неэкспортированное поле:

tmpl   map[string]*Template // Map from name to defined templates.

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

Подробнее об этом можно прочитать в этом ответе: Имя шаблона Go

Вернемся к методу Template.ParseFiles(). Этот метод анализирует несколько шаблонов из файлов, переданных ему в качестве параметров. Шаблоны, проанализированные из файлов, будут названы по именам файлов (без папок, только по имени файла), и они будут добавлены во внутреннюю связанную карту шаблонов шаблона t, назначенного получателем метода.

Разобранные шаблоны добавляться не будут. Для них будет создано несколько отдельных template.Template значений, но они будут связаны (чтобы они могли ссылаться друг на друга, например, они могут включать друг друга).

Посмотрим на пример. Предположим, у нас есть эти 2 файла шаблона:

a.html is:

I'm a.

И b.html:

I'm b.

И пример кода:

t := template.New("a.html")
if _, err := t.ParseFiles("a.html", "b.html"); err != nil {
    panic(err)
}
if err := t.Execute(os.Stdout, nil); err != nil {
    panic(err)
}

В этом примере создается новый пустой шаблон с именем a.html, а затем анализируются 2 файла: a.html и b.html.

Что будет в результате? t будет обозначать шаблон a.html, потому что мы создали его ранее с этим конкретным именем. Запустив код, вы получите следующий результат:

I'm a.

Теперь, если мы изменим первую строку на:

t := template.New("x.html")

А остальное оставим без изменений, запустив его видим нечто похожее:

panic: template: "x.html" is an incomplete or empty template

Причина в том, что t обозначает шаблон с именем x.html, но он пуст, поскольку мы ничего не анализировали "в" его, и проанализированные файлы также не соответствовали имени x.html. Поэтому попытка его выполнить приводит к ошибке.

Теперь, если мы попытаемся выполнить один из связанных с ним именованных шаблонов:

if err := t.ExecuteTemplate(os.Stdout, "a.html", nil); err != nil {
    panic(err)
}

Это удается, и снова дает:

I'm a.
person icza    schedule 07.07.2017
comment
Кристально чистый! Спасибо, что прошли все девять ярдов! - person xpt; 08.07.2017