diff options
Diffstat (limited to 'main.go')
| -rw-r--r-- | main.go | 58 |
1 files changed, 56 insertions, 2 deletions
| @@ -5,10 +5,12 @@ import ( | |||
| 5 | "fmt" | 5 | "fmt" |
| 6 | "html/template" | 6 | "html/template" |
| 7 | "log" | 7 | "log" |
| 8 | "math/rand" | ||
| 8 | "net/http" | 9 | "net/http" |
| 9 | "os" | 10 | "os" |
| 10 | "path" | 11 | "path" |
| 11 | "path/filepath" | 12 | "path/filepath" |
| 13 | "reflect" | ||
| 12 | "sort" | 14 | "sort" |
| 13 | "strings" | 15 | "strings" |
| 14 | "time" | 16 | "time" |
| @@ -87,6 +89,50 @@ var EmbedTemplatePost string | |||
| 87 | //go:embed "files/index.xml" | 89 | //go:embed "files/index.xml" |
| 88 | var EmbedTemplateFeed string | 90 | var EmbedTemplateFeed string |
| 89 | 91 | ||
| 92 | // firstN returns the first n items of a slice. | ||
| 93 | func firstN(n int, items interface{}) interface{} { | ||
| 94 | v := reflect.ValueOf(items) | ||
| 95 | if v.Kind() != reflect.Slice { | ||
| 96 | panic("firstN: not a slice") | ||
| 97 | } | ||
| 98 | if v.Len() < n { | ||
| 99 | return items | ||
| 100 | } | ||
| 101 | return v.Slice(0, n).Interface() | ||
| 102 | } | ||
| 103 | |||
| 104 | // lastN returns the last n items of any slice. | ||
| 105 | func lastN(n int, items interface{}) interface{} { | ||
| 106 | v := reflect.ValueOf(items) | ||
| 107 | if v.Kind() != reflect.Slice { | ||
| 108 | panic("lastN: not a slice") | ||
| 109 | } | ||
| 110 | l := v.Len() | ||
| 111 | if l < n { | ||
| 112 | return items | ||
| 113 | } | ||
| 114 | return v.Slice(l-n, l).Interface() | ||
| 115 | } | ||
| 116 | |||
| 117 | // randomN returns n random items of any slice. | ||
| 118 | func randomN(n int, items interface{}) interface{} { | ||
| 119 | v := reflect.ValueOf(items) | ||
| 120 | if v.Kind() != reflect.Slice { | ||
| 121 | panic("randomN: not a slice") | ||
| 122 | } | ||
| 123 | l := v.Len() | ||
| 124 | if l < n { | ||
| 125 | return items | ||
| 126 | } | ||
| 127 | rand.Seed(time.Now().UnixNano()) | ||
| 128 | indices := rand.Perm(l)[:n] | ||
| 129 | result := reflect.MakeSlice(v.Type(), n, n) | ||
| 130 | for i, idx := range indices { | ||
| 131 | result.Index(i).Set(v.Index(idx)) | ||
| 132 | } | ||
| 133 | return result.Interface() | ||
| 134 | } | ||
| 135 | |||
| 90 | // Function to clean HTML tags using bluemonday. | 136 | // Function to clean HTML tags using bluemonday. |
| 91 | func cleanHTMLTags(htmlString string) string { | 137 | func cleanHTMLTags(htmlString string) string { |
| 92 | p := bluemonday.StrictPolicy() | 138 | p := bluemonday.StrictPolicy() |
| @@ -284,7 +330,11 @@ func buildProject(projectRoot string) { | |||
| 284 | templates = append([]string{templatePathname}, templates...) | 330 | templates = append([]string{templatePathname}, templates...) |
| 285 | templates = append([]string{baseTemplatePathname}, templates...) | 331 | templates = append([]string{baseTemplatePathname}, templates...) |
| 286 | 332 | ||
| 287 | t, err := template.ParseFiles(templates...) | 333 | t, err := template.New("base.html").Funcs(template.FuncMap{ |
| 334 | "first": firstN, | ||
| 335 | "last": lastN, | ||
| 336 | "random": randomN, | ||
| 337 | }).ParseFiles(templates...) | ||
| 288 | if err != nil { | 338 | if err != nil { |
| 289 | panic(err) | 339 | panic(err) |
| 290 | } | 340 | } |
| @@ -335,7 +385,11 @@ func buildProject(projectRoot string) { | |||
| 335 | templates = append([]string{templatePathname}, templates...) | 385 | templates = append([]string{templatePathname}, templates...) |
| 336 | templates = append([]string{baseTemplatePathname}, templates...) | 386 | templates = append([]string{baseTemplatePathname}, templates...) |
| 337 | 387 | ||
| 338 | t, err := template.ParseFiles(templates...) | 388 | t, err := template.New("base.html").Funcs(template.FuncMap{ |
| 389 | "first": firstN, | ||
| 390 | "last": lastN, | ||
| 391 | "random": randomN, | ||
| 392 | }).ParseFiles(templates...) | ||
| 339 | if err != nil { | 393 | if err != nil { |
| 340 | panic(err) | 394 | panic(err) |
| 341 | } | 395 | } |
