summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMitja Felicijan <mitja.felicijan@gmail.com>2024-06-18 18:43:56 +0200
committerMitja Felicijan <mitja.felicijan@gmail.com>2024-06-18 18:43:56 +0200
commitb738f38af8551021f77ad759425063d06e3c80de (patch)
treee44a8864ed0669bcfd07272db377a3c08dcd82c5
parent66e62b48a9f10ca1722cead466ba0b4a0e1239a5 (diff)
downloadjbmafp-b738f38af8551021f77ad759425063d06e3c80de.tar.gz
Added first, last, random filters
-rw-r--r--README.md29
-rw-r--r--main.go58
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
+<!-- First 10 pages -->
+{{ range first 10 .Pages }}
+ {{ if and (eq .Type "post") (not .Draft) }}
+ <li><a href="{{ .RelPermalink }}">{{ .Title }}</a></li>
+ {{ end }}
+{{ end }}
+
+<!-- Last 10 pages -->
+{{ range last 10 .Pages }}
+ {{ if and (eq .Type "post") (not .Draft) }}
+ <li><a href="{{ .RelPermalink }}">{{ .Title }}</a></li>
+ {{ end }}
+{{ end }}
+
+<!-- Random 10 pages -->
+{{ range random 10 .Pages }}
+ {{ if and (eq .Type "post") (not .Draft) }}
+ <li><a href="{{ .RelPermalink }}">{{ .Title }}</a></li>
+ {{ 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)
}