Борьба с вложенностью шаблонов golang html

#go #templates

# #Вперед #шаблоны

Вопрос:

Я все еще борюсь с шаблонами golang. Я могу заставить их работать. Но не так, как мне нужно.

Я хотел бы иметь мастер layout.gohtml , который затем анализирует шаблон страницы thispage.gohtml . Я хочу, чтобы мастер был полным макетом с {{template "title" .}} {{template "content" .}} , и т.д. Тогда шаблон страницы будет содержать изменяющийся контент с {{define ...}} помощью etc…

Я могу заставить это работать, если я буду анализировать шаблоны по каждому запросу и без FuncMaps. Но я хотел бы проанализировать их один раз и назвать их по имени. Этого я не могу сделать. Я просто получаю пустую страницу без ошибок. Застрял на этом в течение нескольких дней.

Я также хотел бы добавить некоторые пользовательские функции в FuncMaps для форматирования и т. Д. И это я не могу заставить работать в этом вложенном сценарии. Это работает для меня в более простых не вложенных сценариях.

Может кто-нибудь, пожалуйста, взглянуть на мой код и сказать мне, где я ошибаюсь? Вывод из этого просто пустой, и отладка (в vscode), похоже, не показывает ничего очевидного. Спасибо…

Этот код выдает пустую страницу и ошибок нет… Ожидаемый результат — это отображаемая страница на основе шаблонов… И tmpl.Execute без имени имеет тот же пустой результат.

 // Show handler
func Show(w http.ResponseWriter, r *http.Request) {
    var page models.Page
    name := mux.Vars(r)["name"]

    switch r.Method {
    case "GET":

        if name != "" {
            page = models.GetPageByName(name)
        } else {
            page = models.GetPageByName("home")
        }

        data := make(map[string]interface{})
        data["Page"] = page

        funcMap := template.FuncMap{
            "toupper": strings.ToUpper,
        }

        var err error
        tmpl := template.New("show").Funcs(funcMap)
        tmpl, err = tmpl.ParseFiles("templates/layout.gohtml", "templates/show.gohtml")
        if err != nil {
            fmt.Println(err)
        }
        // err = tmpl.ExecuteTemplate(w, "show", data)
        err = tmpl.Execute(w, data)
        if err != nil {
            fmt.Println(err)
        }
    }
}
 

layout.gohtml:

 <!doctype html>
<html lang="en">
<head>
    <title>{{block "title" .}}Default Title{{end}}</title>
</head>
<body>
    <nav>...</nav>
    <div class="container">
        {{template "content" .}}
    </div>
</body>
</html>
 

show.gohtml:

 {{define "title"}}{{.Page.Title}}{{end}}
{{define "content"}} 

    <h1>{{.Page.Title}}</h1>

    {{.Page.Content}}

{{end}}
 

Комментарии:

1. Итак, вы говорите, что опубликованный вами код работает? Если да, пожалуйста, покажите код, который этого не делает. Если это не сработает, пожалуйста, укажите, какие у вас проблемы и каковы фактические и ожидаемые результаты. Также ExecuteTemplate() возвращает ошибку, проверьте это.

2. Этот код выдает пустую страницу и ошибок нет… Ожидаемый результат — это отображаемая страница на основе шаблонов… И tmpl.Execute без имени имеет тот же пустой результат. Я уверен, что мне не хватает чего-то довольно глупого. Я думаю, что это как-то связано с присвоением имен шаблонам.

3. Опять же, ExecuteTemplate() и Execute() оба возвращают ошибку, проверьте это. Опубликованный вами код не проверяет эту ошибку.

4. Если я ссылаюсь на layout.gohtml, это работает. Кроме того, layout — это универсальный компонент, который должен использоваться на нескольких страницах. контент — это шаблон, специфичный для страницы. Моя проблема, вероятно, связана с порядком вложенности и именования … т. Е. Моя цель — иметь layout:common content: specific…

5. Помогла проверка ошибки при выполнении… Если я использую err = tmpl.Execute(w, data) , я получаю template: show: "show" is an incomplete or empty template и что-то подобное с ExecuteTemplate template: no template "show" associated with template "show" . Пустой шаблон — это моя пустая страница… Но почему он пустой???