summaryrefslogtreecommitdiff
path: root/tags.go
diff options
context:
space:
mode:
Diffstat (limited to 'tags.go')
-rw-r--r--tags.go88
1 files changed, 88 insertions, 0 deletions
diff --git a/tags.go b/tags.go
new file mode 100644
index 0000000..caffd4a
--- /dev/null
+++ b/tags.go
@@ -0,0 +1,88 @@
+// Should be compiled to binary to be used as CGI script
+package main
+
+import (
+ "fmt"
+ "html"
+ "io/fs"
+ "net/url"
+ "os"
+ "path/filepath"
+ "regexp"
+ "strings"
+)
+
+func extractTitle(content string) string {
+ titleRegex := regexp.MustCompile(`(?i)<title>(.*?)</title>`)
+ matches := titleRegex.FindStringSubmatch(content)
+ if len(matches) > 1 {
+ return matches[1]
+ }
+ return "Без названия"
+}
+
+func main() {
+ // CGI header
+ fmt.Println("Content-Type: text/html; charset=utf-8")
+ fmt.Println()
+
+ // Получаем query string из окружения
+ rawQuery := os.Getenv("QUERY_STRING")
+ values, _ := url.ParseQuery(rawQuery)
+ tag := values.Get("tag")
+ if tag == "" {
+ fmt.Println("<p>Error: no tag specified</p>")
+ return
+ }
+
+ postsDir := "../posts"
+ tagRegex := regexp.MustCompile(`data-tag="` + regexp.QuoteMeta(tag) + `"`)
+
+ type Post struct {
+ Path string
+ Title string
+ }
+
+ var matches []Post
+
+ filepath.WalkDir(postsDir, func(path string, d fs.DirEntry, err error) error {
+ if err != nil {
+ return nil
+ }
+ if !d.IsDir() {
+ contentBytes, err := os.ReadFile(path)
+ if err == nil && tagRegex.Match(contentBytes) {
+ content := string(contentBytes)
+ title := extractTitle(content)
+ relPath := "/posts/" + filepath.Base(path)
+ matches = append(matches, Post{Path: relPath, Title: title})
+ }
+ }
+ return nil
+ })
+
+ // Составляем <ul>
+ var b strings.Builder
+ b.WriteString("<ul>\n")
+ for _, post := range matches {
+ fmt.Fprintf(&b, "<li><a class=\"text-sm underline\" href=\"%s\">%s</a></li>\n",
+ html.EscapeString(post.Path),
+ html.EscapeString(post.Title))
+ }
+ b.WriteString("</ul>")
+
+ // Читаем шаблон
+ templateBytes, err := os.ReadFile("../templates/tags.html")
+ if err != nil {
+ fmt.Println("<p>Error: template not found</p>")
+ return
+ }
+ template := string(templateBytes)
+
+ // Заменяем маркеры
+ output := strings.Replace(template, "<!-- %cgi.list% -->", b.String(), 1)
+ output = strings.Replace(output, "<!-- %cgi.tag% -->", html.EscapeString(tag), 1)
+
+ // Отдаём результат
+ fmt.Print(output)
+} \ No newline at end of file