feat: SEO backend data (1/4)

This commit is contained in:
Florian Sylvain committed 2026-10-15 19:30:29 +02:00
1 parent cb1410f0b0
commit 0eb46b0d74
90 files changed
+6094 -350

No files matched your search

+65
View File
@@ -0,0 +1,65 @@
package slug
import (
"regexp"
"strconv"
"strings"
"unicode/utf8"
)
const MaxRunes = 100
var pattern = regexp.MustCompile(`^[a-z0-9]+(-[a-z0-9]+)*$`)
var nonSlugRun = regexp.MustCompile(`[^a-z0-9]+`)
var diacriticFolder = strings.NewReplacer(
"à", "a", "á", "a", "â", "a", "ã", "a", "ä", "a", "å", "a", "ā", "a", "ă", "a", "ą", "a",
"æ", "ae",
"ç", "c", "ć", "c", "č", "c", "ĉ", "c",
"ď", "d", "đ", "d",
"è", "e", "é", "e", "ê", "e", "ë", "e", "ē", "e", "ė", "e", "ę", "e", "ě", "e",
"ğ", "g",
"ì", "i", "í", "i", "î", "i", "ï", "i", "ī", "i", "į", "i", "ı", "i",
"ł", "l", "ľ", "l",
"ñ", "n", "ń", "n", "ň", "n",
"ò", "o", "ó", "o", "ô", "o", "õ", "o", "ö", "o", "ø", "o", "ō", "o", "ő", "o",
"œ", "oe",
"ř", "r",
"ś", "s", "š", "s", "ş", "s", "ș", "s",
"ß", "ss",
"ť", "t", "ț", "t", "ţ", "t",
"ù", "u", "ú", "u", "û", "u", "ü", "u", "ū", "u", "ů", "u", "ű", "u", "ų", "u",
"ý", "y", "ÿ", "y",
"ź", "z", "ż", "z", "ž", "z",
)
func IsValid(candidate string) bool {
length := utf8.RuneCountInString(candidate)
return length >= 1 && length <= MaxRunes && pattern.MatchString(candidate)
}
func Generate(text string, fallback string) string {
folded := diacriticFolder.Replace(strings.ToLower(text))
generated := strings.Trim(nonSlugRun.ReplaceAllString(folded, "-"), "-")
generated = truncate(generated, MaxRunes)
if generated == "" {
return fallback
}
return generated
}
func WithSuffix(base string, attempt int) string {
if attempt <= 1 {
return base
}
suffix := "-" + strconv.Itoa(attempt)
return truncate(base, MaxRunes-len(suffix)) + suffix
}
func truncate(candidate string, limit int) string {
if len(candidate) <= limit {
return candidate
}
return strings.TrimRight(candidate[:limit], "-")
}