mirror of
https://github.com/goharbor/harbor.git
synced 2024-11-27 12:46:03 +01:00
213 lines
4.5 KiB
Go
213 lines
4.5 KiB
Go
|
// Copyright 2013-2014 beego authors
|
||
|
//
|
||
|
// Licensed under the Apache License, Version 2.0 (the "License"): you may
|
||
|
// not use this file except in compliance with the License. You may obtain
|
||
|
// a copy of the License at
|
||
|
//
|
||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||
|
//
|
||
|
// Unless required by applicable law or agreed to in writing, software
|
||
|
// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||
|
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||
|
// License for the specific language governing permissions and limitations
|
||
|
// under the License.
|
||
|
|
||
|
// Package i18n is for app Internationalization and Localization.
|
||
|
package i18n
|
||
|
|
||
|
import (
|
||
|
"fmt"
|
||
|
"reflect"
|
||
|
"strings"
|
||
|
|
||
|
"github.com/Unknwon/goconfig"
|
||
|
)
|
||
|
|
||
|
var (
|
||
|
locales = &localeStore{store: make(map[string]*locale)}
|
||
|
)
|
||
|
|
||
|
type locale struct {
|
||
|
id int
|
||
|
lang string
|
||
|
langDesc string
|
||
|
message *goconfig.ConfigFile
|
||
|
}
|
||
|
|
||
|
type localeStore struct {
|
||
|
langs []string
|
||
|
langDescs []string
|
||
|
store map[string]*locale
|
||
|
}
|
||
|
|
||
|
// Get target language string
|
||
|
func (d *localeStore) Get(lang, section, format string) (string, bool) {
|
||
|
if locale, ok := d.store[lang]; ok {
|
||
|
if section == "" {
|
||
|
section = goconfig.DEFAULT_SECTION
|
||
|
}
|
||
|
|
||
|
if value, err := locale.message.GetValue(section, format); err == nil {
|
||
|
return value, true
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return "", false
|
||
|
}
|
||
|
|
||
|
func (d *localeStore) Add(lc *locale) bool {
|
||
|
if _, ok := d.store[lc.lang]; ok {
|
||
|
return false
|
||
|
}
|
||
|
|
||
|
lc.id = len(d.langs)
|
||
|
d.langs = append(d.langs, lc.lang)
|
||
|
d.langDescs = append(d.langDescs, lc.langDesc)
|
||
|
d.store[lc.lang] = lc
|
||
|
|
||
|
return true
|
||
|
}
|
||
|
|
||
|
func (d *localeStore) Reload(langs ...string) error {
|
||
|
if len(langs) == 0 {
|
||
|
for _, lc := range d.store {
|
||
|
err := lc.message.Reload()
|
||
|
if err != nil {
|
||
|
return err
|
||
|
}
|
||
|
}
|
||
|
} else {
|
||
|
for _, lang := range langs {
|
||
|
if lc, ok := d.store[lang]; ok {
|
||
|
err := lc.message.Reload()
|
||
|
if err != nil {
|
||
|
return err
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return nil
|
||
|
}
|
||
|
|
||
|
// Reload locales
|
||
|
func ReloadLangs(langs ...string) error {
|
||
|
return locales.Reload(langs...)
|
||
|
}
|
||
|
|
||
|
// List all locale languages
|
||
|
func ListLangs() []string {
|
||
|
langs := make([]string, len(locales.langs))
|
||
|
copy(langs, locales.langs)
|
||
|
return langs
|
||
|
}
|
||
|
|
||
|
func ListLangDescs() []string {
|
||
|
langDescs := make([]string, len(locales.langDescs))
|
||
|
copy(langDescs, locales.langDescs)
|
||
|
return langDescs
|
||
|
}
|
||
|
|
||
|
// Check language name if exist
|
||
|
func IsExist(lang string) bool {
|
||
|
_, ok := locales.store[lang]
|
||
|
return ok
|
||
|
}
|
||
|
|
||
|
// Check language name if exist
|
||
|
func IndexLang(lang string) int {
|
||
|
if lc, ok := locales.store[lang]; ok {
|
||
|
return lc.id
|
||
|
}
|
||
|
return -1
|
||
|
}
|
||
|
|
||
|
// Get language by index id
|
||
|
func GetLangByIndex(index int) string {
|
||
|
if index < 0 || index >= len(locales.langs) {
|
||
|
return ""
|
||
|
}
|
||
|
return locales.langs[index]
|
||
|
}
|
||
|
|
||
|
func GetDescriptionByIndex(index int) string {
|
||
|
if index < 0 || index >= len(locales.langDescs) {
|
||
|
return ""
|
||
|
}
|
||
|
|
||
|
return locales.langDescs[index]
|
||
|
}
|
||
|
|
||
|
func GetDescriptionByLang(lang string) string {
|
||
|
return GetDescriptionByIndex(IndexLang(lang))
|
||
|
}
|
||
|
|
||
|
func SetMessageWithDesc(lang, langDesc, filePath string, appendFiles ...string) error {
|
||
|
message, err := goconfig.LoadConfigFile(filePath, appendFiles...)
|
||
|
if err == nil {
|
||
|
message.BlockMode = false
|
||
|
lc := new(locale)
|
||
|
lc.lang = lang
|
||
|
lc.langDesc = langDesc
|
||
|
lc.message = message
|
||
|
|
||
|
if locales.Add(lc) == false {
|
||
|
return fmt.Errorf("Lang %s alread exist", lang)
|
||
|
}
|
||
|
}
|
||
|
return err
|
||
|
}
|
||
|
|
||
|
// SetMessage sets the message file for localization.
|
||
|
func SetMessage(lang, filePath string, appendFiles ...string) error {
|
||
|
return SetMessageWithDesc(lang, lang, filePath, appendFiles...)
|
||
|
}
|
||
|
|
||
|
// A Locale describles the information of localization.
|
||
|
type Locale struct {
|
||
|
Lang string
|
||
|
}
|
||
|
|
||
|
// Tr translate content to target language.
|
||
|
func (l Locale) Tr(format string, args ...interface{}) string {
|
||
|
return Tr(l.Lang, format, args...)
|
||
|
}
|
||
|
|
||
|
// Index get lang index of LangStore
|
||
|
func (l Locale) Index() int {
|
||
|
return IndexLang(l.Lang)
|
||
|
}
|
||
|
|
||
|
// Tr translate content to target language.
|
||
|
func Tr(lang, format string, args ...interface{}) string {
|
||
|
var section string
|
||
|
parts := strings.SplitN(format, ".", 2)
|
||
|
if len(parts) == 2 {
|
||
|
section = parts[0]
|
||
|
format = parts[1]
|
||
|
}
|
||
|
|
||
|
value, ok := locales.Get(lang, section, format)
|
||
|
if ok {
|
||
|
format = value
|
||
|
}
|
||
|
|
||
|
if len(args) > 0 {
|
||
|
params := make([]interface{}, 0, len(args))
|
||
|
for _, arg := range args {
|
||
|
if arg != nil {
|
||
|
val := reflect.ValueOf(arg)
|
||
|
if val.Kind() == reflect.Slice {
|
||
|
for i := 0; i < val.Len(); i++ {
|
||
|
params = append(params, val.Index(i).Interface())
|
||
|
}
|
||
|
} else {
|
||
|
params = append(params, arg)
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
return fmt.Sprintf(format, params...)
|
||
|
}
|
||
|
return fmt.Sprintf(format)
|
||
|
}
|