2016-12-16 4 views
9

В html/templatetext/template) пакетов, template.New имеет следующую подпись:Go имя шаблона

func New(name string) *Template 

Что именно это name используется для? Я просмотрел документы (и немного источников), но безрезультатно. Я просто создаю все мои шаблоны с пустой строкой, и это, похоже, не имеет значения. Почему я должен беспокоиться о названии?

Даже для именования шаблонов, два кажутся эквивалентными:

template.Must(template.New("").Parse(`{{ define "body" }}Body{{ end }}`)) 
template.Must(template.New("body").Parse(`Body`)) 

https://play.golang.org/p/wKzCHdLf2S

ответ

10

Название шаблона - неудивительно, что - имя шаблон.

Для чего это полезно? Пока вы не хотите, чтобы ссылался на шаблон, это на самом деле не имеет значения. Но если вы хотите, чтобы ссылались на, то да, вы ссылаетесь на него своим именем.

Когда бы вы хотели это навестить? Если вы хотите включить шаблон в другой, например. используя действие {{template}} или когда вы хотите выполнить конкретный шаблон с помощью Template.ExecuteTemplate().

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

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

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

Когда вы разбираете несколько шаблонов сразу, используя Template.ParseFiles() или Template.ParseGlob(), то шаблоны будут названы по имени файла, и они будут связаны автоматически (упомянутые выше функции возвращают одно template.Template значение, которое держит все проанализированные шаблоны, связанные).Док Template.ParseFiles():

ParseFiles создает новый шаблон и анализирует определения шаблона из названных файлов. Имя возвращаемого шаблона будет иметь базовое имя и проанализированное содержимое первого файла. [...]

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

Имя шаблона может поступать из нескольких мест:

  • он может прийти от имени файла (как показано выше)
  • может быть задан явно (если они определены с помощью {{define "somename"}} или {{block "somename"}} действия),
  • или он может быть определен как аргумент, переданный template.New() (функция) или Template.New() (метод).

Давайте рассмотрим несколько примеров:

func main() { 
    t := template.Must(template.New("one").Parse(t1src)) 
    template.Must(t.New("other").Parse(t2src)) 

    // error checks omitted for brevity 
    // Executes default, "one": 
    t.Execute(os.Stdout, nil) 

    // Executes explicit, "one": 
    t.ExecuteTemplate(os.Stdout, "one", nil) 

    // Executes explicit, "other": 
    t.ExecuteTemplate(os.Stdout, "other", nil) 
} 

const t1src = `I'm some template. 
` 
const t2src = `I'm some OTHER template. 
` 

Output (попробовать его на Go Playground):

I'm some template. 
I'm some template. 
I'm some OTHER template. 

Если теперь идти вперед и изменить первые 2 строки в этом:

t := template.Must(template.New("one").Parse(t1src)) 
t = template.Must(t.New("other").Parse(t2src)) 

Тогда что здесь происходит, так это то, что мы assi gned новое значение template.Template до t, которое было результатом разбора t2src, так что это будет значение по умолчанию, но оба шаблона могут быть «достигнуты» от него, поскольку они связаны. Выходные изменения этого (попробуйте на Go Playground):

I'm some OTHER template. 
I'm some template. 
I'm some OTHER template. 

template.New() Вызова (функции) создает новый шаблон, связанный нет. При вызове метода Template.New() (метод) возвращаемый шаблон будет связан с (все) шаблоном (ами), вызываемым методом.

Теперь давайте посмотрим некоторые примеры «встроенных» шаблонов.

func main() { 
    t := template.Must(template.New("one").Parse(t1src)) 
    template.Must(t.New("other").Parse(t2src)) 
    template.Must(t.New("third").Parse(t3src)) 

    t.Execute(os.Stdout, nil) 
    t.ExecuteTemplate(os.Stdout, "one", nil) 
    t.ExecuteTemplate(os.Stdout, "other", nil) 
    t.ExecuteTemplate(os.Stdout, "embedded", nil) 
    t.ExecuteTemplate(os.Stdout, "third", nil) 
} 

const t1src = `I'm some template. {{block "embedded" .}}I'm embedded in "one". 
{{end}}` 
const t2src = `I'm some OTHER template. 
` 
const t3src = `I'm the 3rd, including everything from "one": {{template "one"}} 
` 

Output (попробуйте на Go Playground):

I'm some template. I'm embedded in "one". 
I'm some template. I'm embedded in "one". 
I'm some OTHER template. 
I'm embedded in "one". 
I'm the 3rd, including everything from "one": I'm some template. I'm embedded in "one". 

Это должно быть очевидно, что теперь роль имени шаблона, а где оно происходит от.

4

Он используется для визуализации связанных с ними шаблонов.

Например:

tmpl := template.Must(template.New("body").Parse(` 
    {{ define "body" }} 
     Body 
    {{ end }} 
    `)) 

tmpl = template.Must(tmpl.New("base").Parse(` 
    Start of base template 

    {{ template "body" }} 

    End of base template 
    `)) 

tmpl = template.Must(tmpl.New("baz").Parse(` 
    Start of baz template 

    {{ template "body" }} 

    End of baz template 
    `)) 

tmpl.ExecuteTemplate(os.Stdout, "base", nil) 
tmpl.ExecuteTemplate(os.Stdout, "baz", nil) 

Play Example

Выход:

 Start of base template 


     Body 


    End of base template 

    Start of baz template 


     Body 


    End of baz template 

tmpl.ExecuteTemplate(os.Stdout, "base", nil) будет оказывать шаблон с использованием "базового" шаблон

tmpl.ExecuteTemplate(os.Stdout, "baz", nil) будет оказывать шаблон с использованием «б az "template

+0

За исключением того, что если я изменю эту первую строку на 'template.New (" "), то она будет работать так же хорошо. https://play.golang.org/p/zQoGalIxFq Но я думаю, что вы на что-то. 'ExecuteTemplate', похоже, не работает, не называя шаблон« base ». – Dave

+0

Вот такой же пример, но с пустыми строками для всех имен шаблонов. https://play.golang.org/p/0NdJ1j_ype Похоже, что '{{define" name "}}' работает как альтернатива именованию шаблона в методе 'New'. – Dave

+0

@Dave Я добавил третий шаблон, чтобы лучше проиллюстрировать утилиту именованного шаблона. – jmaloney

Смежные вопросы