package i18n import ( "strings" ) // Lang represents a supported language code. type Lang string const ( EN Lang = "en" ZH Lang = "zh" ) // translations holds all UI strings keyed by language then translation key. var translations = map[Lang]map[string]string{ EN: { // Nav "site_title": "Go Blog", "home": "Home", "login": "Login", "dashboard": "Dashboard", "logout": "Logout", // Home page "home_welcome": "Welcome to Go Blog", "home_subtitle": "A simple, fast blog engine built with Go, Gin, and Tailwind CSS.", "home_sign_in": "Sign In", "home_to_dash": "Dashboard", "home_latest": "Latest Posts", "home_post1_tit": "Getting Started", "home_post1_dsc": "Welcome to your new blog! This is a placeholder post. Start writing to see your content here.", "home_post2_tit": "Hello World", "home_post2_dsc": "Blog posts will appear here once you start publishing from the admin dashboard.", "home_post3_tit": "Built with Go", "home_post3_dsc": "This blog engine uses Go, Gin web framework, GORM, and Tailwind CSS for a modern experience.", "home_no_posts": "No published posts yet.", // Login page "login_title": "Sign In", "login_username": "Username", "login_password": "Password", "login_ph_user": "Enter your username", "login_ph_pass": "Enter your password", "login_submit": "Sign In", "login_error": "Invalid username or password.", "login_required": "Please fill in all fields.", // Dashboard "dash_title": "Dashboard", "dash_welcome": "Welcome back,", "dash_posts": "Posts", "dash_pages": "Pages", "dash_users": "Users", "dash_mgmt_title": "Blog Management", "dash_mgmt_desc": "Post management, categories, and settings will appear here in future updates.", "dash_page_title": "Dashboard", // Footer "footer_text": "© 2026 Go Blog. Powered by Go & Gin.", // Page titles "page_home": "Home", "page_login": "Login", // Language switcher "lang_switch": "中文", // Profile dropdown & page "profile": "Profile", "admin_panel": "Admin Panel", "profile_title": "Edit Profile", "profile_avatar": "Avatar", "profile_change_avatar": "Change Avatar", "profile_display_name": "Display Name", "profile_gender": "Gender", "profile_birthday": "Birthday", "profile_email": "Email", "profile_change_password": "Change Password", "profile_current_password": "Current Password", "profile_new_password": "New Password", "profile_save": "Save Changes", "profile_saved": "Profile updated.", "profile_wrong_password": "Current password is incorrect.", "gender_male": "Male", "gender_female": "Female", "gender_other": "Other", // Avatar cropping "crop_avatar_title": "Crop Avatar", "crop_cancel": "Cancel", "crop_confirm": "Confirm", "crop_uploading": "Uploading...", "crop_success": "Avatar updated.", "crop_error": "Failed to upload avatar. Please try again.", // Article creation "article_create_title": "Create Article", "article_title": "Title", "article_slug": "Slug", "article_slug_hint": "Auto-generated from title if empty", "article_summary": "Summary", "article_content": "Content", "article_cover": "Cover Image URL", "article_status": "Status", "article_draft": "Draft", "article_published": "Published", "article_is_top": "Pin to top", "article_save_draft": "Save Draft", "article_publish": "Publish", "article_created": "Article created successfully.", "article_error": "Failed to create article.", "article_new": "New Article", "article_title_required": "Title is required.", "article_content_required": "Content is required.", }, ZH: { // 导航 "site_title": "Go 博客", "home": "首页", "login": "登录", "dashboard": "后台", "logout": "退出", // 首页 "home_welcome": "欢迎来到 Go Blog", "home_subtitle": "一个使用 Go、Gin 和 Tailwind CSS 构建的简洁快速的博客引擎。", "home_sign_in": "登录", "home_to_dash": "后台管理", "home_latest": "最新文章", "home_post1_tit": "入门指南", "home_post1_dsc": "欢迎来到你的新博客!这是一篇占位文章。开始写作后,你的内容将显示在这里。", "home_post2_tit": "你好,世界", "home_post2_dsc": "当你从后台管理面板发布文章后,博客文章将显示在这里。", "home_post3_tit": "使用 Go 构建", "home_post3_dsc": "此博客引擎使用 Go、Gin Web 框架、GORM 和 Tailwind CSS 构建,提供现代化的体验。", "home_no_posts": "暂无已发布的文章。", // 登录页 "login_title": "登录", "login_username": "用户名", "login_password": "密码", "login_ph_user": "请输入用户名", "login_ph_pass": "请输入密码", "login_submit": "登录", "login_error": "用户名或密码错误。", "login_required": "请填写所有字段。", // 后台 "dash_title": "后台管理", "dash_welcome": "欢迎回来,", "dash_posts": "文章", "dash_pages": "页面", "dash_users": "用户", "dash_mgmt_title": "博客管理", "dash_mgmt_desc": "文章管理、分类和设置将在后续版本中添加。", "dash_page_title": "后台管理", // 页脚 "footer_text": "© 2026 Go Blog。由 Go & Gin 驱动。", "page_home": "首页", "page_login": "登录", // 语言切换 "lang_switch": "English", // 个人中心下拉菜单 & 页面 "profile": "个人信息", "admin_panel": "后台管理", "profile_title": "编辑个人信息", "profile_avatar": "头像", "profile_change_avatar": "更换头像", "profile_display_name": "显示名称", "profile_gender": "性别", "profile_birthday": "生日", "profile_email": "邮箱", "profile_change_password": "修改密码", "profile_current_password": "当前密码", "profile_new_password": "新密码", "profile_save": "保存修改", "profile_saved": "个人信息已更新。", "profile_wrong_password": "当前密码错误。", "gender_male": "男", "gender_female": "女", "gender_other": "其他", // 头像裁剪 "crop_avatar_title": "裁剪头像", "crop_cancel": "取消", "crop_confirm": "确认", "crop_uploading": "上传中...", "crop_success": "头像已更新。", "crop_error": "头像上传失败,请重试。", // 文章创建 "article_create_title": "新建文章", "article_title": "标题", "article_slug": "Slug", "article_slug_hint": "留空则从标题自动生成", "article_summary": "摘要", "article_content": "正文", "article_cover": "封面图 URL", "article_status": "状态", "article_draft": "草稿", "article_published": "已发布", "article_is_top": "置顶", "article_save_draft": "保存草稿", "article_publish": "发布", "article_created": "文章创建成功。", "article_error": "创建文章失败。", "article_new": "新建文章", "article_title_required": "标题不能为空。", "article_content_required": "正文不能为空。", }, } // T returns a copy of the translation map for the given language. // Falls back to English if the language is not supported. func T(l Lang) map[string]string { t, ok := translations[l] if !ok { t = translations[EN] } // Return a shallow copy so callers cannot mutate the original map values. out := make(map[string]string, len(t)) for k, v := range t { out[k] = v } return out } // DetectLang parses the Accept-Language header and returns the best matching // supported language. Returns EN for unsupported languages. func DetectLang(acceptHeader string) Lang { if acceptHeader == "" { return EN } // Accept-Language format: "zh-CN,zh;q=0.9,en;q=0.8,en-US;q=0.7" // Split by comma, then extract primary language from each entry. entries := strings.Split(acceptHeader, ",") for _, entry := range entries { // Trim spaces and remove quality values. entry = strings.TrimSpace(entry) if idx := strings.Index(entry, ";"); idx != -1 { entry = entry[:idx] } // Extract primary language (before any "-" subtag). primary := strings.ToLower(entry) if idx := strings.Index(primary, "-"); idx != -1 { primary = primary[:idx] } switch primary { case "zh": return ZH case "en": return EN } } return EN }