From 172ebc2cefcc3887b4b2a364eca93cbf8aa4e0c4 Mon Sep 17 00:00:00 2001 From: maxim nikonov Date: Sat, 20 Sep 2025 01:12:44 +0500 Subject: feat --- tags.go | 88 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 88 insertions(+) create mode 100644 tags.go (limited to 'tags.go') 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)(.*?)`) + 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("

Error: no tag specified

") + 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 + }) + + // Составляем