summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--README.md21
-rw-r--r--filters.go69
-rw-r--r--main.go65
3 files changed, 96 insertions, 59 deletions
diff --git a/README.md b/README.md
index df1417d..e2dbd71 100644
--- a/README.md
+++ b/README.md
@@ -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
+}
+
diff --git a/main.go b/main.go
index 2824041..9871d1c 100644
--- a/main.go
+++ b/main.go
@@ -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)
}