package templates import ( "fmt" "html/template" "net/http" "net/url" "strings" "time" "code.nonshy.com/nonshy/website/pkg/config" "code.nonshy.com/nonshy/website/pkg/markdown" "code.nonshy.com/nonshy/website/pkg/photo" "code.nonshy.com/nonshy/website/pkg/session" "code.nonshy.com/nonshy/website/pkg/utility" ) // TemplateFuncs available to all pages. func TemplateFuncs(r *http.Request) template.FuncMap { return template.FuncMap{ "InputCSRF": InputCSRF(r), "SincePrettyCoarse": SincePrettyCoarse(), "ComputeAge": utility.Age, "Split": strings.Split, "ToMarkdown": ToMarkdown, "PhotoURL": photo.URLPath, "Now": time.Now, "PrettyTitle": func() template.HTML { return template.HTML(fmt.Sprintf( `non` + `shy`, )) }, "Pluralize64": func(count int64, labels ...string) string { if len(labels) < 2 { labels = []string{"", "s"} } if count == 1 { return labels[0] } else { return labels[1] } }, "Pluralize": func(count int, labels ...string) string { if len(labels) < 2 { labels = []string{"", "s"} } if count == 1 { return labels[0] } else { return labels[1] } }, "Substring": func(value string, n int) string { if n > len(value) { return value } return value[:n] }, "TrimEllipses": func(value string, n int) string { if n > len(value) { return value } return value[:n] + "…" }, "IterRange": func(start, n int) []int { var result = []int{} for i := start; i <= n; i++ { result = append(result, i) } return result }, "SubtractInt": func(a, b int) int { return a - b }, "UrlEncode": func(values ...interface{}) string { var result string for _, value := range values { result += url.QueryEscape(fmt.Sprintf("%v", value)) } return result }, } } // InputCSRF returns the HTML snippet for a CSRF token hidden input field. func InputCSRF(r *http.Request) func() template.HTML { return func() template.HTML { ctx := r.Context() if token, ok := ctx.Value(session.CSRFKey).(string); ok { return template.HTML(fmt.Sprintf( ``, config.CSRFInputName, token, )) } else { return template.HTML(`[CSRF middleware error]`) } } } // SincePrettyCoarse formats a time.Duration in plain English. Intended for "joined 2 months ago" type // strings - returns the coarsest level of granularity. func SincePrettyCoarse() func(time.Time) template.HTML { return func(since time.Time) template.HTML { return template.HTML(utility.FormatDurationCoarse(time.Since(since))) } } // ToMarkdown renders input text as Markdown. func ToMarkdown(input string) template.HTML { return template.HTML(markdown.Render(input)) }