From 941697c4200f183d6e16dbdf332e82549ea94eb1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B8rn=20Erik=20Pedersen?= Date: Fri, 7 Jun 2024 17:38:33 +0200 Subject: [PATCH] Add option to not generate aliases for first page of pagination pages Also consolidate the pagination configuration into a struct. Closes #12572 --- config/allconfig/allconfig.go | 16 ++++ .../allconfig/allconfig_integration_test.go | 82 +++++++++++++++++++ config/allconfig/alldecoders.go | 16 ++++ config/allconfig/configlanguage.go | 8 +- config/allconfig/load.go | 4 +- config/commonConfig.go | 12 +++ config/configProvider.go | 3 +- hugolib/site_render.go | 4 +- resources/page/pagination.go | 4 +- 9 files changed, 135 insertions(+), 14 deletions(-) diff --git a/config/allconfig/allconfig.go b/config/allconfig/allconfig.go index 5ff456d55e5..64288e8878a 100644 --- a/config/allconfig/allconfig.go +++ b/config/allconfig/allconfig.go @@ -179,6 +179,9 @@ type Config struct { // Server configuration. Server config.Server `mapstructure:"-"` + // Pagination configuration. + Pagination config.Pagination `mapstructure:"-"` + // Privacy configuration. Privacy privacy.Config `mapstructure:"-"` @@ -369,6 +372,17 @@ func (c *Config) CompileConfig(logger loggers.Logger) error { return err } + // Legacy paginate values. + if c.Paginate != 0 { + hugo.Deprecate("site config key paginate", "Use paginator.defaultPageSize instead.", "v0.128.0") + c.Pagination.DefaultPageSize = c.Paginate + } + + if c.PaginatePath != "" { + hugo.Deprecate("site config key paginatePath", "Use paginator.path instead.", "v0.128.0") + c.Pagination.Path = c.PaginatePath + } + c.C = &ConfigCompiled{ Timeout: timeout, BaseURL: baseURL, @@ -557,9 +571,11 @@ type RootConfig struct { HasCJKLanguage bool // The default number of pages per page when paginating. + // Deprecated: Use the Pagination struct. Paginate int // The path to use when creating pagination URLs, e.g. "page" in /page/2/. + // Deprecated: Use the Pagination struct. PaginatePath string // Whether to pluralize default list titles. diff --git a/config/allconfig/allconfig_integration_test.go b/config/allconfig/allconfig_integration_test.go index af4655fe81c..a71a28ed758 100644 --- a/config/allconfig/allconfig_integration_test.go +++ b/config/allconfig/allconfig_integration_test.go @@ -102,3 +102,85 @@ suffixes = ["html", "xhtml"] b.Assert(contentTypes.HTML.Suffixes(), qt.DeepEquals, []string{"html", "xhtml"}) b.Assert(contentTypes.Markdown.Suffixes(), qt.DeepEquals, []string{"md", "mdown", "markdown"}) } + +func TestPaginationConfigOld(t *testing.T) { + files := ` +-- hugo.toml -- + [languages.en] + weight = 1 + paginatePath = "page-en" + + [languages.de] + weight = 2 + paginatePath = "page-de" + paginate = 20 +` + + b := hugolib.Test(t, files) + + confEn := b.H.Sites[0].Conf.Pagination() + confDe := b.H.Sites[1].Conf.Pagination() + + b.Assert(confEn.Path, qt.Equals, "page-en") + b.Assert(confEn.DefaultPageSize, qt.Equals, 10) + b.Assert(confDe.Path, qt.Equals, "page-de") + b.Assert(confDe.DefaultPageSize, qt.Equals, 20) +} + +func TestPaginationConfigNew(t *testing.T) { + files := ` +-- hugo.toml -- + [languages.en] + weight = 1 + [languages.en.pagination] + defaultPageSize = 20 + [languages.de] + weight = 2 + [languages.de.pagination] + path = "page-de" + +` + + b := hugolib.Test(t, files) + + confEn := b.H.Sites[0].Conf.Pagination() + confDe := b.H.Sites[1].Conf.Pagination() + + b.Assert(confEn.Path, qt.Equals, "page") + b.Assert(confEn.DefaultPageSize, qt.Equals, 20) + b.Assert(confDe.Path, qt.Equals, "page-de") + b.Assert(confDe.DefaultPageSize, qt.Equals, 10) +} + +func TestPaginationConfigDisableAliases(t *testing.T) { + files := ` +-- hugo.toml -- +disableKinds = ["taxonomy", "term"] +[pagination] +disableAliases = true +defaultPageSize = 2 +-- layouts/_default/list.html -- +{{ $paginator := .Paginate site.RegularPages }} +{{ template "_internal/pagination.html" . }} +{{ range $paginator.Pages }} + {{ .Title }} +{{ end }} +-- content/p1.md -- +--- +title: "p1" +--- +-- content/p2.md -- +--- +title: "p2" +--- +-- content/p3.md -- +--- +title: "p3" +--- +` + + b := hugolib.Test(t, files) + + b.AssertFileExists("public/page/1/index.html", false) + b.AssertFileContent("public/page/2/index.html", "pagination-default") +} diff --git a/config/allconfig/alldecoders.go b/config/allconfig/alldecoders.go index fc033821eea..46dd59bbc20 100644 --- a/config/allconfig/alldecoders.go +++ b/config/allconfig/alldecoders.go @@ -327,6 +327,22 @@ var allDecoderSetups = map[string]decodeWeight{ return err }, }, + "pagination": { + key: "pagination", + decode: func(d decodeWeight, p decodeConfig) error { + p.c.Pagination = config.Pagination{ + DefaultPageSize: 10, + Path: "page", + } + if p.p.IsSet(d.key) { + if err := mapstructure.WeakDecode(p.p.Get(d.key), &p.c.Pagination); err != nil { + return err + } + } + + return nil + }, + }, "privacy": { key: "privacy", decode: func(d decodeWeight, p decodeConfig) error { diff --git a/config/allconfig/configlanguage.go b/config/allconfig/configlanguage.go index 1d2cb5ce36a..38d2309efa6 100644 --- a/config/allconfig/configlanguage.go +++ b/config/allconfig/configlanguage.go @@ -248,12 +248,8 @@ func (c ConfigLanguage) CreateTitle(s string) string { return c.config.C.CreateTitle(s) } -func (c ConfigLanguage) Paginate() int { - return c.config.Paginate -} - -func (c ConfigLanguage) PaginatePath() string { - return c.config.PaginatePath +func (c ConfigLanguage) Pagination() config.Pagination { + return c.config.Pagination } func (c ConfigLanguage) StaticDirs() []string { diff --git a/config/allconfig/load.go b/config/allconfig/load.go index b24655ebcfd..edf8295bf9f 100644 --- a/config/allconfig/load.go +++ b/config/allconfig/load.go @@ -194,8 +194,8 @@ func (l configLoader) applyDefaultConfig() error { "footnoteAnchorPrefix": "", "footnoteReturnLinkContents": "", "newContentEditor": "", - "paginate": 10, - "paginatePath": "page", + "paginate": 0, // Moved into the paginator struct in Hugo v0.128.0. + "paginatePath": "", // Moved into the paginator struct in Hugo v0.128.0. "summaryLength": 70, "rssLimit": -1, "sectionPagesMenu": "", diff --git a/config/commonConfig.go b/config/commonConfig.go index 1e43b165374..40650c5755e 100644 --- a/config/commonConfig.go +++ b/config/commonConfig.go @@ -410,3 +410,15 @@ func DecodeServer(cfg Provider) (Server, error) { return *s, nil } + +// Pagination configures the pagination behavior. +type Pagination struct { + // Default number of elements per page in pagination. + DefaultPageSize int + + // The path element used during pagination. + Path string + + // WHether to disable generation of alias for the first pagination page. + DisableAliases bool +} diff --git a/config/configProvider.go b/config/configProvider.go index ba10d44dd84..ee6691cf1d8 100644 --- a/config/configProvider.go +++ b/config/configProvider.go @@ -52,8 +52,7 @@ type AllProvider interface { DefaultContentLanguageInSubdir() bool IsLangDisabled(string) bool SummaryLength() int - Paginate() int - PaginatePath() string + Pagination() Pagination BuildExpired() bool BuildFuture() bool BuildDrafts() bool diff --git a/hugolib/site_render.go b/hugolib/site_render.go index 1cd509fea96..a7ecf89af2b 100644 --- a/hugolib/site_render.go +++ b/hugolib/site_render.go @@ -223,7 +223,7 @@ func (s *Site) logMissingLayout(name, layout, kind, outputFormat string) { // renderPaginator must be run after the owning Page has been rendered. func (s *Site) renderPaginator(p *pageState, templ tpl.Template) error { - paginatePath := s.conf.PaginatePath + paginatePath := s.Conf.Pagination().Path d := p.targetPathDescriptor f := p.s.rc.Format @@ -233,7 +233,7 @@ func (s *Site) renderPaginator(p *pageState, templ tpl.Template) error { panic(fmt.Sprintf("invalid paginator state for %q", p.pathOrTitle())) } - if f.IsHTML { + if f.IsHTML && !s.Conf.Pagination().DisableAliases { // Write alias for page 1 d.Addends = fmt.Sprintf("/%s/%d", paginatePath, 1) targetPaths := page.CreateTargetPaths(d) diff --git a/resources/page/pagination.go b/resources/page/pagination.go index 4beb96e5094..d24879e6289 100644 --- a/resources/page/pagination.go +++ b/resources/page/pagination.go @@ -263,7 +263,7 @@ func splitPageGroups(pageGroups PagesGroup, size int) []paginatedElement { func ResolvePagerSize(conf config.AllProvider, options ...any) (int, error) { if len(options) == 0 { - return conf.Paginate(), nil + return conf.Pagination().DefaultPageSize, nil } if len(options) > 1 { @@ -400,7 +400,7 @@ func newPaginationURLFactory(d TargetPathDescriptor) paginationURLFactory { pathDescriptor := d var rel string if pageNumber > 1 { - rel = fmt.Sprintf("/%s/%d/", d.PathSpec.Cfg.PaginatePath(), pageNumber) + rel = fmt.Sprintf("/%s/%d/", d.PathSpec.Cfg.Pagination().Path, pageNumber) pathDescriptor.Addends = rel }