github.com/jlevesy/mattermost-server@v5.3.2-0.20181003190404-7468f35cb0c8+incompatible/utils/i18n.go (about)

     1  // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
     2  // See License.txt for license information.
     3  
     4  package utils
     5  
     6  import (
     7  	"fmt"
     8  	"io/ioutil"
     9  	"net/http"
    10  	"path/filepath"
    11  	"strings"
    12  
    13  	"github.com/mattermost/mattermost-server/mlog"
    14  	"github.com/mattermost/mattermost-server/model"
    15  	"github.com/nicksnyder/go-i18n/i18n"
    16  )
    17  
    18  var T i18n.TranslateFunc
    19  var TDefault i18n.TranslateFunc
    20  var locales map[string]string = make(map[string]string)
    21  var settings model.LocalizationSettings
    22  
    23  // this functions loads translations from filesystem
    24  // and assign english while loading server config
    25  func TranslationsPreInit() error {
    26  	// Set T even if we fail to load the translations. Lots of shutdown handling code will
    27  	// segfault trying to handle the error, and the untranslated IDs are strictly better.
    28  	T = TfuncWithFallback("en")
    29  	TDefault = TfuncWithFallback("en")
    30  	return InitTranslationsWithDir("i18n")
    31  }
    32  
    33  func InitTranslations(localizationSettings model.LocalizationSettings) error {
    34  	settings = localizationSettings
    35  
    36  	var err error
    37  	T, err = GetTranslationsBySystemLocale()
    38  	return err
    39  }
    40  
    41  func InitTranslationsWithDir(dir string) error {
    42  	i18nDirectory, found := FindDir(dir)
    43  	if !found {
    44  		return fmt.Errorf("Unable to find i18n directory")
    45  	}
    46  
    47  	files, _ := ioutil.ReadDir(i18nDirectory)
    48  	for _, f := range files {
    49  		if filepath.Ext(f.Name()) == ".json" {
    50  			filename := f.Name()
    51  			locales[strings.Split(filename, ".")[0]] = filepath.Join(i18nDirectory, filename)
    52  
    53  			if err := i18n.LoadTranslationFile(filepath.Join(i18nDirectory, filename)); err != nil {
    54  				return err
    55  			}
    56  		}
    57  	}
    58  
    59  	return nil
    60  }
    61  
    62  func GetTranslationsBySystemLocale() (i18n.TranslateFunc, error) {
    63  	locale := *settings.DefaultServerLocale
    64  	if _, ok := locales[locale]; !ok {
    65  		mlog.Error(fmt.Sprintf("Failed to load system translations for '%v' attempting to fall back to '%v'", locale, model.DEFAULT_LOCALE))
    66  		locale = model.DEFAULT_LOCALE
    67  	}
    68  
    69  	if locales[locale] == "" {
    70  		return nil, fmt.Errorf("Failed to load system translations for '%v'", model.DEFAULT_LOCALE)
    71  	}
    72  
    73  	translations := TfuncWithFallback(locale)
    74  	if translations == nil {
    75  		return nil, fmt.Errorf("Failed to load system translations")
    76  	}
    77  
    78  	mlog.Info(fmt.Sprintf("Loaded system translations for '%v' from '%v'", locale, locales[locale]))
    79  	return translations, nil
    80  }
    81  
    82  func GetUserTranslations(locale string) i18n.TranslateFunc {
    83  	if _, ok := locales[locale]; !ok {
    84  		locale = model.DEFAULT_LOCALE
    85  	}
    86  
    87  	translations := TfuncWithFallback(locale)
    88  	return translations
    89  }
    90  
    91  func GetTranslationsAndLocale(w http.ResponseWriter, r *http.Request) (i18n.TranslateFunc, string) {
    92  	// This is for checking against locales like pt_BR or zn_CN
    93  	headerLocaleFull := strings.Split(r.Header.Get("Accept-Language"), ",")[0]
    94  	// This is for checking against locales like en, es
    95  	headerLocale := strings.Split(strings.Split(r.Header.Get("Accept-Language"), ",")[0], "-")[0]
    96  	defaultLocale := *settings.DefaultClientLocale
    97  	if locales[headerLocaleFull] != "" {
    98  		translations := TfuncWithFallback(headerLocaleFull)
    99  		return translations, headerLocaleFull
   100  	} else if locales[headerLocale] != "" {
   101  		translations := TfuncWithFallback(headerLocale)
   102  		return translations, headerLocale
   103  	} else if locales[defaultLocale] != "" {
   104  		translations := TfuncWithFallback(defaultLocale)
   105  		return translations, headerLocale
   106  	}
   107  
   108  	translations := TfuncWithFallback(model.DEFAULT_LOCALE)
   109  	return translations, model.DEFAULT_LOCALE
   110  }
   111  
   112  func GetSupportedLocales() map[string]string {
   113  	return locales
   114  }
   115  
   116  func TfuncWithFallback(pref string) i18n.TranslateFunc {
   117  	t, _ := i18n.Tfunc(pref)
   118  	return func(translationID string, args ...interface{}) string {
   119  		if translated := t(translationID, args...); translated != translationID {
   120  			return translated
   121  		}
   122  
   123  		t, _ := i18n.Tfunc(model.DEFAULT_LOCALE)
   124  		return t(translationID, args...)
   125  	}
   126  }