URI: 
       translationProvider.go - hugo - [fork] hugo port for 9front
  HTML git clone https://git.drkhsh.at/hugo.git
   DIR Log
   DIR Files
   DIR Refs
   DIR Submodules
   DIR README
   DIR LICENSE
       ---
       translationProvider.go (3830B)
       ---
            1 // Copyright 2017 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 i18n
           15 
           16 import (
           17         "encoding/json"
           18         "fmt"
           19         "strings"
           20 
           21         "github.com/gohugoio/hugo/common/paths"
           22 
           23         "github.com/gohugoio/hugo/common/herrors"
           24         "golang.org/x/text/language"
           25         yaml "gopkg.in/yaml.v2"
           26 
           27         "github.com/gohugoio/go-i18n/v2/i18n"
           28         "github.com/gohugoio/hugo/helpers"
           29         toml "github.com/pelletier/go-toml/v2"
           30 
           31         "github.com/gohugoio/hugo/deps"
           32         "github.com/gohugoio/hugo/hugofs"
           33         "github.com/gohugoio/hugo/source"
           34 )
           35 
           36 // TranslationProvider provides translation handling, i.e. loading
           37 // of bundles etc.
           38 type TranslationProvider struct {
           39         t Translator
           40 }
           41 
           42 // NewTranslationProvider creates a new translation provider.
           43 func NewTranslationProvider() *TranslationProvider {
           44         return &TranslationProvider{}
           45 }
           46 
           47 // Update updates the i18n func in the provided Deps.
           48 func (tp *TranslationProvider) NewResource(dst *deps.Deps) error {
           49         defaultLangTag, err := language.Parse(dst.Conf.DefaultContentLanguage())
           50         if err != nil {
           51                 defaultLangTag = language.English
           52         }
           53         bundle := i18n.NewBundle(defaultLangTag)
           54 
           55         bundle.RegisterUnmarshalFunc("toml", toml.Unmarshal)
           56         bundle.RegisterUnmarshalFunc("yaml", yaml.Unmarshal)
           57         bundle.RegisterUnmarshalFunc("yml", yaml.Unmarshal)
           58         bundle.RegisterUnmarshalFunc("json", json.Unmarshal)
           59 
           60         w := hugofs.NewWalkway(
           61                 hugofs.WalkwayConfig{
           62                         Fs:         dst.BaseFs.I18n.Fs,
           63                         IgnoreFile: dst.SourceSpec.IgnoreFile,
           64                         PathParser: dst.SourceSpec.Cfg.PathParser(),
           65                         WalkFn: func(path string, info hugofs.FileMetaInfo) error {
           66                                 if info.IsDir() {
           67                                         return nil
           68                                 }
           69                                 return addTranslationFile(bundle, source.NewFileInfo(info))
           70                         },
           71                 })
           72 
           73         if err := w.Walk(); err != nil {
           74                 return err
           75         }
           76 
           77         tp.t = NewTranslator(bundle, dst.Conf, dst.Log)
           78 
           79         dst.Translate = tp.t.Func(dst.Conf.Language().Lang)
           80 
           81         return nil
           82 }
           83 
           84 const artificialLangTagPrefix = "art-x-"
           85 
           86 func addTranslationFile(bundle *i18n.Bundle, r *source.File) error {
           87         f, err := r.FileInfo().Meta().Open()
           88         if err != nil {
           89                 return fmt.Errorf("failed to open translations file %q:: %w", r.LogicalName(), err)
           90         }
           91 
           92         b := helpers.ReaderToBytes(f)
           93         f.Close()
           94 
           95         name := r.LogicalName()
           96         lang := paths.Filename(name)
           97         tag := language.Make(lang)
           98         if tag == language.Und {
           99                 try := artificialLangTagPrefix + lang
          100                 _, err = language.Parse(try)
          101                 if err != nil {
          102                         return fmt.Errorf("%q: %s", try, err)
          103                 }
          104                 name = artificialLangTagPrefix + name
          105         }
          106 
          107         _, err = bundle.ParseMessageFileBytes(b, name)
          108         if err != nil {
          109                 if strings.Contains(err.Error(), "no plural rule") {
          110                         // https://github.com/gohugoio/hugo/issues/7798
          111                         name = artificialLangTagPrefix + name
          112                         _, err = bundle.ParseMessageFileBytes(b, name)
          113                         if err == nil {
          114                                 return nil
          115                         }
          116                 }
          117                 return errWithFileContext(fmt.Errorf("failed to load translations: %w", err), r)
          118         }
          119 
          120         return nil
          121 }
          122 
          123 // CloneResource sets the language func for the new language.
          124 func (tp *TranslationProvider) CloneResource(dst, src *deps.Deps) error {
          125         dst.Translate = tp.t.Func(dst.Conf.Language().Lang)
          126         return nil
          127 }
          128 
          129 func errWithFileContext(inerr error, r *source.File) error {
          130         meta := r.FileInfo().Meta()
          131         realFilename := meta.Filename
          132         f, err := meta.Open()
          133         if err != nil {
          134                 return inerr
          135         }
          136         defer f.Close()
          137 
          138         return herrors.NewFileErrorFromName(inerr, realFilename).UpdateContent(f, nil)
          139 }