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