diff options
| -rw-r--r-- | README.md | 29 | ||||
| -rw-r--r-- | main.go | 58 |
2 files changed, 85 insertions, 2 deletions
@@ -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 @@ -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) } |
