From b738f38af8551021f77ad759425063d06e3c80de Mon Sep 17 00:00:00 2001 From: Mitja Felicijan Date: Tue, 18 Jun 2024 18:43:56 +0200 Subject: Added first, last, random filters --- README.md | 29 +++++++++++++++++++++++++++++ main.go | 58 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 85 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 773f233..a04c9de 100644 --- a/README.md +++ b/README.md @@ -158,6 +158,35 @@ Payload { }) ``` +## Special filters + +- first (gets first N posts) +- last (gets last N posts) +- random (gets random N posts) + +```html + +{{ range first 10 .Pages }} + {{ if and (eq .Type "post") (not .Draft) }} +
  • {{ .Title }}
  • + {{ end }} +{{ end }} + + +{{ range last 10 .Pages }} + {{ if and (eq .Type "post") (not .Draft) }} +
  • {{ .Title }}
  • + {{ end }} +{{ end }} + + +{{ range random 10 .Pages }} + {{ if and (eq .Type "post") (not .Draft) }} +
  • {{ .Title }}
  • + {{ end }} +{{ end }} +``` + ## License [jbmafp](https://github.com/mitjafelicijan/jbmafp) was written by [Mitja diff --git a/main.go b/main.go index 8440286..2824041 100644 --- a/main.go +++ b/main.go @@ -5,10 +5,12 @@ import ( "fmt" "html/template" "log" + "math/rand" "net/http" "os" "path" "path/filepath" + "reflect" "sort" "strings" "time" @@ -87,6 +89,50 @@ var EmbedTemplatePost string //go:embed "files/index.xml" var EmbedTemplateFeed string +// firstN returns the first n items of a slice. +func firstN(n int, items interface{}) interface{} { + v := reflect.ValueOf(items) + if v.Kind() != reflect.Slice { + panic("firstN: not a slice") + } + if v.Len() < n { + return items + } + return v.Slice(0, n).Interface() +} + +// lastN returns the last n items of any slice. +func lastN(n int, items interface{}) interface{} { + v := reflect.ValueOf(items) + if v.Kind() != reflect.Slice { + panic("lastN: not a slice") + } + l := v.Len() + if l < n { + return items + } + return v.Slice(l-n, l).Interface() +} + +// randomN returns n random items of any slice. +func randomN(n int, items interface{}) interface{} { + v := reflect.ValueOf(items) + if v.Kind() != reflect.Slice { + panic("randomN: not a slice") + } + l := v.Len() + if l < n { + return items + } + rand.Seed(time.Now().UnixNano()) + indices := rand.Perm(l)[:n] + result := reflect.MakeSlice(v.Type(), n, n) + for i, idx := range indices { + result.Index(i).Set(v.Index(idx)) + } + return result.Interface() +} + // Function to clean HTML tags using bluemonday. func cleanHTMLTags(htmlString string) string { p := bluemonday.StrictPolicy() @@ -284,7 +330,11 @@ func buildProject(projectRoot string) { templates = append([]string{templatePathname}, templates...) templates = append([]string{baseTemplatePathname}, templates...) - t, err := template.ParseFiles(templates...) + t, err := template.New("base.html").Funcs(template.FuncMap{ + "first": firstN, + "last": lastN, + "random": randomN, + }).ParseFiles(templates...) if err != nil { panic(err) } @@ -335,7 +385,11 @@ func buildProject(projectRoot string) { templates = append([]string{templatePathname}, templates...) templates = append([]string{baseTemplatePathname}, templates...) - t, err := template.ParseFiles(templates...) + t, err := template.New("base.html").Funcs(template.FuncMap{ + "first": firstN, + "last": lastN, + "random": randomN, + }).ParseFiles(templates...) if err != nil { panic(err) } -- cgit v1.2.3