From 4652ae4a44d8767496f65646f6480a288b0b1d6b Mon Sep 17 00:00:00 2001 From: =?utf8?q?Bj=C3=B8rn=20Erik=20Pedersen?= Date: Thu, 5 Mar 2026 12:39:43 +0100 Subject: [PATCH] Move to new locales library and upgrade CLDR from v36.1 to v48.1 * I had all kinds of issues upgrading CLDR on the old library, so I decided to start fresh in github.com/bep/golocales * It shaves off about 3 MB of the binary, and package init cost is zero compared to the old localescompressed (5000x faster). * We will probably move to the `text/**` packages at this point, but this will have to do for now. --- common/htime/time.go | 36 ++++++++++++++++++------------------ common/htime/time_test.go | 37 +++++++++++++++++++------------------ go.mod | 5 ++--- go.sum | 22 ++++------------------ hugolib/dates_test.go | 2 +- hugolib/language_test.go | 6 +++--- langs/language.go | 13 ++++++------- tpl/lang/lang.go | 28 +++++++++------------------- tpl/lang/lang_test.go | 14 +++++++------- tpl/time/time_test.go | 17 ++++++++--------- 10 files changed, 77 insertions(+), 103 deletions(-) diff --git a/common/htime/time.go b/common/htime/time.go index c71e39ee4..3745e6aba 100644 --- a/common/htime/time.go +++ b/common/htime/time.go @@ -18,10 +18,10 @@ import ( "strings" "time" + "github.com/bep/golocales" + "github.com/bep/clocks" "github.com/spf13/cast" - - "github.com/gohugoio/locales" ) var ( @@ -78,9 +78,9 @@ var ( Clock = clocks.System() ) -func NewTimeFormatter(ltr locales.Translator) TimeFormatter { +func NewTimeFormatter(ltr golocales.Translator) TimeFormatter { if ltr == nil { - panic("must provide a locales.Translator") + panic("must provide a golocales.Translator") } return TimeFormatter{ ltr: ltr, @@ -89,7 +89,7 @@ func NewTimeFormatter(ltr locales.Translator) TimeFormatter { // TimeFormatter is locale aware. type TimeFormatter struct { - ltr locales.Translator + ltr golocales.Translator } func (f TimeFormatter) Format(t time.Time, layout string) string { @@ -101,39 +101,39 @@ func (f TimeFormatter) Format(t time.Time, layout string) string { // It may be one of Hugo's custom layouts. switch strings.ToLower(layout[1:]) { case "date_full": - return f.ltr.FmtDateFull(t) + return f.ltr.FormatDateFull(t) case "date_long": - return f.ltr.FmtDateLong(t) + return f.ltr.FormatDateLong(t) case "date_medium": - return f.ltr.FmtDateMedium(t) + return f.ltr.FormatDateMedium(t) case "date_short": - return f.ltr.FmtDateShort(t) + return f.ltr.FormatDateShort(t) case "time_full": - return f.ltr.FmtTimeFull(t) + return f.ltr.FormatTimeFull(t) case "time_long": - return f.ltr.FmtTimeLong(t) + return f.ltr.FormatTimeLong(t) case "time_medium": - return f.ltr.FmtTimeMedium(t) + return f.ltr.FormatTimeMedium(t) case "time_short": - return f.ltr.FmtTimeShort(t) + return f.ltr.FormatTimeShort(t) } } s := t.Format(layout) - monthIdx := t.Month() - 1 // Month() starts at 1. + monthIdx := t.Month() - 1 // time.Month is 1-based, but our month name slices are 0-based. dayIdx := t.Weekday() if strings.Contains(layout, "January") { - s = strings.ReplaceAll(s, longMonthNames[monthIdx], f.ltr.MonthWide(t.Month())) + s = strings.ReplaceAll(s, longMonthNames[monthIdx], f.ltr.MonthsWide()[monthIdx]) } else if strings.Contains(layout, "Jan") { - s = strings.ReplaceAll(s, shortMonthNames[monthIdx], f.ltr.MonthAbbreviated(t.Month())) + s = strings.ReplaceAll(s, shortMonthNames[monthIdx], f.ltr.MonthsAbbreviated()[monthIdx]) } if strings.Contains(layout, "Monday") { - s = strings.ReplaceAll(s, longDayNames[dayIdx], f.ltr.WeekdayWide(t.Weekday())) + s = strings.ReplaceAll(s, longDayNames[dayIdx], f.ltr.WeekdaysWide()[dayIdx]) } else if strings.Contains(layout, "Mon") { - s = strings.ReplaceAll(s, shortDayNames[dayIdx], f.ltr.WeekdayAbbreviated(t.Weekday())) + s = strings.ReplaceAll(s, shortDayNames[dayIdx], f.ltr.WeekdaysAbbreviated()[dayIdx]) } return s diff --git a/common/htime/time_test.go b/common/htime/time_test.go index a84d1c3bb..3f875e693 100644 --- a/common/htime/time_test.go +++ b/common/htime/time_test.go @@ -17,8 +17,9 @@ import ( "testing" "time" + "github.com/bep/golocales" + qt "github.com/frankban/quicktest" - translators "github.com/gohugoio/localescompressed" ) func TestTimeFormatter(t *testing.T) { @@ -34,7 +35,7 @@ func TestTimeFormatter(t *testing.T) { mondayNovemberFirst = mondayNovemberFirst.Add(33 * time.Second) c.Run("Norsk nynorsk", func(c *qt.C) { - f := NewTimeFormatter(translators.GetTranslator("nn")) + f := NewTimeFormatter(golocales.New("nn")) c.Assert(f.Format(june06, "Monday Jan 2 2006"), qt.Equals, "onsdag juni 6 2018") c.Assert(f.Format(june06, "Mon January 2 2006"), qt.Equals, "on. juni 6 2018") @@ -42,35 +43,35 @@ func TestTimeFormatter(t *testing.T) { }) c.Run("Custom layouts Norsk nynorsk", func(c *qt.C) { - f := NewTimeFormatter(translators.GetTranslator("nn")) + f := NewTimeFormatter(golocales.New("nn")) c.Assert(f.Format(june06, ":date_full"), qt.Equals, "onsdag 6. juni 2018") c.Assert(f.Format(june06, ":date_long"), qt.Equals, "6. juni 2018") c.Assert(f.Format(june06, ":date_medium"), qt.Equals, "6. juni 2018") - c.Assert(f.Format(june06, ":date_short"), qt.Equals, "06.06.2018") + c.Assert(f.Format(june06, ":date_short"), qt.Equals, "06.06.18") - c.Assert(f.Format(june06, ":time_full"), qt.Equals, "kl. 02:09:37 UTC") + c.Assert(f.Format(june06, ":time_full"), qt.Equals, "02:09:37 UTC") c.Assert(f.Format(june06, ":time_long"), qt.Equals, "02:09:37 UTC") c.Assert(f.Format(june06, ":time_medium"), qt.Equals, "02:09:37") c.Assert(f.Format(june06, ":time_short"), qt.Equals, "02:09") }) c.Run("Custom layouts English", func(c *qt.C) { - f := NewTimeFormatter(translators.GetTranslator("en")) + f := NewTimeFormatter(golocales.New("en")) c.Assert(f.Format(june06, ":date_full"), qt.Equals, "Wednesday, June 6, 2018") c.Assert(f.Format(june06, ":date_long"), qt.Equals, "June 6, 2018") c.Assert(f.Format(june06, ":date_medium"), qt.Equals, "Jun 6, 2018") c.Assert(f.Format(june06, ":date_short"), qt.Equals, "6/6/18") - c.Assert(f.Format(june06, ":time_full"), qt.Equals, "2:09:37 am UTC") - c.Assert(f.Format(june06, ":time_long"), qt.Equals, "2:09:37 am UTC") - c.Assert(f.Format(june06, ":time_medium"), qt.Equals, "2:09:37 am") - c.Assert(f.Format(june06, ":time_short"), qt.Equals, "2:09 am") + c.Assert(f.Format(june06, ":time_full"), qt.Equals, "2:09:37\u202fam UTC") + c.Assert(f.Format(june06, ":time_long"), qt.Equals, "2:09:37\u202fam UTC") + c.Assert(f.Format(june06, ":time_medium"), qt.Equals, "2:09:37\u202fam") + c.Assert(f.Format(june06, ":time_short"), qt.Equals, "2:09\u202fam") }) c.Run("English", func(c *qt.C) { - f := NewTimeFormatter(translators.GetTranslator("en")) + f := NewTimeFormatter(golocales.New("en")) c.Assert(f.Format(june06, "Monday Jan 2 2006"), qt.Equals, "Wednesday Jun 6 2018") c.Assert(f.Format(june06, "Mon January 2 2006"), qt.Equals, "Wed June 6 2018") @@ -78,31 +79,31 @@ func TestTimeFormatter(t *testing.T) { }) c.Run("Weekdays German", func(c *qt.C) { - tr := translators.GetTranslator("de") + tr := golocales.New("de") f := NewTimeFormatter(tr) // Issue #9107 for i, weekDayWideGerman := range []string{"Montag", "Dienstag", "Mittwoch", "Donnerstag", "Freitag", "Samstag", "Sonntag"} { date := mondayNovemberFirst.Add(time.Duration(i*24) * time.Hour) - c.Assert(tr.WeekdayWide(date.Weekday()), qt.Equals, weekDayWideGerman) + c.Assert(tr.WeekdaysWide()[date.Weekday()], qt.Equals, weekDayWideGerman) c.Assert(f.Format(date, "Monday"), qt.Equals, weekDayWideGerman) } for i, weekDayAbbreviatedGerman := range []string{"Mo.", "Di.", "Mi.", "Do.", "Fr.", "Sa.", "So."} { date := mondayNovemberFirst.Add(time.Duration(i*24) * time.Hour) - c.Assert(tr.WeekdayAbbreviated(date.Weekday()), qt.Equals, weekDayAbbreviatedGerman) + c.Assert(tr.WeekdaysAbbreviated()[date.Weekday()], qt.Equals, weekDayAbbreviatedGerman) c.Assert(f.Format(date, "Mon"), qt.Equals, weekDayAbbreviatedGerman) } }) c.Run("Months German", func(c *qt.C) { - tr := translators.GetTranslator("de") + tr := golocales.New("de") f := NewTimeFormatter(tr) // Issue #9107 for i, monthWideNorway := range []string{"Januar", "Februar", "März", "April", "Mai", "Juni", "Juli"} { date := jan06.Add(time.Duration(i*24*31) * time.Hour) - c.Assert(tr.MonthWide(date.Month()), qt.Equals, monthWideNorway) + c.Assert(tr.MonthsWide()[date.Month()-1], qt.Equals, monthWideNorway) c.Assert(f.Format(date, "January"), qt.Equals, monthWideNorway) } }) @@ -121,7 +122,7 @@ func BenchmarkTimeFormatter(b *testing.B) { }) b.Run("Localized", func(b *testing.B) { - f := NewTimeFormatter(translators.GetTranslator("nn")) + f := NewTimeFormatter(golocales.New("nn")) b.ResetTimer() for b.Loop() { got := f.Format(june06, "Monday Jan 2 2006") @@ -132,7 +133,7 @@ func BenchmarkTimeFormatter(b *testing.B) { }) b.Run("Localized Custom", func(b *testing.B) { - f := NewTimeFormatter(translators.GetTranslator("nn")) + f := NewTimeFormatter(golocales.New("nn")) b.ResetTimer() for b.Loop() { got := f.Format(june06, ":date_medium") diff --git a/go.mod b/go.mod index aa142809c..a1fca033d 100644 --- a/go.mod +++ b/go.mod @@ -12,8 +12,9 @@ require ( github.com/bep/goat v0.5.0 github.com/bep/godartsass/v2 v2.5.0 github.com/bep/golibsass v1.2.0 + github.com/bep/golocales v0.1.0 github.com/bep/goportabletext v0.1.0 - github.com/bep/helpers v0.7.0 + github.com/bep/helpers v0.8.0 github.com/bep/imagemeta v0.17.0 github.com/bep/lazycache v0.8.1 github.com/bep/logg v0.4.0 @@ -42,8 +43,6 @@ require ( github.com/gohugoio/httpcache v0.8.0 github.com/gohugoio/hugo-goldmark-extensions/extras v0.6.0 github.com/gohugoio/hugo-goldmark-extensions/passthrough v0.4.0 - github.com/gohugoio/locales v0.14.0 - github.com/gohugoio/localescompressed v1.0.1 github.com/google/go-cmp v0.7.0 github.com/gorilla/websocket v1.5.3 github.com/hairyhenderson/go-codeowners v0.7.0 diff --git a/go.sum b/go.sum index cda32b7e2..bf28c0983 100644 --- a/go.sum +++ b/go.sum @@ -156,10 +156,12 @@ github.com/bep/godartsass/v2 v2.5.0 h1:tKRvwVdyjCIr48qgtLa4gHEdtRkPF8H1OeEhJAEv7 github.com/bep/godartsass/v2 v2.5.0/go.mod h1:rjsi1YSXAl/UbsGL85RLDEjRKdIKUlMQHr6ChUNYOFU= github.com/bep/golibsass v1.2.0 h1:nyZUkKP/0psr8nT6GR2cnmt99xS93Ji82ZD9AgOK6VI= github.com/bep/golibsass v1.2.0/go.mod h1:DL87K8Un/+pWUS75ggYv41bliGiolxzDKWJAq3eJ1MA= +github.com/bep/golocales v0.1.0 h1:rjWf1S4basIje+G+je5WMW8G+yzaoz4gEDFolrFVdvA= +github.com/bep/golocales v0.1.0/go.mod h1:Hl78nje8mNL3LzLeJvYN9NsIZgyFJGrGfvgO9r1+mwE= github.com/bep/goportabletext v0.1.0 h1:8dqym2So1cEqVZiBa4ZnMM1R9l/DnC1h4ONg4J5kujw= github.com/bep/goportabletext v0.1.0/go.mod h1:6lzSTsSue75bbcyvVc0zqd1CdApuT+xkZQ6Re5DzZFg= -github.com/bep/helpers v0.7.0 h1:xruRGxcJ1lkbFhoTftFw4UdQ5/3TqEyxWCQLtfY/Pbg= -github.com/bep/helpers v0.7.0/go.mod h1:NOkGxcWYMzJfri141CUO2MnnEXEKJsnj6xKPlrsahA0= +github.com/bep/helpers v0.8.0 h1:plg2BFgA9AgIHF2XemyZdZLqixjzQk3uyyArV48FngQ= +github.com/bep/helpers v0.8.0/go.mod h1:PfE7MGdA8sSQ19nyDh4tYbs5rAlStlJaDI21f/fnNps= github.com/bep/imagemeta v0.17.0 h1:0sCIQTcmERGUCazrBfmoeh7SoHutlYQqLr24GCItTxA= github.com/bep/imagemeta v0.17.0/go.mod h1:+Hlp195TfZpzsqCxtDKTG6eWdyz2+F2V/oCYfr3CZKA= github.com/bep/lazycache v0.8.1 h1:ko6ASLjkPxyV5DMWoNNZ8B2M0weyjqXX8IZkjBoBtvg= @@ -176,8 +178,6 @@ github.com/bep/textandbinarywriter v0.1.0 h1:KXmXsRN2Uhwhm1G3e/snM8+5SPQBJrCEpIo github.com/bep/textandbinarywriter v0.1.0/go.mod h1:dAcHveajlWWU7PXhp6Dn4PIAYDg2H13Huif9xMS2w8w= github.com/bep/tmc v0.6.0 h1:5zWy4L+3gS+Kk8czzLC4g7ETaC3wkX9ZtTRdAdL8V4s= github.com/bep/tmc v0.6.0/go.mod h1:SNHxc3o2WSNMAYqJcAO0rxFY+pbhZzMwjIHe5xaAue0= -github.com/bep/workers v1.0.0 h1:U+H8YmEaBCEaFZBst7GcRVEoqeRC9dzH2dWOwGmOchg= -github.com/bep/workers v1.0.0/go.mod h1:7kIESOB86HfR2379pwoMWNy8B50D7r99fRLUyPSNyCs= github.com/bits-and-blooms/bitset v1.24.4 h1:95H15Og1clikBrKr/DuzMXkQzECs1M6hhoGXLwLQOZE= github.com/bits-and-blooms/bitset v1.24.4/go.mod h1:7hO7Gc7Pp1vODcmWvKMRA9BNmbv6a/7QIWpPxHddWR8= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= @@ -236,7 +236,6 @@ github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSw github.com/fortytw2/leaktest v1.3.0 h1:u8491cBMTQ8ft8aeV+adlcytMZylmA5nnwwkRZjI8vw= github.com/fortytw2/leaktest v1.3.0/go.mod h1:jDsjWgpAGjm2CA7WthBh/CdZYEPF31XHquHwclZch5g= github.com/frankban/quicktest v1.7.2/go.mod h1:jaStnuzAqU1AJdCO0l53JDCJrVDKcS03DbaAcR7Ks/o= -github.com/frankban/quicktest v1.13.0/go.mod h1:qLE0fzW0VuyUAJgPU19zByoIr0HtCHN/r/VLSOOIySU= github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8= github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0= github.com/fsnotify/fsnotify v1.9.0 h1:2Ml+OJNzbYCTzsxtv8vKSFD9PbJjmhYF14k/jKC7S9k= @@ -281,10 +280,6 @@ github.com/gohugoio/hugo-goldmark-extensions/extras v0.6.0 h1:c16engMi6zyOGeCrP7 github.com/gohugoio/hugo-goldmark-extensions/extras v0.6.0/go.mod h1:e3+TRCT4Uz6NkZOAVMOMgPeJ+7KEtQMX8hdB+WG4qRs= github.com/gohugoio/hugo-goldmark-extensions/passthrough v0.4.0 h1:awFlqaCQ0N/RS9ndIBpDYNms101I1sGbDRG1bksa5Js= github.com/gohugoio/hugo-goldmark-extensions/passthrough v0.4.0/go.mod h1:lK1CjqrueCd3OBnsLLQJGrQ+uodWfT9M9Cq2zfDWJCE= -github.com/gohugoio/locales v0.14.0 h1:Q0gpsZwfv7ATHMbcTNepFd59H7GoykzWJIxi113XGDc= -github.com/gohugoio/locales v0.14.0/go.mod h1:ip8cCAv/cnmVLzzXtiTpPwgJ4xhKZranqNqtoIu0b/4= -github.com/gohugoio/localescompressed v1.0.1 h1:KTYMi8fCWYLswFyJAeOtuk/EkXR/KPTHHNN9OS+RTxo= -github.com/gohugoio/localescompressed v1.0.1/go.mod h1:jBF6q8D7a0vaEmcWPNcAjUZLJaIVNiwvM3WlmTvooB0= github.com/golang-jwt/jwt/v5 v5.2.3 h1:kkGXqQOBSDDWRhWNXTFpqGSCMyh/PLnqUvMGJPDJDs0= github.com/golang-jwt/jwt/v5 v5.2.3/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= @@ -325,7 +320,6 @@ github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= @@ -392,7 +386,6 @@ github.com/keybase/go-keychain v0.0.1/go.mod h1:PdEILRW3i9D8JcdM+FmY6RwkHGnhHxXw github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= -github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= @@ -520,7 +513,6 @@ github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9de github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/yuin/goldmark v1.7.16 h1:n+CJdUxaFMiDUNnWC3dMWCIQJSkxH4uz3ZwQBkAlVNE= github.com/yuin/goldmark v1.7.16/go.mod h1:ip/1k0VRfGynBgxOz0yCqHrbZXhcjxyuS66Brc7iBKg= github.com/yuin/goldmark-emoji v1.0.6 h1:QWfF2FYaXwL74tfGOW5izeiZepUDroDJfWubQI9HTHs= @@ -604,7 +596,6 @@ golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.33.0 h1:tHFzIWbBifEmbwtGz65eaWyGiGZatSrT9prnU8DbVL8= golang.org/x/mod v0.33.0/go.mod h1:swjeQEj+6r7fODbD2cqrnje9PnziFuw4bmLbBZFrQ5w= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -638,7 +629,6 @@ golang.org/x/net v0.0.0-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwY golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= -golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.51.0 h1:94R/GTO7mt3/4wIKpcR5gkGmRLOuE/2hNGeWq/GBIFo= golang.org/x/net v0.51.0/go.mod h1:aamm+2QF5ogm02fjy5Bb7CQ0WMt1/WVM7FtyaTLlA9Y= @@ -663,7 +653,6 @@ golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.19.0 h1:vV+1eWNmZ5geRlYjzm2adRgW2/mcpevXNg50YZtPCE4= golang.org/x/sync v0.19.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -698,10 +687,8 @@ golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -770,7 +757,6 @@ golang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4f golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210108195828-e2f9c7f1fc8e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= -golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.42.0 h1:uNgphsn75Tdz5Ji2q36v/nsFSfR/9BRFvqhGBaJGd5k= golang.org/x/tools v0.42.0/go.mod h1:Ma6lCIwGZvHK6XtgbswSoWroEkhugApmsXyrUmBhfr0= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= diff --git a/hugolib/dates_test.go b/hugolib/dates_test.go index 7e886d596..b140fbcef 100644 --- a/hugolib/dates_test.go +++ b/hugolib/dates_test.go @@ -253,7 +253,7 @@ Past talks: 3 Home's Date should be greater than past: true Home's Date should be less than future: true Home's Date should be equal mydata date: true -Full time: 6:00:00 am UTC +Full time: 6:00:00 am UTC `) } diff --git a/hugolib/language_test.go b/hugolib/language_test.go index e242fc907..172403ed8 100644 --- a/hugolib/language_test.go +++ b/hugolib/language_test.go @@ -118,9 +118,9 @@ FormatNumberCustom: 12,345.68 b.AssertFileContent("public/nn/index.html", ` FormatNumber: 512,50 -FormatPercent: 512,50 % -FormatCurrency: 512,50 USD -FormatAccounting: 512,50 kr +FormatPercent: 512,50 % +FormatCurrency: 512,50 USD +FormatAccounting: 512,50 kr FormatNumberCustom: 12,345.68 `) diff --git a/langs/language.go b/langs/language.go index 3560663ee..1ff15b266 100644 --- a/langs/language.go +++ b/langs/language.go @@ -22,14 +22,13 @@ import ( "golang.org/x/text/collate" "golang.org/x/text/language" + "github.com/bep/golocales" "github.com/bep/logg" "github.com/gohugoio/hugo/common/hmaps" "github.com/gohugoio/hugo/common/htime" "github.com/gohugoio/hugo/common/hugo" "github.com/gohugoio/hugo/common/loggers" "github.com/gohugoio/hugo/hugolib/sitesmatrix" - "github.com/gohugoio/locales" - translators "github.com/gohugoio/localescompressed" ) var _ sitesmatrix.DimensionInfo = (*Language)(nil) @@ -45,7 +44,7 @@ type Language struct { // Used for date formatting etc. We don't want these exported to the // templates. - translator locales.Translator + translator golocales.Translator timeFormatter htime.TimeFormatter tag language.Tag @@ -80,11 +79,11 @@ func (l *Language) IsDefault() bool { // NewLanguage creates a new language. func NewLanguage(lang, defaultContentLanguage, timeZone string, languageConfig LanguageConfig, logger loggers.Logger) (*Language, error) { - translator := translators.GetTranslator(lang) + translator := golocales.New(lang) if translator == nil { - translator = translators.GetTranslator(defaultContentLanguage) + translator = golocales.New(defaultContentLanguage) if translator == nil { - translator = translators.GetTranslator("en") + translator = golocales.New("en") } } @@ -223,7 +222,7 @@ func GetTimeFormatter(l *Language) htime.TimeFormatter { return l.timeFormatter } -func GetTranslator(l *Language) locales.Translator { +func GetTranslator(l *Language) golocales.Translator { return l.translator } diff --git a/tpl/lang/lang.go b/tpl/lang/lang.go index 4cbd661af..cf510f534 100644 --- a/tpl/lang/lang.go +++ b/tpl/lang/lang.go @@ -22,16 +22,14 @@ import ( "strconv" "strings" - "github.com/gohugoio/locales" - translators "github.com/gohugoio/localescompressed" - + "github.com/bep/golocales" "github.com/gohugoio/hugo/common/hreflect" "github.com/gohugoio/hugo/deps" "github.com/spf13/cast" ) // New returns a new instance of the lang-namespaced template functions. -func New(deps *deps.Deps, translator locales.Translator) *Namespace { +func New(deps *deps.Deps, translator golocales.Translator) *Namespace { return &Namespace{ translator: translator, deps: deps, @@ -40,7 +38,7 @@ func New(deps *deps.Deps, translator locales.Translator) *Namespace { // Namespace provides template functions for the "lang" namespace. type Namespace struct { - translator locales.Translator + translator golocales.Translator deps *deps.Deps } @@ -69,7 +67,7 @@ func (ns *Namespace) FormatNumber(precision, number any) (string, error) { if err != nil { return "", err } - return ns.translator.FmtNumber(n, p), nil + return ns.translator.FormatNumber(n, p), nil } // FormatPercent formats number with the given precision for the current language. @@ -79,7 +77,7 @@ func (ns *Namespace) FormatPercent(precision, number any) (string, error) { if err != nil { return "", err } - return ns.translator.FmtPercent(n, p), nil + return ns.translator.FormatPercent(n, p), nil } // FormatCurrency returns the currency representation of number for the given currency and precision @@ -91,11 +89,7 @@ func (ns *Namespace) FormatCurrency(precision, currency, number any) (string, er if err != nil { return "", err } - c := translators.GetCurrency(cast.ToString(currency)) - if c < 0 { - return "", fmt.Errorf("unknown currency code: %q", currency) - } - return ns.translator.FmtCurrency(n, p, c), nil + return ns.translator.FormatCurrency(n, p, cast.ToString(currency)), nil } // FormatAccounting returns the currency representation of number for the given currency and precision @@ -107,15 +101,11 @@ func (ns *Namespace) FormatAccounting(precision, currency, number any) (string, if err != nil { return "", err } - c := translators.GetCurrency(cast.ToString(currency)) - if c < 0 { - return "", fmt.Errorf("unknown currency code: %q", currency) - } - return ns.translator.FmtAccounting(n, p, c), nil + return ns.translator.FormatAccounting(n, p, cast.ToString(currency)), nil } -func (ns *Namespace) castPrecisionNumber(precision, number any) (uint64, float64, error) { - p, err := cast.ToUint64E(precision) +func (ns *Namespace) castPrecisionNumber(precision, number any) (int, float64, error) { + p, err := cast.ToIntE(precision) if err != nil { return 0, 0, err } diff --git a/tpl/lang/lang_test.go b/tpl/lang/lang_test.go index 6ec40cab3..0e970ed3c 100644 --- a/tpl/lang/lang_test.go +++ b/tpl/lang/lang_test.go @@ -3,9 +3,9 @@ package lang import ( "testing" + "github.com/bep/golocales" qt "github.com/frankban/quicktest" "github.com/gohugoio/hugo/deps" - translators "github.com/gohugoio/localescompressed" ) func TestNumFmt(t *testing.T) { @@ -67,8 +67,8 @@ func TestNumFmt(t *testing.T) { func TestFormatNumbers(t *testing.T) { c := qt.New(t) - nsNn := New(&deps.Deps{}, translators.GetTranslator("nn")) - nsEn := New(&deps.Deps{}, translators.GetTranslator("en")) + nsNn := New(&deps.Deps{}, golocales.New("nn")) + nsEn := New(&deps.Deps{}, golocales.New("en")) pi := 3.14159265359 c.Run("FormatNumber", func(c *qt.C) { @@ -108,10 +108,10 @@ func TestFormatNumbers(t *testing.T) { func TestLanguageKeyFormat(t *testing.T) { c := qt.New(t) - nsUnderscoreUpper := New(&deps.Deps{}, translators.GetTranslator("es_ES")) - nsUnderscoreLower := New(&deps.Deps{}, translators.GetTranslator("es_es")) - nsHyphenUpper := New(&deps.Deps{}, translators.GetTranslator("es-ES")) - nsHyphenLower := New(&deps.Deps{}, translators.GetTranslator("es-es")) + nsUnderscoreUpper := New(&deps.Deps{}, golocales.New("es_ES")) + nsUnderscoreLower := New(&deps.Deps{}, golocales.New("es_es")) + nsHyphenUpper := New(&deps.Deps{}, golocales.New("es-ES")) + nsHyphenLower := New(&deps.Deps{}, golocales.New("es-es")) pi := 3.14159265359 c.Run("FormatNumber", func(c *qt.C) { diff --git a/tpl/time/time_test.go b/tpl/time/time_test.go index a0989d78f..87656b38c 100644 --- a/tpl/time/time_test.go +++ b/tpl/time/time_test.go @@ -18,13 +18,12 @@ import ( "testing" gtime "time" + "github.com/bep/golocales" qt "github.com/frankban/quicktest" "github.com/gohugoio/hugo/common/htime" "github.com/gohugoio/hugo/hugolib" "github.com/gohugoio/hugo/tpl/time" - - translators "github.com/gohugoio/localescompressed" ) func TestTimeLocation(t *testing.T) { @@ -35,7 +34,7 @@ func TestTimeLocation(t *testing.T) { ).Build() loc, _ := gtime.LoadLocation("America/Antigua") - ns := time.New(htime.NewTimeFormatter(translators.GetTranslator("en")), loc, b.H.Deps) + ns := time.New(htime.NewTimeFormatter(golocales.New("en")), loc, b.H.Deps) for i, test := range []struct { name string @@ -99,7 +98,7 @@ func TestFormat(t *testing.T) { c.Run("UTC", func(c *qt.C) { c.Parallel() - ns := time.New(htime.NewTimeFormatter(translators.GetTranslator("en")), gtime.UTC, b.H.Deps) + ns := time.New(htime.NewTimeFormatter(golocales.New("en")), gtime.UTC, b.H.Deps) for i, test := range []struct { layout string @@ -142,12 +141,12 @@ func TestFormat(t *testing.T) { loc, err := gtime.LoadLocation("America/Los_Angeles") c.Assert(err, qt.IsNil) - ns := time.New(htime.NewTimeFormatter(translators.GetTranslator("en")), loc, b.H.Deps) + ns := time.New(htime.NewTimeFormatter(golocales.New("en")), loc, b.H.Deps) d, err := ns.Format(":time_full", "2020-03-09T11:00:00") c.Assert(err, qt.IsNil) - c.Assert(d, qt.Equals, "11:00:00 am Pacific Daylight Time") + c.Assert(d, qt.Equals, "11:00:00\u202fam Pacific Daylight Time") }) } @@ -158,7 +157,7 @@ func TestDuration(t *testing.T) { hugolib.IntegrationTestConfig{T: t}, ).Build() - ns := time.New(htime.NewTimeFormatter(translators.GetTranslator("en")), gtime.UTC, b.H.Deps) + ns := time.New(htime.NewTimeFormatter(golocales.New("en")), gtime.UTC, b.H.Deps) for i, test := range []struct { unit any @@ -205,7 +204,7 @@ func TestIn(t *testing.T) { hugolib.IntegrationTestConfig{T: t}, ).Build() - ns := time.New(htime.NewTimeFormatter(translators.GetTranslator("en")), gtime.UTC, b.H.Deps) + ns := time.New(htime.NewTimeFormatter(golocales.New("en")), gtime.UTC, b.H.Deps) in := gtime.Date(2025, gtime.March, 31, 15, 0, 0, 0, gtime.UTC) @@ -246,7 +245,7 @@ func BenchmarkInWithCaching(b *testing.B) { hugolib.IntegrationTestConfig{T: b}, ).Build() - ns := time.New(htime.NewTimeFormatter(translators.GetTranslator("en")), gtime.UTC, bb.H.Deps) + ns := time.New(htime.NewTimeFormatter(golocales.New("en")), gtime.UTC, bb.H.Deps) for i := 0; b.Loop(); i++ { timeZoneName := timeZoneNames[i%len(timeZoneNames)] -- 2.39.5