URI: 
       Localize all the GroupBy*Date methods - hugo - [fork] hugo port for 9front
  HTML git clone git@git.drkhsh.at/hugo.git
   DIR Log
   DIR Files
   DIR Refs
   DIR Submodules
   DIR README
   DIR LICENSE
       ---
   DIR commit 658e11ebaa94de219f941699d119a97a18301eea
   DIR parent e0a882fd3b9825dc9a95b83d72fc330dcbbbcce9
  HTML Author: Bjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com>
       Date:   Tue,  5 Apr 2022 09:57:58 +0200
       
       Localize all the GroupBy*Date methods
       
       Fixes #9745
       
       Diffstat:
         M hugolib/hugo_sites.go               |       3 +++
         M hugolib/hugo_sites_build.go         |       1 +
         M hugolib/site.go                     |       5 +++++
         M langs/language.go                   |      15 +++++++++++----
         A resources/page/integration_test.go  |      72 +++++++++++++++++++++++++++++++
         M resources/page/page_matcher_test.go |       3 ++-
         M resources/page/pagegroup.go         |      51 ++++++++++++++++++-------------
         M resources/page/pages_sort_test.go   |      13 ++++++-------
         M resources/page/site.go              |       5 +++++
         M resources/page/testhelpers_test.go  |       1 +
         M tpl/time/init.go                    |       2 +-
         M tpl/time/time.go                    |       6 ++----
         M tpl/time/time_test.go               |       9 +++++----
       
       13 files changed, 144 insertions(+), 42 deletions(-)
       ---
   DIR diff --git a/hugolib/hugo_sites.go b/hugolib/hugo_sites.go
       @@ -73,6 +73,9 @@ type HugoSites struct {
                // Render output formats for all sites.
                renderFormats output.Formats
        
       +        // The currently rendered Site.
       +        currentSite *Site
       +
                *deps.Deps
        
                gitInfo       *gitInfo
   DIR diff --git a/hugolib/hugo_sites_build.go b/hugolib/hugo_sites_build.go
       @@ -289,6 +289,7 @@ func (h *HugoSites) render(config *BuildCfg) error {
        
                i := 0
                for _, s := range h.Sites {
       +                h.currentSite = s
                        for siteOutIdx, renderFormat := range s.renderFormats {
                                siteRenderContext.outIdx = siteOutIdx
                                siteRenderContext.sitesOutIdx = i
   DIR diff --git a/hugolib/site.go b/hugolib/site.go
       @@ -738,6 +738,11 @@ func (s *SiteInfo) Sites() page.Sites {
                return s.s.h.siteInfos()
        }
        
       +// Current returns the currently rendered Site.
       +func (s *SiteInfo) Current() page.Site {
       +        return s.s.h.currentSite.Info
       +}
       +
        func (s *SiteInfo) String() string {
                return fmt.Sprintf("Site(%q)", s.title)
        }
   DIR diff --git a/langs/language.go b/langs/language.go
       @@ -21,6 +21,7 @@ import (
        
                "github.com/pkg/errors"
        
       +        "github.com/gohugoio/hugo/common/htime"
                "github.com/gohugoio/hugo/common/maps"
                "github.com/gohugoio/hugo/config"
                "github.com/gohugoio/locales"
       @@ -77,7 +78,8 @@ type Language struct {
                // Used for date formatting etc. We don't want these exported to the
                // templates.
                // TODO(bep) do the same for some of the others.
       -        translator locales.Translator
       +        translator    locales.Translator
       +        timeFormatter htime.TimeFormatter
        
                location *time.Location
        
       @@ -113,9 +115,10 @@ func NewLanguage(lang string, cfg config.Provider) *Language {
                        Lang:       lang,
                        ContentDir: cfg.GetString("contentDir"),
                        Cfg:        cfg, LocalCfg: localCfg,
       -                Provider:   compositeConfig,
       -                params:     params,
       -                translator: translator,
       +                Provider:      compositeConfig,
       +                params:        params,
       +                translator:    translator,
       +                timeFormatter: htime.NewTimeFormatter(translator),
                }
        
                if err := l.loadLocation(cfg.GetString("timeZone")); err != nil {
       @@ -260,6 +263,10 @@ func (l *Language) IsSet(key string) bool {
        // Internal access to unexported Language fields.
        // This construct is to prevent them from leaking to the templates.
        
       +func GetTimeFormatter(l *Language) htime.TimeFormatter {
       +        return l.timeFormatter
       +}
       +
        func GetTranslator(l *Language) locales.Translator {
                return l.translator
        }
   DIR diff --git a/resources/page/integration_test.go b/resources/page/integration_test.go
       @@ -0,0 +1,72 @@
       +// Copyright 2021 The Hugo Authors. All rights reserved.
       +//
       +// Licensed under the Apache License, Version 2.0 (the "License");
       +// you may not use this file except in compliance with the License.
       +// You may obtain a copy of the License at
       +// http://www.apache.org/licenses/LICENSE-2.0
       +//
       +// Unless required by applicable law or agreed to in writing, software
       +// distributed under the License is distributed on an "AS IS" BASIS,
       +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
       +// See the License for the specific language governing permissions and
       +// limitations under the License.
       +
       +package page_test
       +
       +import (
       +        "testing"
       +
       +        "github.com/gohugoio/hugo/hugolib"
       +)
       +
       +func TestGroupByLocalizedDate(t *testing.T) {
       +
       +        files := `
       +-- config.toml --
       +defaultContentLanguage = 'en'
       +defaultContentLanguageInSubdir = true
       +[languages]
       +[languages.en]
       +title = 'My blog'
       +weight = 1
       +[languages.fr]
       +title = 'Mon blogue'
       +weight = 2
       +[languages.nn]
       +title = 'Bloggen min'
       +weight = 3
       +-- content/p1.md --
       +---
       +title: "Post 1"
       +date: "2020-01-01"
       +---
       +-- content/p2.md --
       +---
       +title: "Post 2"
       +date: "2020-02-01"
       +---
       +-- content/p1.fr.md --
       +---
       +title: "Post 1"
       +date: "2020-01-01"
       +---
       +-- content/p2.fr.md --
       +---
       +title: "Post 2"
       +date: "2020-02-01"
       +---
       +-- layouts/index.html --
       +{{ range $k, $v := site.RegularPages.GroupByDate "January, 2006" }}{{ $k }}|{{ $v.Key }}|{{ $v.Pages }}{{ end }}
       +
       +        `
       +
       +        b := hugolib.NewIntegrationTestBuilder(
       +                hugolib.IntegrationTestConfig{
       +                        T:           t,
       +                        TxtarString: files,
       +                        NeedsOsFS:   true,
       +                }).Build()
       +
       +        b.AssertFileContent("public/en/index.html", "0|February, 2020|Pages(1)1|January, 2020|Pages(1)")
       +        b.AssertFileContent("public/fr/index.html", "0|février, 2020|Pages(1)1|janvier, 2020|Pages(1)")
       +}
   DIR diff --git a/resources/page/page_matcher_test.go b/resources/page/page_matcher_test.go
       @@ -14,10 +14,11 @@
        package page
        
        import (
       -        "github.com/gohugoio/hugo/common/hugo"
                "path/filepath"
                "testing"
        
       +        "github.com/gohugoio/hugo/common/hugo"
       +
                qt "github.com/frankban/quicktest"
        )
        
   DIR diff --git a/resources/page/pagegroup.go b/resources/page/pagegroup.go
       @@ -26,6 +26,7 @@ import (
                "github.com/gohugoio/hugo/common/collections"
                "github.com/gohugoio/hugo/common/hreflect"
                "github.com/gohugoio/hugo/compare"
       +        "github.com/gohugoio/hugo/langs"
        
                "github.com/gohugoio/hugo/resources/resource"
        )
       @@ -219,7 +220,7 @@ func (p Pages) GroupByParam(key string, order ...string) (PagesGroup, error) {
                return r, nil
        }
        
       -func (p Pages) groupByDateField(sorter func(p Pages) Pages, formatter func(p Page) string, order ...string) (PagesGroup, error) {
       +func (p Pages) groupByDateField(format string, sorter func(p Pages) Pages, getDate func(p Page) time.Time, order ...string) (PagesGroup, error) {
                if len(p) < 1 {
                        return nil, nil
                }
       @@ -234,16 +235,24 @@ func (p Pages) groupByDateField(sorter func(p Pages) Pages, formatter func(p Pag
                        return nil, nil
                }
        
       -        date := formatter(sp[0].(Page))
       +        firstPage := sp[0].(Page)
       +        date := getDate(firstPage)
       +
       +        // Pages may be a mix of multiple languages, so we need to use the language
       +        // for the currently rendered Site.
       +        currentSite := firstPage.Site().Current()
       +        formatter := langs.GetTimeFormatter(currentSite.Language())
       +        formatted := formatter.Format(date, format)
                var r []PageGroup
       -        r = append(r, PageGroup{Key: date, Pages: make(Pages, 0)})
       +        r = append(r, PageGroup{Key: formatted, Pages: make(Pages, 0)})
                r[0].Pages = append(r[0].Pages, sp[0])
        
                i := 0
                for _, e := range sp[1:] {
       -                date = formatter(e.(Page))
       -                if r[i].Key.(string) != date {
       -                        r = append(r, PageGroup{Key: date})
       +                date = getDate(e.(Page))
       +                formatted := formatter.Format(date, format)
       +                if r[i].Key.(string) != formatted {
       +                        r = append(r, PageGroup{Key: formatted})
                                i++
                        }
                        r[i].Pages = append(r[i].Pages, e)
       @@ -259,10 +268,10 @@ func (p Pages) GroupByDate(format string, order ...string) (PagesGroup, error) {
                sorter := func(p Pages) Pages {
                        return p.ByDate()
                }
       -        formatter := func(p Page) string {
       -                return p.Date().Format(format)
       +        getDate := func(p Page) time.Time {
       +                return p.Date()
                }
       -        return p.groupByDateField(sorter, formatter, order...)
       +        return p.groupByDateField(format, sorter, getDate, order...)
        }
        
        // GroupByPublishDate groups by the given page's PublishDate value in
       @@ -273,10 +282,10 @@ func (p Pages) GroupByPublishDate(format string, order ...string) (PagesGroup, e
                sorter := func(p Pages) Pages {
                        return p.ByPublishDate()
                }
       -        formatter := func(p Page) string {
       -                return p.PublishDate().Format(format)
       +        getDate := func(p Page) time.Time {
       +                return p.PublishDate()
                }
       -        return p.groupByDateField(sorter, formatter, order...)
       +        return p.groupByDateField(format, sorter, getDate, order...)
        }
        
        // GroupByExpiryDate groups by the given page's ExpireDate value in
       @@ -287,10 +296,10 @@ func (p Pages) GroupByExpiryDate(format string, order ...string) (PagesGroup, er
                sorter := func(p Pages) Pages {
                        return p.ByExpiryDate()
                }
       -        formatter := func(p Page) string {
       -                return p.ExpiryDate().Format(format)
       +        getDate := func(p Page) time.Time {
       +                return p.ExpiryDate()
                }
       -        return p.groupByDateField(sorter, formatter, order...)
       +        return p.groupByDateField(format, sorter, getDate, order...)
        }
        
        // GroupByLastmod groups by the given page's Lastmod value in
       @@ -301,10 +310,10 @@ func (p Pages) GroupByLastmod(format string, order ...string) (PagesGroup, error
                sorter := func(p Pages) Pages {
                        return p.ByLastmod()
                }
       -        formatter := func(p Page) string {
       -                return p.Lastmod().Format(format)
       +        getDate := func(p Page) time.Time {
       +                return p.Lastmod()
                }
       -        return p.groupByDateField(sorter, formatter, order...)
       +        return p.groupByDateField(format, sorter, getDate, order...)
        }
        
        // GroupByParamDate groups by a date set as a param on the page in
       @@ -340,10 +349,10 @@ func (p Pages) GroupByParamDate(key string, format string, order ...string) (Pag
                        pageBy(pdate).Sort(r)
                        return r
                }
       -        formatter := func(p Page) string {
       -                return dates[p].Format(format)
       +        getDate := func(p Page) time.Time {
       +                return dates[p]
                }
       -        return p.groupByDateField(sorter, formatter, order...)
       +        return p.groupByDateField(format, sorter, getDate, order...)
        }
        
        // ProbablyEq wraps compare.ProbablyEqer
   DIR diff --git a/resources/page/pages_sort_test.go b/resources/page/pages_sort_test.go
       @@ -18,18 +18,17 @@ import (
                "testing"
                "time"
        
       -        "github.com/gohugoio/hugo/htesting/hqt"
       -        "github.com/gohugoio/hugo/source"
       -
                "github.com/gohugoio/hugo/resources/resource"
       +        "github.com/google/go-cmp/cmp"
        
                qt "github.com/frankban/quicktest"
        )
        
       -var eq = qt.CmpEquals(hqt.DeepAllowUnexported(
       -        &testPage{},
       -        &source.FileInfo{},
       -))
       +var eq = qt.CmpEquals(
       +        cmp.Comparer(func(p1, p2 testPage) bool {
       +                return p1.path == p2.path && p1.weight == p2.weight
       +        }),
       +)
        
        func TestDefaultSort(t *testing.T) {
                t.Parallel()
   DIR diff --git a/resources/page/site.go b/resources/page/site.go
       @@ -37,6 +37,7 @@ type Site interface {
                ServerPort() int
                Title() string
                Sites() Sites
       +        Current() Site
                Hugo() hugo.Info
                BaseURL() template.URL
                Taxonomies() any
       @@ -82,6 +83,10 @@ func (t testSite) Sites() Sites {
                return nil
        }
        
       +func (t testSite) Current() Site {
       +        return t
       +}
       +
        func (t testSite) IsServer() bool {
                return false
        }
   DIR diff --git a/resources/page/testhelpers_test.go b/resources/page/testhelpers_test.go
       @@ -64,6 +64,7 @@ func newTestPageWithFile(filename string) *testPage {
                        currentSection: &testPage{
                                sectionEntries: []string{"a", "b", "c"},
                        },
       +                site: testSite{l: langs.NewDefaultLanguage(config.New())},
                }
        }
        
   DIR diff --git a/tpl/time/init.go b/tpl/time/init.go
       @@ -28,7 +28,7 @@ func init() {
                        if d.Language == nil {
                                panic("Language must be set")
                        }
       -                ctx := New(langs.GetTranslator(d.Language), langs.GetLocation(d.Language))
       +                ctx := New(langs.GetTimeFormatter(d.Language), langs.GetLocation(d.Language))
        
                        ns := &internal.TemplateFuncsNamespace{
                                Name: name,
   DIR diff --git a/tpl/time/time.go b/tpl/time/time.go
       @@ -21,15 +21,13 @@ import (
        
                "github.com/gohugoio/hugo/common/htime"
        
       -        "github.com/gohugoio/locales"
       -
                "github.com/spf13/cast"
        )
        
        // New returns a new instance of the time-namespaced template functions.
       -func New(translator locales.Translator, location *time.Location) *Namespace {
       +func New(timeFormatter htime.TimeFormatter, location *time.Location) *Namespace {
                return &Namespace{
       -                timeFormatter: htime.NewTimeFormatter(translator),
       +                timeFormatter: timeFormatter,
                        location:      location,
                }
        }
   DIR diff --git a/tpl/time/time_test.go b/tpl/time/time_test.go
       @@ -20,6 +20,7 @@ import (
        
                qt "github.com/frankban/quicktest"
        
       +        "github.com/gohugoio/hugo/common/htime"
                translators "github.com/gohugoio/localescompressed"
        )
        
       @@ -27,7 +28,7 @@ func TestTimeLocation(t *testing.T) {
                t.Parallel()
        
                loc, _ := time.LoadLocation("America/Antigua")
       -        ns := New(translators.GetTranslator("en"), loc)
       +        ns := New(htime.NewTimeFormatter(translators.GetTranslator("en")), loc)
        
                for i, test := range []struct {
                        name     string
       @@ -86,7 +87,7 @@ func TestFormat(t *testing.T) {
        
                c.Run("UTC", func(c *qt.C) {
                        c.Parallel()
       -                ns := New(translators.GetTranslator("en"), time.UTC)
       +                ns := New(htime.NewTimeFormatter(translators.GetTranslator("en")), time.UTC)
        
                        for i, test := range []struct {
                                layout string
       @@ -129,7 +130,7 @@ func TestFormat(t *testing.T) {
        
                        loc, err := time.LoadLocation("America/Los_Angeles")
                        c.Assert(err, qt.IsNil)
       -                ns := New(translators.GetTranslator("en"), loc)
       +                ns := New(htime.NewTimeFormatter(translators.GetTranslator("en")), loc)
        
                        d, err := ns.Format(":time_full", "2020-03-09T11:00:00")
        
       @@ -143,7 +144,7 @@ func TestFormat(t *testing.T) {
        func TestDuration(t *testing.T) {
                t.Parallel()
        
       -        ns := New(translators.GetTranslator("en"), time.UTC)
       +        ns := New(htime.NewTimeFormatter(translators.GetTranslator("en")), time.UTC)
        
                for i, test := range []struct {
                        unit   any