diff options
| author | Mitja Felicijan <mitja.felicijan@gmail.com> | 2024-06-21 17:28:03 +0200 |
|---|---|---|
| committer | Mitja Felicijan <mitja.felicijan@gmail.com> | 2024-06-21 17:28:03 +0200 |
| commit | 0130404a1dc663d4aa68d780c9bcb23a4243e68d (patch) | |
| tree | d57563d101f6bbf08f9bfd6b3214e311d64d4f22 | |
| parent | 921b7e42fb26e0d9c5b50221eb8c6e5390f51908 (diff) | |
| download | jbmafp-0130404a1dc663d4aa68d780c9bcb23a4243e68d.tar.gz | |
Added additional filters
| -rw-r--r-- | README.md | 21 | ||||
| -rw-r--r-- | filters.go | 69 | ||||
| -rw-r--r-- | main.go | 65 |
3 files changed, 96 insertions, 59 deletions
@@ -163,28 +163,43 @@ Payload { - first (gets first N posts) - last (gets last N posts) - random (gets random N posts) +- filterbytype (get just the posts with specific type) ```html <!-- First 10 pages --> -{{ range first 10 .Pages }} +{{ range .Pages | first 10 }} {{ if and (eq .Type "post") (not .Draft) }} <li><a href="{{ .RelPermalink }}">{{ .Title }}</a></li> {{ end }} {{ end }} <!-- Last 10 pages --> -{{ range last 10 .Pages }} +{{ range .Pages | last 10 }} {{ if and (eq .Type "post") (not .Draft) }} <li><a href="{{ .RelPermalink }}">{{ .Title }}</a></li> {{ end }} {{ end }} <!-- Random 10 pages --> -{{ range random 10 .Pages }} +{{ range .Pages | random 10 }} {{ if and (eq .Type "post") (not .Draft) }} <li><a href="{{ .RelPermalink }}">{{ .Title }}</a></li> {{ end }} {{ end }} + +<!-- Filter by type --> +{{ range .Pages | filterbytype "post" }} + {{ if not .Draft }} + <li><a href="{{ .RelPermalink }}">{{ .Title }}</a></li> + {{ end }} +{{ end }} + +<!-- Chain multiple together --> +{{ range .Pages | filterbytype "post" | random 20 | first 5 }} + {{ if not .Draft }} + <li><a href="{{ .RelPermalink }}">{{ .Title }}</a></li> + {{ end }} +{{ end }} ``` ## Additional material diff --git a/filters.go b/filters.go new file mode 100644 index 0000000..bb57599 --- /dev/null +++ b/filters.go @@ -0,0 +1,69 @@ +package main + +import ( + "math/rand" + "reflect" + "time" +) + +// 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() +} + +// filterByType filters pages by their type. +func filterByType(pageType string, pages interface{}) interface{} { + v := reflect.ValueOf(pages) + if v.Kind() != reflect.Slice { + panic("filterByType: not a slice") + } + + var filtered []interface{} + for i := 0; i < v.Len(); i++ { + page := v.Index(i).Interface().(Page) + if page.Type == pageType { + filtered = append(filtered, page) + } + } + return filtered +} + @@ -5,12 +5,10 @@ import ( "fmt" "html/template" "log" - "math/rand" "net/http" "os" "path" "path/filepath" - "reflect" "sort" "strings" "time" @@ -89,50 +87,6 @@ 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() @@ -318,6 +272,13 @@ func buildProject(projectRoot string) { return } + filters := template.FuncMap{ + "first": firstN, + "last": lastN, + "random": randomN, + "filterbytype": filterByType, + } + // Generate HTML files for all pages. for _, page := range pages { outFilepath := path.Join(projectRoot, "public", page.Meta["url"].(string)) @@ -330,11 +291,7 @@ func buildProject(projectRoot string) { templates = append([]string{templatePathname}, templates...) templates = append([]string{baseTemplatePathname}, templates...) - t, err := template.New("base.html").Funcs(template.FuncMap{ - "first": firstN, - "last": lastN, - "random": randomN, - }).ParseFiles(templates...) + t, err := template.New("base.html").Funcs(filters).ParseFiles(templates...) if err != nil { panic(err) } @@ -385,11 +342,7 @@ func buildProject(projectRoot string) { templates = append([]string{templatePathname}, templates...) templates = append([]string{baseTemplatePathname}, templates...) - t, err := template.New("base.html").Funcs(template.FuncMap{ - "first": firstN, - "last": lastN, - "random": randomN, - }).ParseFiles(templates...) + t, err := template.New("base.html").Funcs(filters).ParseFiles(templates...) if err != nil { panic(err) } |
