package templates import ( "fmt" "html/template" "net/http" "strings" "time" "git.kirsle.net/apps/gosocial/pkg/config" "git.kirsle.net/apps/gosocial/pkg/markdown" "git.kirsle.net/apps/gosocial/pkg/photo" "git.kirsle.net/apps/gosocial/pkg/session" "git.kirsle.net/apps/gosocial/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] } }, "Substring": func(value string, n int) string { if n > len(value) { return value } return value[:n] }, } } // 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 { var result = func(text string, v int64) template.HTML { if v == 1 { text = strings.TrimSuffix(text, "s") } return template.HTML(fmt.Sprintf(text, v)) } return func(since time.Time) template.HTML { var ( duration = time.Since(since) ) if duration.Seconds() < 60.0 { return result("%d seconds", int64(duration.Seconds())) } if duration.Minutes() < 60.0 { return result("%d minutes", int64(duration.Minutes())) } if duration.Hours() < 24.0 { return result("%d hours", int64(duration.Hours())) } days := int64(duration.Hours() / 24) if days < 30 { return result("%d days", days) } months := int64(days / 30) if months < 12 { return result("%d months", months) } years := int64(days / 365) return result("%d years", years) } } // ToMarkdown renders input text as Markdown. func ToMarkdown(input string) template.HTML { return template.HTML(markdown.Render(input)) }