diff --git a/README.md b/README.md index df1417d1d83982f52ed9f20148b9866da53bc7fb..e2dbd712b3835d4a0b019842479b26f0997ffcd4 100644 --- a/README.md +++ b/README.md @@ -163,25 +163,40 @@ - first (gets first N posts) - last (gets last N posts) - random (gets random N posts) +- filterbytype (get just the posts with specific type) ```html -{{ range first 10 .Pages }} +{{ range .Pages | first 10 }} {{ if and (eq .Type "post") (not .Draft) }}
  • {{ .Title }}
  • {{ end }} {{ end }} -{{ range last 10 .Pages }} +{{ range .Pages | last 10 }} {{ if and (eq .Type "post") (not .Draft) }}
  • {{ .Title }}
  • {{ end }} {{ end }} -{{ range random 10 .Pages }} +{{ range .Pages | random 10 }} {{ if and (eq .Type "post") (not .Draft) }} +
  • {{ .Title }}
  • + {{ end }} +{{ end }} + + +{{ range .Pages | filterbytype "post" }} + {{ if not .Draft }} +
  • {{ .Title }}
  • + {{ end }} +{{ end }} + + +{{ range .Pages | filterbytype "post" | random 20 | first 5 }} + {{ if not .Draft }}
  • {{ .Title }}
  • {{ end }} {{ end }} diff --git a/filters.go b/filters.go new file mode 100644 index 0000000000000000000000000000000000000000..bb5759960df7fa7d97745bb3b85208da1b85eb34 --- /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 +} + diff --git a/main.go b/main.go index 2824041e174ddd7d5d1ea1597f314313d4f56abf..9871d1c04c8321b8ffd51c2ea7273f9b5facd836 100644 --- a/main.go +++ b/main.go @@ -5,12 +5,10 @@ "bytes" "fmt" "html/template" "log" - "math/rand" "net/http" "os" "path" "path/filepath" - "reflect" "sort" "strings" "time" @@ -89,50 +87,6 @@ //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 @@ log.Println("Error creating directory:", err) 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 @@ templates := includeTemplateList(projectRoot) 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 @@ templates := includeTemplateList(projectRoot) 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) }