@blecked88

Как правильно вызвать метод в шаблоне Go?

Хочу сделать нечто такое:
{{ range .Posts.GetSublistByPagenumber .Number }}

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

Метод такой:
func (posts Posts) GetSublistByPagenumber(pageNumber int) Posts {

	fmt.Println("I AM IN GetSublistByPagenumber")

	if pageNumber < 1 {
		return posts[0:MAX_POSTS_ON_PAGE]
	}

	startIndex := (pageNumber - 1) * MAX_POSTS_ON_PAGE
	endIndex := startIndex + MAX_POSTS_ON_PAGE

	if startIndex >= len(posts) {
		return []Post{}
	}
	if endIndex > len(posts) {
		endIndex = len(posts)
	}
	// Возвращаем подсписок постов

	return posts[startIndex:endIndex]
}


контекст страницы такой:
func GetPageContext(c *gin.Context, pageNumber int, posts Posts, data string) *Page {
	accessLvl := getAccessLvl(c)
	return &Page{
		AccessLvl: accessLvl,
		Title:     "title",
		Posts:     posts,
		Tags:      t,
		Number:    pageNumber,
		Data:      data,
	}
}


Тип Posts, для которого определен метод:

// Структура поста
type Post struct {
	ID          int
	Author      string
	Title       string
	Body        string
	PostingTime string
	UpdateTime  string
	Tags        string
	Lock        int
}

type Posts []Post


В мапу как я понимаю методы не надо добавлять. Ну они и просто не добавляются.
Ну на всякий случай, роутинг такой:
func SetupRoutes(r *gin.Engine) {
	funcMap := template.FuncMap{
		"add":                add,
		"GetFirstSymbols":    GetFirstSymbols,
		"SplitString":        SplitString,
		"DaysSinceStartSite": DaysSinceStartSite,
		"GetRegUsersCount":   GetRegUsersCount,
		"GetDbSize":          GetDbSize,
		"CountFilesByEXT":    CountFilesByEXT,
		"getCurTime":         getCurTime,
	}

	r.SetFuncMap(funcMap)
	r.LoadHTMLGlob("templates/*")
	InitRoutes(r)
}
  • Вопрос задан
  • 83 просмотра
Пригласить эксперта
Ответы на вопрос 1
Первое, что вам порекомендую - не стоит прямо вот рабочие сущности кидать в шаблоны. Подготовьте для шаблонов специальные структуры с данными и уже без всяких методов, или хотя бы уже готовый слайс с данными. Поверьте, мизерные потери производительности при заполнении этой структуры из вашей оригинальной Posts стоят того, что выш код будет прозрачен, понятен и прост, что значительно уменьшит возможность багов.

Вот вам простейший пример:

index.html
<!doctype html>
<html lang="en">
    <head>
        <meta charset="UTF-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <title>Document</title>
    </head>
    <body>
        <!--Вот то, что я предложил -->
        <h1>Page number {{ .Number }}</h1>
        {{ range .Posts }}
        <h2>{{ .Title }}</h2>
        <p>{{ .Body }}</p>
        {{ end }}

        <!--А вот то, что вы хотели -->
        <h1>Page number {{ .Number }}</h1>
        {{ range .Posts.GetSublistByPagenumber .Number }}
        <h2>{{ .Title }}</h2>
        <p>{{ .Body }}</p>
        {{ end }}
    </body>
</html>


main.go
package main

import (
	"html/template"
	"log"
	"os"
)

// Структура поста
type Post struct {
	ID          int
	Author      string
	Title       string
	Body        string
	PostingTime string
	UpdateTime  string
	Tags        string
	Lock        int
}

type Posts []Post

func (posts Posts) GetSublistByPagenumber(pageNumber int) Posts {

	return Posts{
		Post{
			ID:          1,
			Author:      "Vitaliy",
			Title:       "First post",
			Body:        "Hello, world!",
			PostingTime: "2021-10-10 10:00:00",
			UpdateTime:  "2021-10-10 10:00:00",
			Tags:        "first, post",
			Lock:        0,
		},
		Post{
			ID:          2,
			Author:      "Alex",
			Title:       "Second post",
			Body:        "Hello, world!",
			PostingTime: "2021-10-10 10:00:00",
			UpdateTime:  "2021-10-10 10:00:00",
			Tags:        "second, post",
			Lock:        0,
		},
	}
}

// Структура с уже готовыми заполненными данными без всяких методов
type PostTemplate struct {
	Number int
	Posts  Posts
}

func main() {
	posts := Posts{}

	// Подготавливаем список заранее
	sublist := posts.GetSublistByPagenumber(1)

	postVars := PostTemplate{
		Number: 1,
		Posts:  sublist,
	}

	tmpl, err := template.ParseFiles("index.html")
	if err != nil {
		log.Println(err.Error())
		return
	}

	w := os.Stdout

	err = tmpl.Execute(w, postVars)
	if err != nil {
		log.Println(err.Error())
	}

}
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы