From 2ca5043b65135046017c41d214ab852850f03228 Mon Sep 17 00:00:00 2001 From: matheusgomes28 Date: Fri, 8 Mar 2024 23:23:02 +0000 Subject: [PATCH] Add support for shortcode-like feature in posts --- admin-app/post.go | 78 ++++++++++++++++++++++++++++++++++++++++++++++- app/app.go | 1 + 2 files changed, 78 insertions(+), 1 deletion(-) diff --git a/admin-app/post.go b/admin-app/post.go index 487e36f..2c6ff4d 100644 --- a/admin-app/post.go +++ b/admin-app/post.go @@ -2,8 +2,11 @@ package admin_app import ( "encoding/json" + "fmt" "net/http" + "regexp" "strconv" + "strings" "github.com/gin-gonic/gin" "github.com/matheusgomes28/urchin/database" @@ -65,10 +68,20 @@ func postPostHandler(database database.Database) func(*gin.Context) { return } + transformed_content, err := transformContent(add_post_request.Content) + if err != nil { + log.Warn().Msgf("could not transform post: %v", err) + c.JSON(http.StatusBadRequest, gin.H{ + "error": "invalid request body", + "msg": err.Error(), + }) + return + } + id, err := database.AddPost( add_post_request.Title, add_post_request.Excerpt, - add_post_request.Content, + transformed_content, ) if err != nil { log.Error().Msgf("failed to add post: %v", err) @@ -153,3 +166,66 @@ func deletePostHandler(database database.Database) func(*gin.Context) { }) } } + +// partitionString will partition the strings by +// removing the given ranges +func partitionString(text string, indexes [][]int) []string { + + partitions := make([]string, 0) + start := 0 + for _, window := range indexes { + partitions = append(partitions, text[start:window[0]]) + start = window[1] + } + + partitions = append(partitions, text[start:len(text)-1]) + return partitions +} + +func shortcodeToMarkdown(shortcode string) (string, error) { + key_value := strings.Split(shortcode, ":") + + key := key_value[0] + values := key_value[1:] + + if key == "img" { + if len(values) == 1 { + image_src := fmt.Sprintf("/media/%s", values[0]) + return fmt.Sprintf("![image](%s)", image_src), nil + } else if len(values) == 2 { + image_src := fmt.Sprintf("/media/%s", values[0]) + alt_text := values[1] + return fmt.Sprintf("![%s](%s)", alt_text, image_src), nil + } else { + return "", fmt.Errorf("invalid shortcode: %s", shortcode) + } + } + + return "", fmt.Errorf("unsupported shortcode: %s", key) +} + +func transformContent(content string) (string, error) { + // Find all the occurences of {{ and }} + regex, _ := regexp.Compile(`{{[\w.-]+(:[\w.-]+)+}}`) + + shortcodes := regex.FindAllStringIndex(content, -1) + partitions := partitionString(content, shortcodes) + + builder := strings.Builder{} + i := 0 + for i, shortcode := range(shortcodes) { + builder.WriteString(partitions[i]) + + markdown, err := shortcodeToMarkdown(content[shortcode[0]+2:shortcode[1]-2]) + if err != nil { + return "", err + } + builder.WriteString(markdown) + } + + // Guaranteed to have +1 than the number of + // shortcodes by algorithm + builder.WriteString(partitions[i+1]) + + return builder.String(), nil +} diff --git a/app/app.go b/app/app.go index 1cf8664..5694a5a 100644 --- a/app/app.go +++ b/app/app.go @@ -30,6 +30,7 @@ func SetupRoutes(app_settings common.AppSettings, database database.Database) *g r.POST("/contact-send", makeContactFormHandler()) r.Static("/static", "./static") + r.Static("/media", "./media") return r }