reprogl

Форк
0
/
templating.go 
198 строк · 5.1 Кб
1
package views
2

3
import (
4
	"context"
5
	"embed"
6
	"fmt"
7
	"html/template"
8
	"net/http"
9
	"strings"
10

11
	"xelbot.com/reprogl/container"
12
	"xelbot.com/reprogl/security"
13
	"xelbot.com/reprogl/session"
14
)
15

16
const defaultPageSize = 64 * 1024
17

18
var (
19
	//go:embed templates markdown
20
	sources embed.FS
21

22
	templates map[string]*template.Template
23
)
24

25
func init() {
26
	templates = make(map[string]*template.Template)
27
}
28

29
func LoadViewSet() error {
30
	templatesMap := map[string][]string{
31
		"about.gohtml": {
32
			"templates/about.gohtml",
33
			"templates/partials/menu.gohtml",
34
			"templates/partials/sticky-header.gohtml",
35
			"templates/partials/big-header.gohtml",
36
			"templates/partials/footer.gohtml",
37
			"templates/partials/social-icons.gohtml",
38
			"templates/layout/svg-sprites.gohtml",
39
			"templates/layout/base.gohtml",
40
		},
41
		"article.gohtml": {
42
			"templates/article.gohtml",
43
			"templates/partials/author-info.gohtml",
44
			"templates/partials/comment-form.gohtml",
45
			"templates/partials/menu.gohtml",
46
			"templates/partials/sidebar.gohtml",
47
			"templates/partials/social-icons.gohtml",
48
			"templates/partials/powered-by.gohtml",
49
			"templates/layout/svg-auth.gohtml",
50
			"templates/layout/svg-sprites.gohtml",
51
			"templates/layout/base.gohtml",
52
		},
53
		"statistics.gohtml": {
54
			"templates/statistics.gohtml",
55
			"templates/partials/author-info.gohtml",
56
			"templates/partials/menu.gohtml",
57
			"templates/partials/sidebar.gohtml",
58
			"templates/partials/social-icons.gohtml",
59
			"templates/partials/powered-by.gohtml",
60
			"templates/layout/svg-sprites.gohtml",
61
			"templates/layout/base.gohtml",
62
		},
63
		"profile.gohtml": {
64
			"templates/profile.gohtml",
65
			"templates/partials/profile-form.gohtml",
66
			"templates/partials/menu.gohtml",
67
			"templates/partials/sidebar.gohtml",
68
			"templates/partials/social-icons.gohtml",
69
			"templates/layout/svg-sprites.gohtml",
70
			"templates/layout/base.gohtml",
71
		},
72
		"index.gohtml": {
73
			"templates/index.gohtml",
74
			"templates/partials/menu.gohtml",
75
			"templates/partials/sticky-header.gohtml",
76
			"templates/partials/big-header.gohtml",
77
			"templates/partials/footer.gohtml",
78
			"templates/partials/social-icons.gohtml",
79
			"templates/layout/svg-sprites.gohtml",
80
			"templates/layout/base.gohtml",
81
		},
82
		"categories.gohtml": {
83
			"templates/fragments/categories.gohtml",
84
		},
85
		"comments.gohtml": {
86
			"templates/fragments/comments.gohtml",
87
		},
88
		"recent-posts.gohtml": {
89
			"templates/fragments/recent-posts.gohtml",
90
		},
91
		"login.gohtml": {
92
			"templates/auth/login.gohtml",
93
		},
94
		"auth-navigation.gohtml": {
95
			"templates/fragments/auth-navigation.gohtml",
96
		},
97
		"menu-auth.gohtml": {
98
			"templates/fragments/menu-auth.gohtml",
99
		},
100
		"unsubscribe.gohtml": {
101
			"templates/unsubscribe.gohtml",
102
		},
103
		"oauth-pending.gohtml": {
104
			"templates/oauth/oauth-pending.gohtml",
105
		},
106
	}
107

108
	customFunctions := template.FuncMap{
109
		"raw":           rawHTML,
110
		"is_dev":        func() bool { return container.IsDevMode() },
111
		"path":          urlGenerator,
112
		"abs_path":      absUrlGenerator,
113
		"render_esi":    renderESI,
114
		"tags":          tags,
115
		"cdn":           cdnBase,
116
		"nl2br":         nl2br,
117
		"author_bio":    authorBio,
118
		"author_data":   authorDataPart,
119
		"author_adr":    authorLocation,
120
		"author_job":    authorJob,
121
		"author_avatar": authorAvatar,
122
		"substr":        subString,
123
		"time_tag":      timeTag,
124
		"asset":         assetTag,
125
		"go_version":    func() string { return container.GoVersionNumbers },
126
		"commit_hash":   func() string { return container.GitRevision },
127
		"cnt_comments":  commentsCountString,
128
		"cnt_times":     timesCountString,
129
		"flag_cnt":      flagCounterImage(true),
130
		"flag_cnt_mini": flagCounterImage(false),
131
		"emojiFlag":     emojiFlag,
132

133
		"articleStyles":    articleStyles,
134
		"statisticsStyles": statisticsStyles,
135
		"indexStyles":      indexStyles,
136
		"infoStyles":       infoStyles,
137
		"profileStyles":    profileStyles,
138
	}
139

140
	for key, files := range templatesMap {
141
		tmpl, err := template.New(key).Funcs(customFunctions).ParseFS(sources, files...)
142
		if err != nil {
143
			return err
144
		}
145

146
		templates[key] = tmpl
147
	}
148

149
	return nil
150
}
151

152
func RenderTemplate(name string, data interface{}) (string, error) {
153
	tmpl, ok := templates[name]
154
	if !ok {
155
		return "", fmt.Errorf("the template %s does not exist", name)
156
	}
157

158
	var buf strings.Builder
159
	buf.Grow(defaultPageSize)
160

161
	err := tmpl.Execute(&buf, data)
162
	if err != nil {
163
		return "", err
164
	}
165

166
	return buf.String(), nil
167
}
168

169
func WriteTemplate(w http.ResponseWriter, name string, data any) error {
170
	content, err := RenderTemplate(name, data)
171
	if err != nil {
172
		return err
173
	}
174

175
	w.Header().Set("Content-Type", "text/html; charset=utf-8")
176
	w.Header().Set("Surrogate-Control", "content=\"ESI/1.0\"")
177
	_, err = w.Write([]byte(content))
178
	if err != nil {
179
		return err
180
	}
181

182
	return nil
183
}
184

185
func WriteTemplateWithContext(ctx context.Context, w http.ResponseWriter, name string, data any) error {
186
	if flashObjectPart, ok := data.(DataWithFlashMessage); ok {
187
		if flashSuccessMessage, found := session.Pop[string](ctx, session.FlashSuccessKey); found {
188
			flashObjectPart.SetSuccessFlash(flashSuccessMessage)
189
		}
190
	}
191

192
	if identityPart, ok := data.(security.IdentityAware); ok {
193
		identity, _ := session.GetIdentity(ctx)
194
		identityPart.SetIdentity(identity)
195
	}
196

197
	return WriteTemplate(w, name, data)
198
}
199

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.