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)
}