Files
MyClub/internal/models/i18n.go
T
Tomas Dvorak dfc079288f hot fix #1
2026-01-26 08:13:18 +01:00

138 lines
4.9 KiB
Go

package models
import (
"time"
"gorm.io/gorm"
)
// Language represents a supported language
type Language struct {
ID string `gorm:"primaryKey;type:varchar(5)" json:"id"`
Name string `gorm:"type:varchar(100);not null" json:"name"`
NativeName string `gorm:"type:varchar(100);not null" json:"native_name"`
Code string `gorm:"type:varchar(10);not null;uniqueIndex" json:"code"`
IsDefault bool `gorm:"default:false" json:"is_default"`
IsActive bool `gorm:"default:true" json:"is_active"`
SortOrder int `gorm:"default:0" json:"sort_order"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
}
// Translation represents a translatable string
type Translation struct {
ID uint `gorm:"primaryKey" json:"id"`
Key string `gorm:"type:varchar(200);not null;index" json:"key"`
LanguageCode string `gorm:"type:varchar(10);not null;index" json:"language_code"`
Value string `gorm:"type:text;not null" json:"value"`
Context string `gorm:"type:varchar(100)" json:"context"` // e.g., "navbar", "admin", "public"
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
// Relationships
Language Language `gorm:"foreignKey:LanguageCode;references:Code" json:"language,omitempty"`
}
// ContentTranslation represents translations for content like articles, activities, etc.
type ContentTranslation struct {
ID uint `gorm:"primaryKey" json:"id"`
ContentType string `gorm:"type:varchar(50);not null;index" json:"content_type"` // "article", "activity", "page", etc.
ContentID uint `gorm:"not null;index" json:"content_id"`
LanguageCode string `gorm:"type:varchar(10);not null;index" json:"language_code"`
Title string `gorm:"type:varchar(500)" json:"title"`
Content string `gorm:"type:text" json:"content"`
Excerpt string `gorm:"type:text" json:"excerpt"`
MetaTitle string `gorm:"type:varchar(200)" json:"meta_title"`
MetaDescription string `gorm:"type:varchar(500)" json:"meta_description"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
// Relationships
Language Language `gorm:"foreignKey:LanguageCode;references:Code" json:"language,omitempty"`
}
// UserLanguagePreference tracks user's preferred language
type UserLanguagePreference struct {
ID uint `gorm:"primaryKey" json:"id"`
UserID uint `gorm:"not null;uniqueIndex" json:"user_id"`
LanguageCode string `gorm:"type:varchar(10);not null" json:"language_code"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
// Relationships
User User `gorm:"foreignKey:UserID" json:"user,omitempty"`
Language Language `gorm:"foreignKey:LanguageCode;references:Code" json:"language,omitempty"`
}
// TableName returns the table name for Language model
func (Language) TableName() string {
return "languages"
}
// TableName returns the table name for Translation model
func (Translation) TableName() string {
return "translations"
}
// TableName returns the table name for ContentTranslation model
func (ContentTranslation) TableName() string {
return "content_translations"
}
// TableName returns the table name for UserLanguagePreference model
func (UserLanguagePreference) TableName() string {
return "user_language_preferences"
}
// BeforeCreate sets default values
func (l *Language) BeforeCreate(tx *gorm.DB) error {
if l.SortOrder == 0 {
l.SortOrder = 100
}
return nil
}
// GetDefaultLanguage returns the default language
func GetDefaultLanguage(db *gorm.DB) (*Language, error) {
var lang Language
err := db.Where("is_default = ? AND is_active = ?", true, true).First(&lang).Error
if err != nil {
return nil, err
}
return &lang, nil
}
// GetActiveLanguages returns all active languages ordered by sort order
func GetActiveLanguages(db *gorm.DB) ([]Language, error) {
var languages []Language
err := db.Where("is_active = ?", true).Order("sort_order ASC, name ASC").Find(&languages).Error
return languages, err
}
// GetTranslation returns a translation for a specific key and language
func GetTranslation(db *gorm.DB, key, languageCode string) (*Translation, error) {
var translation Translation
err := db.Where("key = ? AND language_code = ?", key, languageCode).First(&translation).Error
if err != nil {
return nil, err
}
return &translation, nil
}
// GetTranslationWithFallback returns a translation, falling back to default language if needed
func GetTranslationWithFallback(db *gorm.DB, key, languageCode string) (*Translation, error) {
// Try requested language first
translation, err := GetTranslation(db, key, languageCode)
if err == nil {
return translation, nil
}
// Fall back to default language
defaultLang, err := GetDefaultLanguage(db)
if err != nil {
return nil, err
}
return GetTranslation(db, key, defaultLang.Code)
}