- Created main application entry point in `main.go`. - Added configuration management in `config/config.go` and tests in `config/config_test.go`. - Implemented handlers for book and stationery uploads in `handlers/book.go` and `handlers/stationery.go`, including validation logic. - Established database connection and services in `services/database.go` and `services/book_service.go`. - Defined models for books and stationery in `models/book.go` and `models/stationery.go`. - Set up Firebase integration for image uploads in `services/firebase.go`. - Created migration scripts for database schema in `migrations/001_create_tables.sql` and subsequent updates. - Added CORS and error handling middleware. - Included comprehensive tests for handlers, services, and utilities. - Documented API endpoints and usage in `README.md` and migration instructions in `migrations/README.md`. - Introduced `.gitignore` to exclude unnecessary files and directories. - Added Go module support with `go.mod` and `go.sum` files. - Implemented utility functions for slug generation and validation in `utils/slug.go` and `utils/validation.go`.
88 lines
1.9 KiB
Go
88 lines
1.9 KiB
Go
package utils
|
|
|
|
import (
|
|
"regexp"
|
|
"strings"
|
|
"unicode"
|
|
)
|
|
|
|
// GenerateSlug converts a string to a URL-friendly slug
|
|
// Converts to lowercase, replaces spaces with hyphens, removes special characters
|
|
func GenerateSlug(text string) string {
|
|
if text == "" {
|
|
return ""
|
|
}
|
|
|
|
// Convert to lowercase
|
|
slug := strings.ToLower(text)
|
|
|
|
// Replace spaces and underscores with hyphens
|
|
slug = strings.ReplaceAll(slug, " ", "-")
|
|
slug = strings.ReplaceAll(slug, "_", "-")
|
|
|
|
// Remove all non-alphanumeric characters except hyphens
|
|
reg := regexp.MustCompile(`[^a-z0-9-]`)
|
|
slug = reg.ReplaceAllString(slug, "")
|
|
|
|
// Remove multiple consecutive hyphens
|
|
reg = regexp.MustCompile(`-+`)
|
|
slug = reg.ReplaceAllString(slug, "-")
|
|
|
|
// Remove leading and trailing hyphens
|
|
slug = strings.Trim(slug, "-")
|
|
|
|
// If empty after processing, return a default
|
|
if slug == "" {
|
|
slug = "item"
|
|
}
|
|
|
|
return slug
|
|
}
|
|
|
|
// IsValidSlug checks if a string is a valid slug format
|
|
func IsValidSlug(slug string) bool {
|
|
if slug == "" {
|
|
return false
|
|
}
|
|
|
|
// Check if it contains only lowercase letters, numbers, and hyphens
|
|
reg := regexp.MustCompile(`^[a-z0-9-]+$`)
|
|
if !reg.MatchString(slug) {
|
|
return false
|
|
}
|
|
|
|
// Check it doesn't start or end with hyphen
|
|
if strings.HasPrefix(slug, "-") || strings.HasSuffix(slug, "-") {
|
|
return false
|
|
}
|
|
|
|
// Check it doesn't have consecutive hyphens
|
|
if strings.Contains(slug, "--") {
|
|
return false
|
|
}
|
|
|
|
return true
|
|
}
|
|
|
|
// CleanString removes leading/trailing whitespace and normalizes spaces
|
|
func CleanString(s string) string {
|
|
// Trim whitespace
|
|
s = strings.TrimSpace(s)
|
|
|
|
// Replace multiple spaces with single space
|
|
reg := regexp.MustCompile(`\s+`)
|
|
s = reg.ReplaceAllString(s, " ")
|
|
|
|
return s
|
|
}
|
|
|
|
// ContainsOnlyLetters checks if a string contains only letters (and spaces)
|
|
func ContainsOnlyLetters(s string) bool {
|
|
for _, r := range s {
|
|
if !unicode.IsLetter(r) && !unicode.IsSpace(r) {
|
|
return false
|
|
}
|
|
}
|
|
return true
|
|
}
|