commit c5b40ca1750049fc833c714b02ef5f1410c4cdda
parent 3fff705c8b00eb5656cffed1eac851d945d968df
Author: brookjeynes <me@brookjeynes.dev>
Date: Tue, 12 May 2026 18:12:27 +1000
refactor: move Slug to domain package
Signed-off-by: brookjeynes <me@brookjeynes.dev>
Diffstat:
2 files changed, 35 insertions(+), 31 deletions(-)
diff --git a/internal/domain/strings.go b/internal/domain/strings.go
@@ -0,0 +1,33 @@
+package domain
+
+import (
+ "strings"
+ "unicode"
+
+ "golang.org/x/text/runes"
+ "golang.org/x/text/transform"
+ "golang.org/x/text/unicode/norm"
+)
+
+func Slug(title string) string {
+ // strip apostrophes before normalizing
+ s := strings.ReplaceAll(title, "'", "")
+
+ // unicode normalize: NFD decompose, strip non-spacing marks, recompose
+ t := transform.Chain(norm.NFD, runes.Remove(runes.In(unicode.Mn)), norm.NFC)
+ s, _, _ = transform.String(t, s)
+
+ s = strings.ToLower(s)
+ s = strings.Map(func(r rune) rune {
+ if r >= 'a' && r <= 'z' || r >= '0' && r <= '9' {
+ return r
+ }
+ return '-'
+ }, s)
+
+ for strings.Contains(s, "--") {
+ s = strings.ReplaceAll(s, "--", "-")
+ }
+
+ return strings.Trim(s, "-")
+}
diff --git a/internal/server/song.go b/internal/server/song.go
@@ -8,37 +8,8 @@ import (
"lyrics/internal/server/ui/views/song"
"net/http"
"strconv"
- "strings"
- "unicode"
-
- "golang.org/x/text/runes"
- "golang.org/x/text/transform"
- "golang.org/x/text/unicode/norm"
)
-func Slug(title string) string {
- // strip apostrophes before normalizing
- s := strings.ReplaceAll(title, "'", "")
-
- // unicode normalize: NFD decompose, strip non-spacing marks, recompose
- t := transform.Chain(norm.NFD, runes.Remove(runes.In(unicode.Mn)), norm.NFC)
- s, _, _ = transform.String(t, s)
-
- s = strings.ToLower(s)
- s = strings.Map(func(r rune) rune {
- if r >= 'a' && r <= 'z' || r >= '0' && r <= '9' {
- return r
- }
- return '-'
- }, s)
-
- for strings.Contains(s, "--") {
- s = strings.ReplaceAll(s, "--", "-")
- }
-
- return strings.Trim(s, "-")
-}
-
func (ss *ServerState) Song(w http.ResponseWriter, r *http.Request) {
logger := ss.logger.With("handler", "Song")
@@ -65,8 +36,8 @@ func (ss *ServerState) Song(w http.ResponseWriter, r *http.Request) {
songTitle = *s.LatinTitle
}
- if Slug(songTitle) != slug {
- htmx.HxRedirect(w, http.StatusMovedPermanently, fmt.Sprintf("/song/%d/%s", id, Slug(songTitle)))
+ if domain.Slug(songTitle) != slug {
+ htmx.HxRedirect(w, http.StatusMovedPermanently, fmt.Sprintf("/song/%d/%s", id, domain.Slug(songTitle)))
return
}