github.com/schumacherfm/hugo@v0.47.1/hugolib/multilingual.go (about)

     1  // Copyright 2016-present The Hugo Authors. All rights reserved.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  // http://www.apache.org/licenses/LICENSE-2.0
     7  //
     8  // Unless required by applicable law or agreed to in writing, software
     9  // distributed under the License is distributed on an "AS IS" BASIS,
    10  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    11  // See the License for the specific language governing permissions and
    12  // limitations under the License.
    13  
    14  package hugolib
    15  
    16  import (
    17  	"sync"
    18  
    19  	"github.com/gohugoio/hugo/common/maps"
    20  
    21  	"sort"
    22  
    23  	"errors"
    24  	"fmt"
    25  
    26  	"github.com/gohugoio/hugo/langs"
    27  
    28  	"github.com/gohugoio/hugo/config"
    29  	"github.com/spf13/cast"
    30  )
    31  
    32  // Multilingual manages the all languages used in a multilingual site.
    33  type Multilingual struct {
    34  	Languages langs.Languages
    35  
    36  	DefaultLang *langs.Language
    37  
    38  	langMap     map[string]*langs.Language
    39  	langMapInit sync.Once
    40  }
    41  
    42  // Language returns the Language associated with the given string.
    43  func (ml *Multilingual) Language(lang string) *langs.Language {
    44  	ml.langMapInit.Do(func() {
    45  		ml.langMap = make(map[string]*langs.Language)
    46  		for _, l := range ml.Languages {
    47  			ml.langMap[l.Lang] = l
    48  		}
    49  	})
    50  	return ml.langMap[lang]
    51  }
    52  
    53  func getLanguages(cfg config.Provider) langs.Languages {
    54  	if cfg.IsSet("languagesSorted") {
    55  		return cfg.Get("languagesSorted").(langs.Languages)
    56  	}
    57  
    58  	return langs.Languages{langs.NewDefaultLanguage(cfg)}
    59  }
    60  
    61  func newMultiLingualFromSites(cfg config.Provider, sites ...*Site) (*Multilingual, error) {
    62  	languages := make(langs.Languages, len(sites))
    63  
    64  	for i, s := range sites {
    65  		if s.Language == nil {
    66  			return nil, errors.New("Missing language for site")
    67  		}
    68  		languages[i] = s.Language
    69  	}
    70  
    71  	defaultLang := cfg.GetString("defaultContentLanguage")
    72  
    73  	if defaultLang == "" {
    74  		defaultLang = "en"
    75  	}
    76  
    77  	return &Multilingual{Languages: languages, DefaultLang: langs.NewLanguage(defaultLang, cfg)}, nil
    78  
    79  }
    80  
    81  func newMultiLingualForLanguage(language *langs.Language) *Multilingual {
    82  	languages := langs.Languages{language}
    83  	return &Multilingual{Languages: languages, DefaultLang: language}
    84  }
    85  func (ml *Multilingual) enabled() bool {
    86  	return len(ml.Languages) > 1
    87  }
    88  
    89  func (s *Site) multilingualEnabled() bool {
    90  	if s.owner == nil {
    91  		return false
    92  	}
    93  	return s.owner.multilingual != nil && s.owner.multilingual.enabled()
    94  }
    95  
    96  func toSortedLanguages(cfg config.Provider, l map[string]interface{}) (langs.Languages, error) {
    97  	languages := make(langs.Languages, len(l))
    98  	i := 0
    99  
   100  	for lang, langConf := range l {
   101  		langsMap, err := cast.ToStringMapE(langConf)
   102  
   103  		if err != nil {
   104  			return nil, fmt.Errorf("Language config is not a map: %T", langConf)
   105  		}
   106  
   107  		language := langs.NewLanguage(lang, cfg)
   108  
   109  		for loki, v := range langsMap {
   110  			switch loki {
   111  			case "title":
   112  				language.Title = cast.ToString(v)
   113  			case "languagename":
   114  				language.LanguageName = cast.ToString(v)
   115  			case "weight":
   116  				language.Weight = cast.ToInt(v)
   117  			case "contentdir":
   118  				language.ContentDir = cast.ToString(v)
   119  			case "disabled":
   120  				language.Disabled = cast.ToBool(v)
   121  			case "params":
   122  				m := cast.ToStringMap(v)
   123  				// Needed for case insensitive fetching of params values
   124  				maps.ToLower(m)
   125  				for k, vv := range m {
   126  					language.SetParam(k, vv)
   127  				}
   128  			}
   129  
   130  			// Put all into the Params map
   131  			language.SetParam(loki, v)
   132  
   133  			// Also set it in the configuration map (for baseURL etc.)
   134  			language.Set(loki, v)
   135  		}
   136  
   137  		languages[i] = language
   138  		i++
   139  	}
   140  
   141  	sort.Sort(languages)
   142  
   143  	return languages, nil
   144  }