Add initial project structure with core functionality for book and stationery uploads
- 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`.
This commit is contained in:
87
utils/slug.go
Normal file
87
utils/slug.go
Normal file
@@ -0,0 +1,87 @@
|
||||
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
|
||||
}
|
||||
Reference in New Issue
Block a user