mirror of
https://github.com/gohugoio/hugo.git
synced 2025-08-29 22:29:56 +02:00
Create a struct with all of Hugo's config options
Primary motivation is documentation, but it will also hopefully simplify the code. Also, * Lower case the default output format names; this is in line with the custom ones (map keys) and how it's treated all the places. This avoids doing `stringds.EqualFold` everywhere. Closes #10896 Closes #10620
This commit is contained in:
@@ -166,7 +166,7 @@ type OutputFormatsProvider interface {
|
||||
OutputFormats() OutputFormats
|
||||
}
|
||||
|
||||
// Page is the core interface in Hugo.
|
||||
// Page is the core interface in Hugo and what you get as the top level data context in your templates.
|
||||
type Page interface {
|
||||
ContentProvider
|
||||
TableOfContentsProvider
|
||||
@@ -249,7 +249,7 @@ type PageMetaProvider interface {
|
||||
|
||||
// Sitemap returns the sitemap configuration for this page.
|
||||
// This is for internal use only.
|
||||
Sitemap() config.Sitemap
|
||||
Sitemap() config.SitemapConfig
|
||||
|
||||
// Type is a discriminator used to select layouts etc. It is typically set
|
||||
// in front matter, but will fall back to the root section.
|
||||
|
@@ -111,7 +111,7 @@ func MarshalPageToJSON(p Page) ([]byte, error) {
|
||||
Section string
|
||||
SectionsEntries []string
|
||||
SectionsPath string
|
||||
Sitemap config.Sitemap
|
||||
Sitemap config.SitemapConfig
|
||||
Type string
|
||||
Weight int
|
||||
Language *langs.Language
|
||||
|
@@ -19,6 +19,7 @@ import (
|
||||
"strings"
|
||||
|
||||
"github.com/gohugoio/hugo/common/maps"
|
||||
"github.com/gohugoio/hugo/config"
|
||||
"github.com/gohugoio/hugo/hugofs/glob"
|
||||
"github.com/mitchellh/mapstructure"
|
||||
)
|
||||
@@ -80,43 +81,90 @@ func (m PageMatcher) Matches(p Page) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
// DecodeCascade decodes in which could be either a map or a slice of maps.
|
||||
func DecodeCascade(in any) (map[PageMatcher]maps.Params, error) {
|
||||
m, err := maps.ToSliceStringMap(in)
|
||||
if err != nil {
|
||||
return map[PageMatcher]maps.Params{
|
||||
{}: maps.ToStringMap(in),
|
||||
}, nil
|
||||
}
|
||||
func DecodeCascadeConfig(in any) (*config.ConfigNamespace[[]PageMatcherParamsConfig, map[PageMatcher]maps.Params], error) {
|
||||
buildConfig := func(in any) (map[PageMatcher]maps.Params, any, error) {
|
||||
cascade := make(map[PageMatcher]maps.Params)
|
||||
if in == nil {
|
||||
return cascade, []map[string]any{}, nil
|
||||
}
|
||||
ms, err := maps.ToSliceStringMap(in)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
cascade := make(map[PageMatcher]maps.Params)
|
||||
var cfgs []PageMatcherParamsConfig
|
||||
|
||||
for _, vv := range m {
|
||||
var m PageMatcher
|
||||
if mv, found := vv["_target"]; found {
|
||||
err := DecodePageMatcher(mv, &m)
|
||||
for _, m := range ms {
|
||||
m = maps.CleanConfigStringMap(m)
|
||||
c, err := mapToPageMatcherParamsConfig(m)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, nil, err
|
||||
}
|
||||
cfgs = append(cfgs, c)
|
||||
}
|
||||
c, found := cascade[m]
|
||||
if found {
|
||||
// Merge
|
||||
for k, v := range vv {
|
||||
if _, found := c[k]; !found {
|
||||
c[k] = v
|
||||
|
||||
for _, cfg := range cfgs {
|
||||
m := cfg.Target
|
||||
c, found := cascade[m]
|
||||
if found {
|
||||
// Merge
|
||||
for k, v := range cfg.Params {
|
||||
if _, found := c[k]; !found {
|
||||
c[k] = v
|
||||
}
|
||||
}
|
||||
} else {
|
||||
cascade[m] = cfg.Params
|
||||
}
|
||||
} else {
|
||||
cascade[m] = vv
|
||||
}
|
||||
|
||||
return cascade, cfgs, nil
|
||||
}
|
||||
|
||||
return cascade, nil
|
||||
return config.DecodeNamespace[[]PageMatcherParamsConfig](in, buildConfig)
|
||||
|
||||
}
|
||||
|
||||
// DecodePageMatcher decodes m into v.
|
||||
func DecodePageMatcher(m any, v *PageMatcher) error {
|
||||
// DecodeCascade decodes in which could be either a map or a slice of maps.
|
||||
func DecodeCascade(in any) (map[PageMatcher]maps.Params, error) {
|
||||
conf, err := DecodeCascadeConfig(in)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return conf.Config, nil
|
||||
}
|
||||
|
||||
func mapToPageMatcherParamsConfig(m map[string]any) (PageMatcherParamsConfig, error) {
|
||||
var pcfg PageMatcherParamsConfig
|
||||
for k, v := range m {
|
||||
switch strings.ToLower(k) {
|
||||
case "params":
|
||||
// We simplified the structure of the cascade config in Hugo 0.111.0.
|
||||
// There is a small chance that someone has used the old structure with the params keyword,
|
||||
// those values will now be moved to the top level.
|
||||
// This should be very unlikely as it would lead to constructs like .Params.params.foo,
|
||||
// and most people see params as an Hugo internal keyword.
|
||||
pcfg.Params = maps.ToStringMap(v)
|
||||
case "_target", "target":
|
||||
var target PageMatcher
|
||||
if err := decodePageMatcher(v, &target); err != nil {
|
||||
return pcfg, err
|
||||
}
|
||||
pcfg.Target = target
|
||||
default:
|
||||
// Legacy config.
|
||||
if pcfg.Params == nil {
|
||||
pcfg.Params = make(maps.Params)
|
||||
}
|
||||
pcfg.Params[k] = v
|
||||
}
|
||||
}
|
||||
return pcfg, pcfg.init()
|
||||
|
||||
}
|
||||
|
||||
// decodePageMatcher decodes m into v.
|
||||
func decodePageMatcher(m any, v *PageMatcher) error {
|
||||
if err := mapstructure.WeakDecode(m, v); err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -140,3 +188,14 @@ func DecodePageMatcher(m any, v *PageMatcher) error {
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
type PageMatcherParamsConfig struct {
|
||||
// Apply Params to all Pages matching Target.
|
||||
Params maps.Params
|
||||
Target PageMatcher
|
||||
}
|
||||
|
||||
func (p *PageMatcherParamsConfig) init() error {
|
||||
maps.PrepareParams(p.Params)
|
||||
return nil
|
||||
}
|
||||
|
@@ -18,6 +18,7 @@ import (
|
||||
"testing"
|
||||
|
||||
"github.com/gohugoio/hugo/common/hugo"
|
||||
"github.com/gohugoio/hugo/common/maps"
|
||||
|
||||
qt "github.com/frankban/quicktest"
|
||||
)
|
||||
@@ -71,13 +72,87 @@ func TestPageMatcher(t *testing.T) {
|
||||
|
||||
c.Run("Decode", func(c *qt.C) {
|
||||
var v PageMatcher
|
||||
c.Assert(DecodePageMatcher(map[string]any{"kind": "foo"}, &v), qt.Not(qt.IsNil))
|
||||
c.Assert(DecodePageMatcher(map[string]any{"kind": "{foo,bar}"}, &v), qt.Not(qt.IsNil))
|
||||
c.Assert(DecodePageMatcher(map[string]any{"kind": "taxonomy"}, &v), qt.IsNil)
|
||||
c.Assert(DecodePageMatcher(map[string]any{"kind": "{taxonomy,foo}"}, &v), qt.IsNil)
|
||||
c.Assert(DecodePageMatcher(map[string]any{"kind": "{taxonomy,term}"}, &v), qt.IsNil)
|
||||
c.Assert(DecodePageMatcher(map[string]any{"kind": "*"}, &v), qt.IsNil)
|
||||
c.Assert(DecodePageMatcher(map[string]any{"kind": "home", "path": filepath.FromSlash("/a/b/**")}, &v), qt.IsNil)
|
||||
c.Assert(decodePageMatcher(map[string]any{"kind": "foo"}, &v), qt.Not(qt.IsNil))
|
||||
c.Assert(decodePageMatcher(map[string]any{"kind": "{foo,bar}"}, &v), qt.Not(qt.IsNil))
|
||||
c.Assert(decodePageMatcher(map[string]any{"kind": "taxonomy"}, &v), qt.IsNil)
|
||||
c.Assert(decodePageMatcher(map[string]any{"kind": "{taxonomy,foo}"}, &v), qt.IsNil)
|
||||
c.Assert(decodePageMatcher(map[string]any{"kind": "{taxonomy,term}"}, &v), qt.IsNil)
|
||||
c.Assert(decodePageMatcher(map[string]any{"kind": "*"}, &v), qt.IsNil)
|
||||
c.Assert(decodePageMatcher(map[string]any{"kind": "home", "path": filepath.FromSlash("/a/b/**")}, &v), qt.IsNil)
|
||||
c.Assert(v, qt.Equals, PageMatcher{Kind: "home", Path: "/a/b/**"})
|
||||
})
|
||||
|
||||
c.Run("mapToPageMatcherParamsConfig", func(c *qt.C) {
|
||||
fn := func(m map[string]any) PageMatcherParamsConfig {
|
||||
v, err := mapToPageMatcherParamsConfig(m)
|
||||
c.Assert(err, qt.IsNil)
|
||||
return v
|
||||
}
|
||||
// Legacy.
|
||||
c.Assert(fn(map[string]any{"_target": map[string]any{"kind": "page"}, "foo": "bar"}), qt.DeepEquals, PageMatcherParamsConfig{
|
||||
Params: maps.Params{
|
||||
"foo": "bar",
|
||||
},
|
||||
Target: PageMatcher{Path: "", Kind: "page", Lang: "", Environment: ""},
|
||||
})
|
||||
|
||||
// Current format.
|
||||
c.Assert(fn(map[string]any{"target": map[string]any{"kind": "page"}, "params": map[string]any{"foo": "bar"}}), qt.DeepEquals, PageMatcherParamsConfig{
|
||||
Params: maps.Params{
|
||||
"foo": "bar",
|
||||
},
|
||||
Target: PageMatcher{Path: "", Kind: "page", Lang: "", Environment: ""},
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
func TestDecodeCascadeConfig(t *testing.T) {
|
||||
c := qt.New(t)
|
||||
|
||||
in := []map[string]any{
|
||||
{
|
||||
"params": map[string]any{
|
||||
"a": "av",
|
||||
},
|
||||
"target": map[string]any{
|
||||
"kind": "page",
|
||||
"Environment": "production",
|
||||
},
|
||||
},
|
||||
{
|
||||
"params": map[string]any{
|
||||
"b": "bv",
|
||||
},
|
||||
"target": map[string]any{
|
||||
"kind": "page",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
got, err := DecodeCascadeConfig(in)
|
||||
|
||||
c.Assert(err, qt.IsNil)
|
||||
c.Assert(got, qt.IsNotNil)
|
||||
c.Assert(got.Config, qt.DeepEquals,
|
||||
map[PageMatcher]maps.Params{
|
||||
{Path: "", Kind: "page", Lang: "", Environment: ""}: {
|
||||
"b": "bv",
|
||||
},
|
||||
{Path: "", Kind: "page", Lang: "", Environment: "production"}: {
|
||||
"a": "av",
|
||||
},
|
||||
},
|
||||
)
|
||||
c.Assert(got.SourceStructure, qt.DeepEquals, []PageMatcherParamsConfig{
|
||||
{
|
||||
Params: maps.Params{"a": string("av")},
|
||||
Target: PageMatcher{Kind: "page", Environment: "production"},
|
||||
},
|
||||
{Params: maps.Params{"b": string("bv")}, Target: PageMatcher{Kind: "page"}},
|
||||
})
|
||||
|
||||
got, err = DecodeCascadeConfig(nil)
|
||||
c.Assert(err, qt.IsNil)
|
||||
c.Assert(got, qt.IsNotNil)
|
||||
|
||||
}
|
||||
|
@@ -67,8 +67,8 @@ func (p *nopPage) Aliases() []string {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (p *nopPage) Sitemap() config.Sitemap {
|
||||
return config.Sitemap{}
|
||||
func (p *nopPage) Sitemap() config.SitemapConfig {
|
||||
return config.SitemapConfig{}
|
||||
}
|
||||
|
||||
func (p *nopPage) Layout() string {
|
||||
@@ -217,7 +217,7 @@ func (p *nopPage) HasShortcode(name string) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (p *nopPage) Hugo() (h hugo.Info) {
|
||||
func (p *nopPage) Hugo() (h hugo.HugoInfo) {
|
||||
return
|
||||
}
|
||||
|
||||
|
@@ -18,6 +18,7 @@ import (
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"github.com/gohugoio/hugo/common/urls"
|
||||
"github.com/gohugoio/hugo/helpers"
|
||||
"github.com/gohugoio/hugo/output"
|
||||
)
|
||||
@@ -91,18 +92,18 @@ func (p TargetPaths) RelPermalink(s *helpers.PathSpec) string {
|
||||
}
|
||||
|
||||
func (p TargetPaths) PermalinkForOutputFormat(s *helpers.PathSpec, f output.Format) string {
|
||||
var baseURL string
|
||||
var baseURL urls.BaseURL
|
||||
var err error
|
||||
if f.Protocol != "" {
|
||||
baseURL, err = s.BaseURL.WithProtocol(f.Protocol)
|
||||
baseURL, err = s.Cfg.BaseURL().WithProtocol(f.Protocol)
|
||||
if err != nil {
|
||||
return ""
|
||||
}
|
||||
} else {
|
||||
baseURL = s.BaseURL.String()
|
||||
baseURL = s.Cfg.BaseURL()
|
||||
}
|
||||
|
||||
return s.PermalinkForBaseURL(p.Link, baseURL)
|
||||
baseURLstr := baseURL.String()
|
||||
return s.PermalinkForBaseURL(p.Link, baseURLstr)
|
||||
}
|
||||
|
||||
func isHtmlIndex(s string) bool {
|
||||
|
@@ -11,7 +11,7 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package page
|
||||
package page_test
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
@@ -20,6 +20,7 @@ import (
|
||||
"testing"
|
||||
|
||||
"github.com/gohugoio/hugo/media"
|
||||
"github.com/gohugoio/hugo/resources/page"
|
||||
|
||||
"github.com/gohugoio/hugo/output"
|
||||
)
|
||||
@@ -27,7 +28,7 @@ import (
|
||||
func TestPageTargetPath(t *testing.T) {
|
||||
pathSpec := newTestPathSpec()
|
||||
|
||||
noExtNoDelimMediaType := media.WithDelimiterAndSuffixes(media.TextType, "", "")
|
||||
noExtNoDelimMediaType := media.WithDelimiterAndSuffixes(media.Builtin.TextType, "", "")
|
||||
noExtNoDelimMediaType.Delimiter = ""
|
||||
|
||||
// Netlify style _redirects
|
||||
@@ -43,152 +44,152 @@ func TestPageTargetPath(t *testing.T) {
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
d TargetPathDescriptor
|
||||
expected TargetPaths
|
||||
d page.TargetPathDescriptor
|
||||
expected page.TargetPaths
|
||||
}{
|
||||
{"JSON home", TargetPathDescriptor{Kind: KindHome, Type: output.JSONFormat}, TargetPaths{TargetFilename: "/index.json", SubResourceBaseTarget: "", Link: "/index.json"}},
|
||||
{"AMP home", TargetPathDescriptor{Kind: KindHome, Type: output.AMPFormat}, TargetPaths{TargetFilename: "/amp/index.html", SubResourceBaseTarget: "/amp", Link: "/amp/"}},
|
||||
{"HTML home", TargetPathDescriptor{Kind: KindHome, BaseName: "_index", Type: output.HTMLFormat}, TargetPaths{TargetFilename: "/index.html", SubResourceBaseTarget: "", Link: "/"}},
|
||||
{"Netlify redirects", TargetPathDescriptor{Kind: KindHome, BaseName: "_index", Type: noExtDelimFormat}, TargetPaths{TargetFilename: "/_redirects", SubResourceBaseTarget: "", Link: "/_redirects"}},
|
||||
{"HTML section list", TargetPathDescriptor{
|
||||
Kind: KindSection,
|
||||
{"JSON home", page.TargetPathDescriptor{Kind: page.KindHome, Type: output.JSONFormat}, page.TargetPaths{TargetFilename: "/index.json", SubResourceBaseTarget: "", Link: "/index.json"}},
|
||||
{"AMP home", page.TargetPathDescriptor{Kind: page.KindHome, Type: output.AMPFormat}, page.TargetPaths{TargetFilename: "/amp/index.html", SubResourceBaseTarget: "/amp", Link: "/amp/"}},
|
||||
{"HTML home", page.TargetPathDescriptor{Kind: page.KindHome, BaseName: "_index", Type: output.HTMLFormat}, page.TargetPaths{TargetFilename: "/index.html", SubResourceBaseTarget: "", Link: "/"}},
|
||||
{"Netlify redirects", page.TargetPathDescriptor{Kind: page.KindHome, BaseName: "_index", Type: noExtDelimFormat}, page.TargetPaths{TargetFilename: "/_redirects", SubResourceBaseTarget: "", Link: "/_redirects"}},
|
||||
{"HTML section list", page.TargetPathDescriptor{
|
||||
Kind: page.KindSection,
|
||||
Sections: []string{"sect1"},
|
||||
BaseName: "_index",
|
||||
Type: output.HTMLFormat,
|
||||
}, TargetPaths{TargetFilename: "/sect1/index.html", SubResourceBaseTarget: "/sect1", Link: "/sect1/"}},
|
||||
{"HTML taxonomy term", TargetPathDescriptor{
|
||||
Kind: KindTerm,
|
||||
}, page.TargetPaths{TargetFilename: "/sect1/index.html", SubResourceBaseTarget: "/sect1", Link: "/sect1/"}},
|
||||
{"HTML taxonomy term", page.TargetPathDescriptor{
|
||||
Kind: page.KindTerm,
|
||||
Sections: []string{"tags", "hugo"},
|
||||
BaseName: "_index",
|
||||
Type: output.HTMLFormat,
|
||||
}, TargetPaths{TargetFilename: "/tags/hugo/index.html", SubResourceBaseTarget: "/tags/hugo", Link: "/tags/hugo/"}},
|
||||
{"HTML taxonomy", TargetPathDescriptor{
|
||||
Kind: KindTaxonomy,
|
||||
}, page.TargetPaths{TargetFilename: "/tags/hugo/index.html", SubResourceBaseTarget: "/tags/hugo", Link: "/tags/hugo/"}},
|
||||
{"HTML taxonomy", page.TargetPathDescriptor{
|
||||
Kind: page.KindTaxonomy,
|
||||
Sections: []string{"tags"},
|
||||
BaseName: "_index",
|
||||
Type: output.HTMLFormat,
|
||||
}, TargetPaths{TargetFilename: "/tags/index.html", SubResourceBaseTarget: "/tags", Link: "/tags/"}},
|
||||
}, page.TargetPaths{TargetFilename: "/tags/index.html", SubResourceBaseTarget: "/tags", Link: "/tags/"}},
|
||||
{
|
||||
"HTML page", TargetPathDescriptor{
|
||||
Kind: KindPage,
|
||||
"HTML page", page.TargetPathDescriptor{
|
||||
Kind: page.KindPage,
|
||||
Dir: "/a/b",
|
||||
BaseName: "mypage",
|
||||
Sections: []string{"a"},
|
||||
Type: output.HTMLFormat,
|
||||
}, TargetPaths{TargetFilename: "/a/b/mypage/index.html", SubResourceBaseTarget: "/a/b/mypage", Link: "/a/b/mypage/"},
|
||||
}, page.TargetPaths{TargetFilename: "/a/b/mypage/index.html", SubResourceBaseTarget: "/a/b/mypage", Link: "/a/b/mypage/"},
|
||||
},
|
||||
|
||||
{
|
||||
"HTML page with index as base", TargetPathDescriptor{
|
||||
Kind: KindPage,
|
||||
"HTML page with index as base", page.TargetPathDescriptor{
|
||||
Kind: page.KindPage,
|
||||
Dir: "/a/b",
|
||||
BaseName: "index",
|
||||
Sections: []string{"a"},
|
||||
Type: output.HTMLFormat,
|
||||
}, TargetPaths{TargetFilename: "/a/b/index.html", SubResourceBaseTarget: "/a/b", Link: "/a/b/"},
|
||||
}, page.TargetPaths{TargetFilename: "/a/b/index.html", SubResourceBaseTarget: "/a/b", Link: "/a/b/"},
|
||||
},
|
||||
|
||||
{
|
||||
"HTML page with special chars", TargetPathDescriptor{
|
||||
Kind: KindPage,
|
||||
"HTML page with special chars", page.TargetPathDescriptor{
|
||||
Kind: page.KindPage,
|
||||
Dir: "/a/b",
|
||||
BaseName: "My Page!",
|
||||
Type: output.HTMLFormat,
|
||||
}, TargetPaths{TargetFilename: "/a/b/my-page/index.html", SubResourceBaseTarget: "/a/b/my-page", Link: "/a/b/my-page/"},
|
||||
}, page.TargetPaths{TargetFilename: "/a/b/my-page/index.html", SubResourceBaseTarget: "/a/b/my-page", Link: "/a/b/my-page/"},
|
||||
},
|
||||
{"RSS home", TargetPathDescriptor{Kind: "rss", Type: output.RSSFormat}, TargetPaths{TargetFilename: "/index.xml", SubResourceBaseTarget: "", Link: "/index.xml"}},
|
||||
{"RSS section list", TargetPathDescriptor{
|
||||
{"RSS home", page.TargetPathDescriptor{Kind: "rss", Type: output.RSSFormat}, page.TargetPaths{TargetFilename: "/index.xml", SubResourceBaseTarget: "", Link: "/index.xml"}},
|
||||
{"RSS section list", page.TargetPathDescriptor{
|
||||
Kind: "rss",
|
||||
Sections: []string{"sect1"},
|
||||
Type: output.RSSFormat,
|
||||
}, TargetPaths{TargetFilename: "/sect1/index.xml", SubResourceBaseTarget: "/sect1", Link: "/sect1/index.xml"}},
|
||||
}, page.TargetPaths{TargetFilename: "/sect1/index.xml", SubResourceBaseTarget: "/sect1", Link: "/sect1/index.xml"}},
|
||||
{
|
||||
"AMP page", TargetPathDescriptor{
|
||||
Kind: KindPage,
|
||||
"AMP page", page.TargetPathDescriptor{
|
||||
Kind: page.KindPage,
|
||||
Dir: "/a/b/c",
|
||||
BaseName: "myamp",
|
||||
Type: output.AMPFormat,
|
||||
}, TargetPaths{TargetFilename: "/amp/a/b/c/myamp/index.html", SubResourceBaseTarget: "/amp/a/b/c/myamp", Link: "/amp/a/b/c/myamp/"},
|
||||
}, page.TargetPaths{TargetFilename: "/amp/a/b/c/myamp/index.html", SubResourceBaseTarget: "/amp/a/b/c/myamp", Link: "/amp/a/b/c/myamp/"},
|
||||
},
|
||||
{
|
||||
"AMP page with URL with suffix", TargetPathDescriptor{
|
||||
Kind: KindPage,
|
||||
"AMP page with URL with suffix", page.TargetPathDescriptor{
|
||||
Kind: page.KindPage,
|
||||
Dir: "/sect/",
|
||||
BaseName: "mypage",
|
||||
URL: "/some/other/url.xhtml",
|
||||
Type: output.HTMLFormat,
|
||||
}, TargetPaths{TargetFilename: "/some/other/url.xhtml", SubResourceBaseTarget: "/some/other", Link: "/some/other/url.xhtml"},
|
||||
}, page.TargetPaths{TargetFilename: "/some/other/url.xhtml", SubResourceBaseTarget: "/some/other", Link: "/some/other/url.xhtml"},
|
||||
},
|
||||
{
|
||||
"JSON page with URL without suffix", TargetPathDescriptor{
|
||||
Kind: KindPage,
|
||||
"JSON page with URL without suffix", page.TargetPathDescriptor{
|
||||
Kind: page.KindPage,
|
||||
Dir: "/sect/",
|
||||
BaseName: "mypage",
|
||||
URL: "/some/other/path/",
|
||||
Type: output.JSONFormat,
|
||||
}, TargetPaths{TargetFilename: "/some/other/path/index.json", SubResourceBaseTarget: "/some/other/path", Link: "/some/other/path/index.json"},
|
||||
}, page.TargetPaths{TargetFilename: "/some/other/path/index.json", SubResourceBaseTarget: "/some/other/path", Link: "/some/other/path/index.json"},
|
||||
},
|
||||
{
|
||||
"JSON page with URL without suffix and no trailing slash", TargetPathDescriptor{
|
||||
Kind: KindPage,
|
||||
"JSON page with URL without suffix and no trailing slash", page.TargetPathDescriptor{
|
||||
Kind: page.KindPage,
|
||||
Dir: "/sect/",
|
||||
BaseName: "mypage",
|
||||
URL: "/some/other/path",
|
||||
Type: output.JSONFormat,
|
||||
}, TargetPaths{TargetFilename: "/some/other/path/index.json", SubResourceBaseTarget: "/some/other/path", Link: "/some/other/path/index.json"},
|
||||
}, page.TargetPaths{TargetFilename: "/some/other/path/index.json", SubResourceBaseTarget: "/some/other/path", Link: "/some/other/path/index.json"},
|
||||
},
|
||||
{
|
||||
"HTML page with URL without suffix and no trailing slash", TargetPathDescriptor{
|
||||
Kind: KindPage,
|
||||
"HTML page with URL without suffix and no trailing slash", page.TargetPathDescriptor{
|
||||
Kind: page.KindPage,
|
||||
Dir: "/sect/",
|
||||
BaseName: "mypage",
|
||||
URL: "/some/other/path",
|
||||
Type: output.HTMLFormat,
|
||||
}, TargetPaths{TargetFilename: "/some/other/path/index.html", SubResourceBaseTarget: "/some/other/path", Link: "/some/other/path/"},
|
||||
}, page.TargetPaths{TargetFilename: "/some/other/path/index.html", SubResourceBaseTarget: "/some/other/path", Link: "/some/other/path/"},
|
||||
},
|
||||
{
|
||||
"HTML page with URL containing double hyphen", TargetPathDescriptor{
|
||||
Kind: KindPage,
|
||||
"HTML page with URL containing double hyphen", page.TargetPathDescriptor{
|
||||
Kind: page.KindPage,
|
||||
Dir: "/sect/",
|
||||
BaseName: "mypage",
|
||||
URL: "/some/other--url/",
|
||||
Type: output.HTMLFormat,
|
||||
}, TargetPaths{TargetFilename: "/some/other--url/index.html", SubResourceBaseTarget: "/some/other--url", Link: "/some/other--url/"},
|
||||
}, page.TargetPaths{TargetFilename: "/some/other--url/index.html", SubResourceBaseTarget: "/some/other--url", Link: "/some/other--url/"},
|
||||
},
|
||||
{
|
||||
"HTML page with expanded permalink", TargetPathDescriptor{
|
||||
Kind: KindPage,
|
||||
"HTML page with expanded permalink", page.TargetPathDescriptor{
|
||||
Kind: page.KindPage,
|
||||
Dir: "/a/b",
|
||||
BaseName: "mypage",
|
||||
ExpandedPermalink: "/2017/10/my-title/",
|
||||
Type: output.HTMLFormat,
|
||||
}, TargetPaths{TargetFilename: "/2017/10/my-title/index.html", SubResourceBaseTarget: "/2017/10/my-title", Link: "/2017/10/my-title/"},
|
||||
}, page.TargetPaths{TargetFilename: "/2017/10/my-title/index.html", SubResourceBaseTarget: "/2017/10/my-title", Link: "/2017/10/my-title/"},
|
||||
},
|
||||
{
|
||||
"Paginated HTML home", TargetPathDescriptor{
|
||||
Kind: KindHome,
|
||||
"Paginated HTML home", page.TargetPathDescriptor{
|
||||
Kind: page.KindHome,
|
||||
BaseName: "_index",
|
||||
Type: output.HTMLFormat,
|
||||
Addends: "page/3",
|
||||
}, TargetPaths{TargetFilename: "/page/3/index.html", SubResourceBaseTarget: "/page/3", Link: "/page/3/"},
|
||||
}, page.TargetPaths{TargetFilename: "/page/3/index.html", SubResourceBaseTarget: "/page/3", Link: "/page/3/"},
|
||||
},
|
||||
{
|
||||
"Paginated Taxonomy terms list", TargetPathDescriptor{
|
||||
Kind: KindTerm,
|
||||
"Paginated Taxonomy terms list", page.TargetPathDescriptor{
|
||||
Kind: page.KindTerm,
|
||||
BaseName: "_index",
|
||||
Sections: []string{"tags", "hugo"},
|
||||
Type: output.HTMLFormat,
|
||||
Addends: "page/3",
|
||||
}, TargetPaths{TargetFilename: "/tags/hugo/page/3/index.html", SubResourceBaseTarget: "/tags/hugo/page/3", Link: "/tags/hugo/page/3/"},
|
||||
}, page.TargetPaths{TargetFilename: "/tags/hugo/page/3/index.html", SubResourceBaseTarget: "/tags/hugo/page/3", Link: "/tags/hugo/page/3/"},
|
||||
},
|
||||
{
|
||||
"Regular page with addend", TargetPathDescriptor{
|
||||
Kind: KindPage,
|
||||
"Regular page with addend", page.TargetPathDescriptor{
|
||||
Kind: page.KindPage,
|
||||
Dir: "/a/b",
|
||||
BaseName: "mypage",
|
||||
Addends: "c/d/e",
|
||||
Type: output.HTMLFormat,
|
||||
}, TargetPaths{TargetFilename: "/a/b/mypage/c/d/e/index.html", SubResourceBaseTarget: "/a/b/mypage/c/d/e", Link: "/a/b/mypage/c/d/e/"},
|
||||
}, page.TargetPaths{TargetFilename: "/a/b/mypage/c/d/e/index.html", SubResourceBaseTarget: "/a/b/mypage/c/d/e", Link: "/a/b/mypage/c/d/e/"},
|
||||
},
|
||||
}
|
||||
|
||||
@@ -206,8 +207,8 @@ func TestPageTargetPath(t *testing.T) {
|
||||
expected := test.expected
|
||||
|
||||
// TODO(bep) simplify
|
||||
if test.d.Kind == KindPage && test.d.BaseName == test.d.Type.BaseName {
|
||||
} else if test.d.Kind == KindHome && test.d.Type.Path != "" {
|
||||
if test.d.Kind == page.KindPage && test.d.BaseName == test.d.Type.BaseName {
|
||||
} else if test.d.Kind == page.KindHome && test.d.Type.Path != "" {
|
||||
} else if test.d.Type.MediaType.FirstSuffix.Suffix != "" && (!strings.HasPrefix(expected.TargetFilename, "/index") || test.d.Addends != "") && test.d.URL == "" && isUgly {
|
||||
expected.TargetFilename = strings.Replace(expected.TargetFilename,
|
||||
"/"+test.d.Type.BaseName+"."+test.d.Type.MediaType.FirstSuffix.Suffix,
|
||||
@@ -228,7 +229,7 @@ func TestPageTargetPath(t *testing.T) {
|
||||
expected.TargetFilename = filepath.FromSlash(expected.TargetFilename)
|
||||
expected.SubResourceBaseTarget = filepath.FromSlash(expected.SubResourceBaseTarget)
|
||||
|
||||
pagePath := CreateTargetPaths(test.d)
|
||||
pagePath := page.CreateTargetPaths(test.d)
|
||||
|
||||
if !eqTargetPaths(pagePath, expected) {
|
||||
t.Fatalf("[%d] [%s] targetPath expected\n%#v, got:\n%#v", i, test.name, expected, pagePath)
|
||||
@@ -244,18 +245,18 @@ func TestPageTargetPathPrefix(t *testing.T) {
|
||||
pathSpec := newTestPathSpec()
|
||||
tests := []struct {
|
||||
name string
|
||||
d TargetPathDescriptor
|
||||
expected TargetPaths
|
||||
d page.TargetPathDescriptor
|
||||
expected page.TargetPaths
|
||||
}{
|
||||
{
|
||||
"URL set, prefix both, no force",
|
||||
TargetPathDescriptor{Kind: KindPage, Type: output.JSONFormat, URL: "/mydir/my.json", ForcePrefix: false, PrefixFilePath: "pf", PrefixLink: "pl"},
|
||||
TargetPaths{TargetFilename: "/mydir/my.json", SubResourceBaseTarget: "/mydir", SubResourceBaseLink: "/mydir", Link: "/mydir/my.json"},
|
||||
page.TargetPathDescriptor{Kind: page.KindPage, Type: output.JSONFormat, URL: "/mydir/my.json", ForcePrefix: false, PrefixFilePath: "pf", PrefixLink: "pl"},
|
||||
page.TargetPaths{TargetFilename: "/mydir/my.json", SubResourceBaseTarget: "/mydir", SubResourceBaseLink: "/mydir", Link: "/mydir/my.json"},
|
||||
},
|
||||
{
|
||||
"URL set, prefix both, force",
|
||||
TargetPathDescriptor{Kind: KindPage, Type: output.JSONFormat, URL: "/mydir/my.json", ForcePrefix: true, PrefixFilePath: "pf", PrefixLink: "pl"},
|
||||
TargetPaths{TargetFilename: "/pf/mydir/my.json", SubResourceBaseTarget: "/pf/mydir", SubResourceBaseLink: "/pl/mydir", Link: "/pl/mydir/my.json"},
|
||||
page.TargetPathDescriptor{Kind: page.KindPage, Type: output.JSONFormat, URL: "/mydir/my.json", ForcePrefix: true, PrefixFilePath: "pf", PrefixLink: "pl"},
|
||||
page.TargetPaths{TargetFilename: "/pf/mydir/my.json", SubResourceBaseTarget: "/pf/mydir", SubResourceBaseLink: "/pl/mydir", Link: "/pl/mydir/my.json"},
|
||||
},
|
||||
}
|
||||
|
||||
@@ -267,7 +268,7 @@ func TestPageTargetPathPrefix(t *testing.T) {
|
||||
expected.TargetFilename = filepath.FromSlash(expected.TargetFilename)
|
||||
expected.SubResourceBaseTarget = filepath.FromSlash(expected.SubResourceBaseTarget)
|
||||
|
||||
pagePath := CreateTargetPaths(test.d)
|
||||
pagePath := page.CreateTargetPaths(test.d)
|
||||
|
||||
if pagePath != expected {
|
||||
t.Fatalf("[%d] [%s] targetPath expected\n%#v, got:\n%#v", i, test.name, expected, pagePath)
|
||||
@@ -276,7 +277,7 @@ func TestPageTargetPathPrefix(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func eqTargetPaths(p1, p2 TargetPaths) bool {
|
||||
func eqTargetPaths(p1, p2 page.TargetPaths) bool {
|
||||
if p1.Link != p2.Link {
|
||||
return false
|
||||
}
|
||||
|
@@ -31,7 +31,7 @@ import (
|
||||
// FrontMatterHandler maps front matter into Page fields and .Params.
|
||||
// Note that we currently have only extracted the date logic.
|
||||
type FrontMatterHandler struct {
|
||||
fmConfig frontmatterConfig
|
||||
fmConfig FrontmatterConfig
|
||||
|
||||
dateHandler frontMatterFieldHandler
|
||||
lastModHandler frontMatterFieldHandler
|
||||
@@ -159,11 +159,15 @@ func (f FrontMatterHandler) newChainedFrontMatterFieldHandler(handlers ...frontM
|
||||
}
|
||||
}
|
||||
|
||||
type frontmatterConfig struct {
|
||||
date []string
|
||||
lastmod []string
|
||||
publishDate []string
|
||||
expiryDate []string
|
||||
type FrontmatterConfig struct {
|
||||
// Controls how the Date is set from front matter.
|
||||
Date []string
|
||||
// Controls how the Lastmod is set from front matter.
|
||||
Lastmod []string
|
||||
// Controls how the PublishDate is set from front matter.
|
||||
PublishDate []string
|
||||
// Controls how the ExpiryDate is set from front matter.
|
||||
ExpiryDate []string
|
||||
}
|
||||
|
||||
const (
|
||||
@@ -185,16 +189,16 @@ const (
|
||||
)
|
||||
|
||||
// This is the config you get when doing nothing.
|
||||
func newDefaultFrontmatterConfig() frontmatterConfig {
|
||||
return frontmatterConfig{
|
||||
date: []string{fmDate, fmPubDate, fmLastmod},
|
||||
lastmod: []string{fmGitAuthorDate, fmLastmod, fmDate, fmPubDate},
|
||||
publishDate: []string{fmPubDate, fmDate},
|
||||
expiryDate: []string{fmExpiryDate},
|
||||
func newDefaultFrontmatterConfig() FrontmatterConfig {
|
||||
return FrontmatterConfig{
|
||||
Date: []string{fmDate, fmPubDate, fmLastmod},
|
||||
Lastmod: []string{fmGitAuthorDate, fmLastmod, fmDate, fmPubDate},
|
||||
PublishDate: []string{fmPubDate, fmDate},
|
||||
ExpiryDate: []string{fmExpiryDate},
|
||||
}
|
||||
}
|
||||
|
||||
func newFrontmatterConfig(cfg config.Provider) (frontmatterConfig, error) {
|
||||
func DecodeFrontMatterConfig(cfg config.Provider) (FrontmatterConfig, error) {
|
||||
c := newDefaultFrontmatterConfig()
|
||||
defaultConfig := c
|
||||
|
||||
@@ -204,13 +208,13 @@ func newFrontmatterConfig(cfg config.Provider) (frontmatterConfig, error) {
|
||||
loki := strings.ToLower(k)
|
||||
switch loki {
|
||||
case fmDate:
|
||||
c.date = toLowerSlice(v)
|
||||
c.Date = toLowerSlice(v)
|
||||
case fmPubDate:
|
||||
c.publishDate = toLowerSlice(v)
|
||||
c.PublishDate = toLowerSlice(v)
|
||||
case fmLastmod:
|
||||
c.lastmod = toLowerSlice(v)
|
||||
c.Lastmod = toLowerSlice(v)
|
||||
case fmExpiryDate:
|
||||
c.expiryDate = toLowerSlice(v)
|
||||
c.ExpiryDate = toLowerSlice(v)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -221,10 +225,10 @@ func newFrontmatterConfig(cfg config.Provider) (frontmatterConfig, error) {
|
||||
return out
|
||||
}
|
||||
|
||||
c.date = expander(c.date, defaultConfig.date)
|
||||
c.publishDate = expander(c.publishDate, defaultConfig.publishDate)
|
||||
c.lastmod = expander(c.lastmod, defaultConfig.lastmod)
|
||||
c.expiryDate = expander(c.expiryDate, defaultConfig.expiryDate)
|
||||
c.Date = expander(c.Date, defaultConfig.Date)
|
||||
c.PublishDate = expander(c.PublishDate, defaultConfig.PublishDate)
|
||||
c.Lastmod = expander(c.Lastmod, defaultConfig.Lastmod)
|
||||
c.ExpiryDate = expander(c.ExpiryDate, defaultConfig.ExpiryDate)
|
||||
|
||||
return c, nil
|
||||
}
|
||||
@@ -264,16 +268,11 @@ func toLowerSlice(in any) []string {
|
||||
|
||||
// NewFrontmatterHandler creates a new FrontMatterHandler with the given logger and configuration.
|
||||
// If no logger is provided, one will be created.
|
||||
func NewFrontmatterHandler(logger loggers.Logger, cfg config.Provider) (FrontMatterHandler, error) {
|
||||
func NewFrontmatterHandler(logger loggers.Logger, frontMatterConfig FrontmatterConfig) (FrontMatterHandler, error) {
|
||||
if logger == nil {
|
||||
logger = loggers.NewErrorLogger()
|
||||
}
|
||||
|
||||
frontMatterConfig, err := newFrontmatterConfig(cfg)
|
||||
if err != nil {
|
||||
return FrontMatterHandler{}, err
|
||||
}
|
||||
|
||||
allDateKeys := make(map[string]bool)
|
||||
addKeys := func(vals []string) {
|
||||
for _, k := range vals {
|
||||
@@ -283,10 +282,10 @@ func NewFrontmatterHandler(logger loggers.Logger, cfg config.Provider) (FrontMat
|
||||
}
|
||||
}
|
||||
|
||||
addKeys(frontMatterConfig.date)
|
||||
addKeys(frontMatterConfig.expiryDate)
|
||||
addKeys(frontMatterConfig.lastmod)
|
||||
addKeys(frontMatterConfig.publishDate)
|
||||
addKeys(frontMatterConfig.Date)
|
||||
addKeys(frontMatterConfig.ExpiryDate)
|
||||
addKeys(frontMatterConfig.Lastmod)
|
||||
addKeys(frontMatterConfig.PublishDate)
|
||||
|
||||
f := FrontMatterHandler{logger: logger, fmConfig: frontMatterConfig, allDateKeys: allDateKeys}
|
||||
|
||||
@@ -300,7 +299,7 @@ func NewFrontmatterHandler(logger loggers.Logger, cfg config.Provider) (FrontMat
|
||||
func (f *FrontMatterHandler) createHandlers() error {
|
||||
var err error
|
||||
|
||||
if f.dateHandler, err = f.createDateHandler(f.fmConfig.date,
|
||||
if f.dateHandler, err = f.createDateHandler(f.fmConfig.Date,
|
||||
func(d *FrontMatterDescriptor, t time.Time) {
|
||||
d.Dates.FDate = t
|
||||
setParamIfNotSet(fmDate, t, d)
|
||||
@@ -308,7 +307,7 @@ func (f *FrontMatterHandler) createHandlers() error {
|
||||
return err
|
||||
}
|
||||
|
||||
if f.lastModHandler, err = f.createDateHandler(f.fmConfig.lastmod,
|
||||
if f.lastModHandler, err = f.createDateHandler(f.fmConfig.Lastmod,
|
||||
func(d *FrontMatterDescriptor, t time.Time) {
|
||||
setParamIfNotSet(fmLastmod, t, d)
|
||||
d.Dates.FLastmod = t
|
||||
@@ -316,7 +315,7 @@ func (f *FrontMatterHandler) createHandlers() error {
|
||||
return err
|
||||
}
|
||||
|
||||
if f.publishDateHandler, err = f.createDateHandler(f.fmConfig.publishDate,
|
||||
if f.publishDateHandler, err = f.createDateHandler(f.fmConfig.PublishDate,
|
||||
func(d *FrontMatterDescriptor, t time.Time) {
|
||||
setParamIfNotSet(fmPubDate, t, d)
|
||||
d.Dates.FPublishDate = t
|
||||
@@ -324,7 +323,7 @@ func (f *FrontMatterHandler) createHandlers() error {
|
||||
return err
|
||||
}
|
||||
|
||||
if f.expiryDateHandler, err = f.createDateHandler(f.fmConfig.expiryDate,
|
||||
if f.expiryDateHandler, err = f.createDateHandler(f.fmConfig.ExpiryDate,
|
||||
func(d *FrontMatterDescriptor, t time.Time) {
|
||||
setParamIfNotSet(fmExpiryDate, t, d)
|
||||
d.Dates.FExpiryDate = t
|
||||
|
@@ -11,7 +11,7 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package pagemeta
|
||||
package pagemeta_test
|
||||
|
||||
import (
|
||||
"strings"
|
||||
@@ -19,54 +19,20 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/gohugoio/hugo/config"
|
||||
"github.com/gohugoio/hugo/config/testconfig"
|
||||
|
||||
"github.com/gohugoio/hugo/resources/page/pagemeta"
|
||||
"github.com/gohugoio/hugo/resources/resource"
|
||||
|
||||
qt "github.com/frankban/quicktest"
|
||||
)
|
||||
|
||||
func TestDateAndSlugFromBaseFilename(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
c := qt.New(t)
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
date string
|
||||
slug string
|
||||
}{
|
||||
{"page.md", "0001-01-01", ""},
|
||||
{"2012-09-12-page.md", "2012-09-12", "page"},
|
||||
{"2018-02-28-page.md", "2018-02-28", "page"},
|
||||
{"2018-02-28_page.md", "2018-02-28", "page"},
|
||||
{"2018-02-28 page.md", "2018-02-28", "page"},
|
||||
{"2018-02-28page.md", "2018-02-28", "page"},
|
||||
{"2018-02-28-.md", "2018-02-28", ""},
|
||||
{"2018-02-28-.md", "2018-02-28", ""},
|
||||
{"2018-02-28.md", "2018-02-28", ""},
|
||||
{"2018-02-28-page", "2018-02-28", "page"},
|
||||
{"2012-9-12-page.md", "0001-01-01", ""},
|
||||
{"asdfasdf.md", "0001-01-01", ""},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
expecteFDate, err := time.Parse("2006-01-02", test.date)
|
||||
c.Assert(err, qt.IsNil)
|
||||
|
||||
gotDate, gotSlug := dateAndSlugFromBaseFilename(time.UTC, test.name)
|
||||
|
||||
c.Assert(gotDate, qt.Equals, expecteFDate)
|
||||
c.Assert(gotSlug, qt.Equals, test.slug)
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
func newTestFd() *FrontMatterDescriptor {
|
||||
return &FrontMatterDescriptor{
|
||||
func newTestFd() *pagemeta.FrontMatterDescriptor {
|
||||
return &pagemeta.FrontMatterDescriptor{
|
||||
Frontmatter: make(map[string]any),
|
||||
Params: make(map[string]any),
|
||||
Dates: &resource.Dates{},
|
||||
PageURLs: &URLPath{},
|
||||
PageURLs: &pagemeta.URLPath{},
|
||||
Location: time.UTC,
|
||||
}
|
||||
}
|
||||
@@ -83,21 +49,21 @@ func TestFrontMatterNewConfig(t *testing.T) {
|
||||
"publishDate": []string{"date"},
|
||||
})
|
||||
|
||||
fc, err := newFrontmatterConfig(cfg)
|
||||
fc, err := pagemeta.DecodeFrontMatterConfig(cfg)
|
||||
c.Assert(err, qt.IsNil)
|
||||
c.Assert(fc.date, qt.DeepEquals, []string{"publishdate", "pubdate", "published", "lastmod", "modified"})
|
||||
c.Assert(fc.lastmod, qt.DeepEquals, []string{"publishdate", "pubdate", "published"})
|
||||
c.Assert(fc.expiryDate, qt.DeepEquals, []string{"lastmod", "modified"})
|
||||
c.Assert(fc.publishDate, qt.DeepEquals, []string{"date"})
|
||||
c.Assert(fc.Date, qt.DeepEquals, []string{"publishdate", "pubdate", "published", "lastmod", "modified"})
|
||||
c.Assert(fc.Lastmod, qt.DeepEquals, []string{"publishdate", "pubdate", "published"})
|
||||
c.Assert(fc.ExpiryDate, qt.DeepEquals, []string{"lastmod", "modified"})
|
||||
c.Assert(fc.PublishDate, qt.DeepEquals, []string{"date"})
|
||||
|
||||
// Default
|
||||
cfg = config.New()
|
||||
fc, err = newFrontmatterConfig(cfg)
|
||||
fc, err = pagemeta.DecodeFrontMatterConfig(cfg)
|
||||
c.Assert(err, qt.IsNil)
|
||||
c.Assert(fc.date, qt.DeepEquals, []string{"date", "publishdate", "pubdate", "published", "lastmod", "modified"})
|
||||
c.Assert(fc.lastmod, qt.DeepEquals, []string{":git", "lastmod", "modified", "date", "publishdate", "pubdate", "published"})
|
||||
c.Assert(fc.expiryDate, qt.DeepEquals, []string{"expirydate", "unpublishdate"})
|
||||
c.Assert(fc.publishDate, qt.DeepEquals, []string{"publishdate", "pubdate", "published", "date"})
|
||||
c.Assert(fc.Date, qt.DeepEquals, []string{"date", "publishdate", "pubdate", "published", "lastmod", "modified"})
|
||||
c.Assert(fc.Lastmod, qt.DeepEquals, []string{":git", "lastmod", "modified", "date", "publishdate", "pubdate", "published"})
|
||||
c.Assert(fc.ExpiryDate, qt.DeepEquals, []string{"expirydate", "unpublishdate"})
|
||||
c.Assert(fc.PublishDate, qt.DeepEquals, []string{"publishdate", "pubdate", "published", "date"})
|
||||
|
||||
// :default keyword
|
||||
cfg.Set("frontmatter", map[string]any{
|
||||
@@ -106,12 +72,12 @@ func TestFrontMatterNewConfig(t *testing.T) {
|
||||
"expiryDate": []string{"d3", ":default"},
|
||||
"publishDate": []string{"d4", ":default"},
|
||||
})
|
||||
fc, err = newFrontmatterConfig(cfg)
|
||||
fc, err = pagemeta.DecodeFrontMatterConfig(cfg)
|
||||
c.Assert(err, qt.IsNil)
|
||||
c.Assert(fc.date, qt.DeepEquals, []string{"d1", "date", "publishdate", "pubdate", "published", "lastmod", "modified"})
|
||||
c.Assert(fc.lastmod, qt.DeepEquals, []string{"d2", ":git", "lastmod", "modified", "date", "publishdate", "pubdate", "published"})
|
||||
c.Assert(fc.expiryDate, qt.DeepEquals, []string{"d3", "expirydate", "unpublishdate"})
|
||||
c.Assert(fc.publishDate, qt.DeepEquals, []string{"d4", "publishdate", "pubdate", "published", "date"})
|
||||
c.Assert(fc.Date, qt.DeepEquals, []string{"d1", "date", "publishdate", "pubdate", "published", "lastmod", "modified"})
|
||||
c.Assert(fc.Lastmod, qt.DeepEquals, []string{"d2", ":git", "lastmod", "modified", "date", "publishdate", "pubdate", "published"})
|
||||
c.Assert(fc.ExpiryDate, qt.DeepEquals, []string{"d3", "expirydate", "unpublishdate"})
|
||||
c.Assert(fc.PublishDate, qt.DeepEquals, []string{"d4", "publishdate", "pubdate", "published", "date"})
|
||||
}
|
||||
|
||||
func TestFrontMatterDatesHandlers(t *testing.T) {
|
||||
@@ -124,8 +90,8 @@ func TestFrontMatterDatesHandlers(t *testing.T) {
|
||||
cfg.Set("frontmatter", map[string]any{
|
||||
"date": []string{handlerID, "date"},
|
||||
})
|
||||
|
||||
handler, err := NewFrontmatterHandler(nil, cfg)
|
||||
conf := testconfig.GetTestConfig(nil, cfg)
|
||||
handler, err := pagemeta.NewFrontmatterHandler(nil, conf.GetConfigSection("frontmatter").(pagemeta.FrontmatterConfig))
|
||||
c.Assert(err, qt.IsNil)
|
||||
|
||||
d1, _ := time.Parse("2006-01-02", "2018-02-01")
|
||||
@@ -166,7 +132,8 @@ func TestFrontMatterDatesCustomConfig(t *testing.T) {
|
||||
"publishdate": []string{"publishdate"},
|
||||
})
|
||||
|
||||
handler, err := NewFrontmatterHandler(nil, cfg)
|
||||
conf := testconfig.GetTestConfig(nil, cfg)
|
||||
handler, err := pagemeta.NewFrontmatterHandler(nil, conf.GetConfigSection("frontmatter").(pagemeta.FrontmatterConfig))
|
||||
c.Assert(err, qt.IsNil)
|
||||
|
||||
testDate, err := time.Parse("2006-01-02", "2018-02-01")
|
||||
@@ -213,7 +180,8 @@ func TestFrontMatterDatesDefaultKeyword(t *testing.T) {
|
||||
"publishdate": []string{":default", "mypubdate"},
|
||||
})
|
||||
|
||||
handler, err := NewFrontmatterHandler(nil, cfg)
|
||||
conf := testconfig.GetTestConfig(nil, cfg)
|
||||
handler, err := pagemeta.NewFrontmatterHandler(nil, conf.GetConfigSection("frontmatter").(pagemeta.FrontmatterConfig))
|
||||
c.Assert(err, qt.IsNil)
|
||||
|
||||
testDate, _ := time.Parse("2006-01-02", "2018-02-01")
|
||||
@@ -230,28 +198,3 @@ func TestFrontMatterDatesDefaultKeyword(t *testing.T) {
|
||||
c.Assert(d.Dates.FPublishDate.Day(), qt.Equals, 4)
|
||||
c.Assert(d.Dates.FExpiryDate.IsZero(), qt.Equals, true)
|
||||
}
|
||||
|
||||
func TestExpandDefaultValues(t *testing.T) {
|
||||
c := qt.New(t)
|
||||
c.Assert(expandDefaultValues([]string{"a", ":default", "d"}, []string{"b", "c"}), qt.DeepEquals, []string{"a", "b", "c", "d"})
|
||||
c.Assert(expandDefaultValues([]string{"a", "b", "c"}, []string{"a", "b", "c"}), qt.DeepEquals, []string{"a", "b", "c"})
|
||||
c.Assert(expandDefaultValues([]string{":default", "a", ":default", "d"}, []string{"b", "c"}), qt.DeepEquals, []string{"b", "c", "a", "b", "c", "d"})
|
||||
}
|
||||
|
||||
func TestFrontMatterDateFieldHandler(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
c := qt.New(t)
|
||||
|
||||
handlers := new(frontmatterFieldHandlers)
|
||||
|
||||
fd := newTestFd()
|
||||
d, _ := time.Parse("2006-01-02", "2018-02-01")
|
||||
fd.Frontmatter["date"] = d
|
||||
h := handlers.newDateFieldHandler("date", func(d *FrontMatterDescriptor, t time.Time) { d.Dates.FDate = t })
|
||||
|
||||
handled, err := h(fd)
|
||||
c.Assert(handled, qt.Equals, true)
|
||||
c.Assert(err, qt.IsNil)
|
||||
c.Assert(fd.Dates.FDate, qt.Equals, d)
|
||||
}
|
||||
|
@@ -16,6 +16,7 @@ package pagemeta
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/gohugoio/hugo/htesting/hqt"
|
||||
|
||||
@@ -90,3 +91,46 @@ publishResources = true`
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
func TestDateAndSlugFromBaseFilename(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
c := qt.New(t)
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
date string
|
||||
slug string
|
||||
}{
|
||||
{"page.md", "0001-01-01", ""},
|
||||
{"2012-09-12-page.md", "2012-09-12", "page"},
|
||||
{"2018-02-28-page.md", "2018-02-28", "page"},
|
||||
{"2018-02-28_page.md", "2018-02-28", "page"},
|
||||
{"2018-02-28 page.md", "2018-02-28", "page"},
|
||||
{"2018-02-28page.md", "2018-02-28", "page"},
|
||||
{"2018-02-28-.md", "2018-02-28", ""},
|
||||
{"2018-02-28-.md", "2018-02-28", ""},
|
||||
{"2018-02-28.md", "2018-02-28", ""},
|
||||
{"2018-02-28-page", "2018-02-28", "page"},
|
||||
{"2012-9-12-page.md", "0001-01-01", ""},
|
||||
{"asdfasdf.md", "0001-01-01", ""},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
expecteFDate, err := time.Parse("2006-01-02", test.date)
|
||||
c.Assert(err, qt.IsNil)
|
||||
|
||||
gotDate, gotSlug := dateAndSlugFromBaseFilename(time.UTC, test.name)
|
||||
|
||||
c.Assert(gotDate, qt.Equals, expecteFDate)
|
||||
c.Assert(gotSlug, qt.Equals, test.slug)
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
func TestExpandDefaultValues(t *testing.T) {
|
||||
c := qt.New(t)
|
||||
c.Assert(expandDefaultValues([]string{"a", ":default", "d"}, []string{"b", "c"}), qt.DeepEquals, []string{"a", "b", "c", "d"})
|
||||
c.Assert(expandDefaultValues([]string{"a", "b", "c"}, []string{"a", "b", "c"}), qt.DeepEquals, []string{"a", "b", "c"})
|
||||
c.Assert(expandDefaultValues([]string{":default", "a", ":default", "d"}, []string{"b", "c"}), qt.DeepEquals, []string{"b", "c", "a", "b", "c", "d"})
|
||||
}
|
||||
|
@@ -50,6 +50,7 @@ func (p1 Pages) MergeByLanguage(p2 Pages) Pages {
|
||||
|
||||
// MergeByLanguageInterface is the generic version of MergeByLanguage. It
|
||||
// is here just so it can be called from the tpl package.
|
||||
// This is for internal use.
|
||||
func (p1 Pages) MergeByLanguageInterface(in any) (any, error) {
|
||||
if in == nil {
|
||||
return p1, nil
|
||||
|
@@ -250,9 +250,9 @@ func splitPageGroups(pageGroups PagesGroup, size int) []paginatedElement {
|
||||
return split
|
||||
}
|
||||
|
||||
func ResolvePagerSize(cfg config.Provider, options ...any) (int, error) {
|
||||
func ResolvePagerSize(conf config.AllProvider, options ...any) (int, error) {
|
||||
if len(options) == 0 {
|
||||
return cfg.GetInt("paginate"), nil
|
||||
return conf.Paginate(), nil
|
||||
}
|
||||
|
||||
if len(options) > 1 {
|
||||
@@ -389,7 +389,7 @@ func newPaginationURLFactory(d TargetPathDescriptor) paginationURLFactory {
|
||||
pathDescriptor := d
|
||||
var rel string
|
||||
if pageNumber > 1 {
|
||||
rel = fmt.Sprintf("/%s/%d/", d.PathSpec.PaginatePath, pageNumber)
|
||||
rel = fmt.Sprintf("/%s/%d/", d.PathSpec.Cfg.PaginatePath(), pageNumber)
|
||||
pathDescriptor.Addends = rel
|
||||
}
|
||||
|
||||
|
@@ -19,10 +19,7 @@ import (
|
||||
"html/template"
|
||||
"testing"
|
||||
|
||||
"github.com/gohugoio/hugo/config"
|
||||
|
||||
qt "github.com/frankban/quicktest"
|
||||
"github.com/gohugoio/hugo/output"
|
||||
)
|
||||
|
||||
func TestSplitPages(t *testing.T) {
|
||||
@@ -194,58 +191,6 @@ func doTestPagerNoPages(t *testing.T, paginator *Paginator) {
|
||||
c.Assert(pageOne.PageSize(), qt.Equals, 5)
|
||||
}
|
||||
|
||||
func TestPaginationURLFactory(t *testing.T) {
|
||||
t.Parallel()
|
||||
c := qt.New(t)
|
||||
cfg := config.New()
|
||||
cfg.Set("paginatePath", "zoo")
|
||||
|
||||
for _, uglyURLs := range []bool{false, true} {
|
||||
c.Run(fmt.Sprintf("uglyURLs=%t", uglyURLs), func(c *qt.C) {
|
||||
tests := []struct {
|
||||
name string
|
||||
d TargetPathDescriptor
|
||||
baseURL string
|
||||
page int
|
||||
expected string
|
||||
expectedUgly string
|
||||
}{
|
||||
{
|
||||
"HTML home page 32",
|
||||
TargetPathDescriptor{Kind: KindHome, Type: output.HTMLFormat},
|
||||
"http://example.com/", 32, "/zoo/32/", "/zoo/32.html",
|
||||
},
|
||||
{
|
||||
"JSON home page 42",
|
||||
TargetPathDescriptor{Kind: KindHome, Type: output.JSONFormat},
|
||||
"http://example.com/", 42, "/zoo/42/index.json", "/zoo/42.json",
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
d := test.d
|
||||
cfg.Set("baseURL", test.baseURL)
|
||||
cfg.Set("uglyURLs", uglyURLs)
|
||||
d.UglyURLs = uglyURLs
|
||||
|
||||
pathSpec := newTestPathSpecFor(cfg)
|
||||
d.PathSpec = pathSpec
|
||||
|
||||
factory := newPaginationURLFactory(d)
|
||||
|
||||
got := factory(test.page)
|
||||
|
||||
if uglyURLs {
|
||||
c.Assert(got, qt.Equals, test.expectedUgly)
|
||||
} else {
|
||||
c.Assert(got, qt.Equals, test.expected)
|
||||
}
|
||||
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestProbablyEqualPageLists(t *testing.T) {
|
||||
t.Parallel()
|
||||
fivePages := createTestPages(5)
|
||||
|
@@ -37,7 +37,7 @@ type PermalinkExpander struct {
|
||||
|
||||
expanders map[string]func(Page) (string, error)
|
||||
|
||||
ps *helpers.PathSpec
|
||||
urlize func(uri string) string
|
||||
}
|
||||
|
||||
// Time for checking date formats. Every field is different than the
|
||||
@@ -67,9 +67,9 @@ func (p PermalinkExpander) callback(attr string) (pageToPermaAttribute, bool) {
|
||||
}
|
||||
|
||||
// NewPermalinkExpander creates a new PermalinkExpander configured by the given
|
||||
// PathSpec.
|
||||
func NewPermalinkExpander(ps *helpers.PathSpec) (PermalinkExpander, error) {
|
||||
p := PermalinkExpander{ps: ps}
|
||||
// urlize func.
|
||||
func NewPermalinkExpander(urlize func(uri string) string, patterns map[string]string) (PermalinkExpander, error) {
|
||||
p := PermalinkExpander{urlize: urlize}
|
||||
|
||||
p.knownPermalinkAttributes = map[string]pageToPermaAttribute{
|
||||
"year": p.pageToPermalinkDate,
|
||||
@@ -87,11 +87,6 @@ func NewPermalinkExpander(ps *helpers.PathSpec) (PermalinkExpander, error) {
|
||||
"filename": p.pageToPermalinkFilename,
|
||||
}
|
||||
|
||||
patterns := ps.Cfg.GetStringMapString("permalinks")
|
||||
if patterns == nil {
|
||||
return p, nil
|
||||
}
|
||||
|
||||
e, err := p.parse(patterns)
|
||||
if err != nil {
|
||||
return p, err
|
||||
@@ -180,6 +175,9 @@ var attributeRegexp = regexp.MustCompile(`:\w+(\[.+?\])?`)
|
||||
|
||||
// validate determines if a PathPattern is well-formed
|
||||
func (l PermalinkExpander) validate(pp string) bool {
|
||||
if len(pp) == 0 {
|
||||
return false
|
||||
}
|
||||
fragments := strings.Split(pp[1:], "/")
|
||||
bail := false
|
||||
for i := range fragments {
|
||||
@@ -244,7 +242,7 @@ func (l PermalinkExpander) pageToPermalinkDate(p Page, dateField string) (string
|
||||
|
||||
// pageToPermalinkTitle returns the URL-safe form of the title
|
||||
func (l PermalinkExpander) pageToPermalinkTitle(p Page, _ string) (string, error) {
|
||||
return l.ps.URLize(p.Title()), nil
|
||||
return l.urlize(p.Title()), nil
|
||||
}
|
||||
|
||||
// pageToPermalinkFilename returns the URL-safe form of the filename
|
||||
@@ -256,13 +254,13 @@ func (l PermalinkExpander) pageToPermalinkFilename(p Page, _ string) (string, er
|
||||
_, name = filepath.Split(dir)
|
||||
}
|
||||
|
||||
return l.ps.URLize(name), nil
|
||||
return l.urlize(name), nil
|
||||
}
|
||||
|
||||
// if the page has a slug, return the slug, else return the title
|
||||
func (l PermalinkExpander) pageToPermalinkSlugElseTitle(p Page, a string) (string, error) {
|
||||
if p.Slug() != "" {
|
||||
return l.ps.URLize(p.Slug()), nil
|
||||
return l.urlize(p.Slug()), nil
|
||||
}
|
||||
return l.pageToPermalinkTitle(p, a)
|
||||
}
|
||||
@@ -270,7 +268,7 @@ func (l PermalinkExpander) pageToPermalinkSlugElseTitle(p Page, a string) (strin
|
||||
// if the page has a slug, return the slug, else return the filename
|
||||
func (l PermalinkExpander) pageToPermalinkSlugElseFilename(p Page, a string) (string, error) {
|
||||
if p.Slug() != "" {
|
||||
return l.ps.URLize(p.Slug()), nil
|
||||
return l.urlize(p.Slug()), nil
|
||||
}
|
||||
return l.pageToPermalinkFilename(p, a)
|
||||
}
|
||||
|
@@ -1,4 +1,4 @@
|
||||
// Copyright 2019 The Hugo Authors. All rights reserved.
|
||||
// Copyright 2023 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.
|
||||
@@ -16,6 +16,7 @@ package page
|
||||
import (
|
||||
"fmt"
|
||||
"regexp"
|
||||
"strings"
|
||||
"sync"
|
||||
"testing"
|
||||
"time"
|
||||
@@ -52,6 +53,11 @@ var testdataPermalinks = []struct {
|
||||
{"/:2006-01-02", false, ""}, // valid date format but invalid attribute name
|
||||
}
|
||||
|
||||
func urlize(uri string) string {
|
||||
// This is just an approximation of the real urlize function.
|
||||
return strings.ToLower(strings.ReplaceAll(uri, " ", "-"))
|
||||
}
|
||||
|
||||
func TestPermalinkExpansion(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
@@ -73,17 +79,11 @@ func TestPermalinkExpansion(t *testing.T) {
|
||||
name := specNameCleaner.ReplaceAllString(item.spec, "")
|
||||
|
||||
c.Run(name, func(c *qt.C) {
|
||||
|
||||
permalinksConfig := map[string]string{
|
||||
patterns := map[string]string{
|
||||
"posts": item.spec,
|
||||
}
|
||||
|
||||
ps := newTestPathSpec()
|
||||
ps.Cfg.Set("permalinks", permalinksConfig)
|
||||
|
||||
expander, err := NewPermalinkExpander(ps)
|
||||
expander, err := NewPermalinkExpander(urlize, patterns)
|
||||
c.Assert(err, qt.IsNil)
|
||||
|
||||
expanded, err := expander.Expand("posts", page)
|
||||
c.Assert(err, qt.IsNil)
|
||||
c.Assert(expanded, qt.Equals, item.expandsTo)
|
||||
@@ -112,11 +112,7 @@ func TestPermalinkExpansionMultiSection(t *testing.T) {
|
||||
"blog": "/:section/:year",
|
||||
"recipes": "/:slugorfilename",
|
||||
}
|
||||
|
||||
ps := newTestPathSpec()
|
||||
ps.Cfg.Set("permalinks", permalinksConfig)
|
||||
|
||||
expander, err := NewPermalinkExpander(ps)
|
||||
expander, err := NewPermalinkExpander(urlize, permalinksConfig)
|
||||
c.Assert(err, qt.IsNil)
|
||||
|
||||
expanded, err := expander.Expand("posts", page)
|
||||
@@ -145,10 +141,7 @@ func TestPermalinkExpansionConcurrent(t *testing.T) {
|
||||
"posts": "/:slug/",
|
||||
}
|
||||
|
||||
ps := newTestPathSpec()
|
||||
ps.Cfg.Set("permalinks", permalinksConfig)
|
||||
|
||||
expander, err := NewPermalinkExpander(ps)
|
||||
expander, err := NewPermalinkExpander(urlize, permalinksConfig)
|
||||
c.Assert(err, qt.IsNil)
|
||||
|
||||
var wg sync.WaitGroup
|
||||
@@ -174,7 +167,8 @@ func TestPermalinkExpansionSliceSyntax(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
c := qt.New(t)
|
||||
exp, _ := NewPermalinkExpander(newTestPathSpec())
|
||||
exp, err := NewPermalinkExpander(urlize, nil)
|
||||
c.Assert(err, qt.IsNil)
|
||||
slice := []string{"a", "b", "c", "d"}
|
||||
fn := func(s string) []string {
|
||||
return exp.toSliceFunc(s)(slice)
|
||||
@@ -219,11 +213,7 @@ func BenchmarkPermalinkExpand(b *testing.B) {
|
||||
permalinksConfig := map[string]string{
|
||||
"posts": "/:year-:month-:title",
|
||||
}
|
||||
|
||||
ps := newTestPathSpec()
|
||||
ps.Cfg.Set("permalinks", permalinksConfig)
|
||||
|
||||
expander, err := NewPermalinkExpander(ps)
|
||||
expander, err := NewPermalinkExpander(urlize, permalinksConfig)
|
||||
if err != nil {
|
||||
b.Fatal(err)
|
||||
}
|
||||
|
@@ -18,7 +18,10 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/gohugoio/hugo/common/maps"
|
||||
"github.com/gohugoio/hugo/config/privacy"
|
||||
"github.com/gohugoio/hugo/config/services"
|
||||
"github.com/gohugoio/hugo/identity"
|
||||
"github.com/gohugoio/hugo/tpl"
|
||||
|
||||
"github.com/gohugoio/hugo/config"
|
||||
|
||||
@@ -32,13 +35,15 @@ type Site interface {
|
||||
// Returns the Language configured for this Site.
|
||||
Language() *langs.Language
|
||||
|
||||
GetPage(ref ...string) (Page, error)
|
||||
|
||||
// Returns all the regular Pages in this Site.
|
||||
RegularPages() Pages
|
||||
|
||||
// Returns all Pages in this Site.
|
||||
Pages() Pages
|
||||
|
||||
// A shortcut to the home page.
|
||||
// A shortcut to the home
|
||||
Home() Page
|
||||
|
||||
// Returns true if we're running in a server.
|
||||
@@ -50,6 +55,12 @@ type Site interface {
|
||||
// Returns the configured title for this Site.
|
||||
Title() string
|
||||
|
||||
// Returns the configured language code for this Site.
|
||||
LanguageCode() string
|
||||
|
||||
// Returns the configured copyright information for this Site.
|
||||
Copyright() string
|
||||
|
||||
// Returns all Sites for all languages.
|
||||
Sites() Sites
|
||||
|
||||
@@ -57,7 +68,7 @@ type Site interface {
|
||||
Current() Site
|
||||
|
||||
// Returns a struct with some information about the build.
|
||||
Hugo() hugo.Info
|
||||
Hugo() hugo.HugoInfo
|
||||
|
||||
// Returns the BaseURL for this Site.
|
||||
BaseURL() template.URL
|
||||
@@ -71,14 +82,36 @@ type Site interface {
|
||||
// Returns the Menus for this site.
|
||||
Menus() navigation.Menus
|
||||
|
||||
// The main sections in the site.
|
||||
MainSections() []string
|
||||
|
||||
// Returns the Params configured for this site.
|
||||
Params() maps.Params
|
||||
|
||||
// Returns a map of all the data inside /data.
|
||||
Data() map[string]any
|
||||
|
||||
// Returns the site config.
|
||||
Config() SiteConfig
|
||||
|
||||
// Returns the identity of this site.
|
||||
// This is for internal use only.
|
||||
GetIdentity() identity.Identity
|
||||
|
||||
// Author is deprecated and will be removed in a future release.
|
||||
Author() map[string]interface{}
|
||||
|
||||
// Returns the social links for this site.
|
||||
Social() map[string]string
|
||||
|
||||
// Deprecated: Use Config().Services.GoogleAnalytics instead.
|
||||
GoogleAnalytics() string
|
||||
|
||||
// Deprecated: Use Config().Privacy.Disqus instead.
|
||||
DisqusShortname() string
|
||||
|
||||
// For internal use only.
|
||||
GetPageWithTemplateInfo(info tpl.Info, ref ...string) (Page, error)
|
||||
}
|
||||
|
||||
// Sites represents an ordered list of sites (languages).
|
||||
@@ -92,12 +125,139 @@ func (s Sites) First() Site {
|
||||
return s[0]
|
||||
}
|
||||
|
||||
type siteWrapper struct {
|
||||
s Site
|
||||
}
|
||||
|
||||
func WrapSite(s Site) Site {
|
||||
if s == nil {
|
||||
panic("Site is nil")
|
||||
}
|
||||
return &siteWrapper{s: s}
|
||||
}
|
||||
|
||||
func (s *siteWrapper) Social() map[string]string {
|
||||
return s.s.Social()
|
||||
}
|
||||
|
||||
func (s *siteWrapper) Author() map[string]interface{} {
|
||||
return s.s.Author()
|
||||
}
|
||||
|
||||
func (s *siteWrapper) GoogleAnalytics() string {
|
||||
return s.s.GoogleAnalytics()
|
||||
}
|
||||
|
||||
func (s *siteWrapper) GetPage(ref ...string) (Page, error) {
|
||||
return s.s.GetPage(ref...)
|
||||
}
|
||||
|
||||
func (s *siteWrapper) Language() *langs.Language {
|
||||
return s.s.Language()
|
||||
}
|
||||
|
||||
func (s *siteWrapper) RegularPages() Pages {
|
||||
return s.s.RegularPages()
|
||||
}
|
||||
|
||||
func (s *siteWrapper) Pages() Pages {
|
||||
return s.s.Pages()
|
||||
}
|
||||
|
||||
func (s *siteWrapper) Home() Page {
|
||||
return s.s.Home()
|
||||
}
|
||||
|
||||
func (s *siteWrapper) IsServer() bool {
|
||||
return s.s.IsServer()
|
||||
}
|
||||
|
||||
func (s *siteWrapper) ServerPort() int {
|
||||
return s.s.ServerPort()
|
||||
}
|
||||
|
||||
func (s *siteWrapper) Title() string {
|
||||
return s.s.Title()
|
||||
}
|
||||
|
||||
func (s *siteWrapper) LanguageCode() string {
|
||||
return s.s.LanguageCode()
|
||||
}
|
||||
|
||||
func (s *siteWrapper) Copyright() string {
|
||||
return s.s.Copyright()
|
||||
}
|
||||
|
||||
func (s *siteWrapper) Sites() Sites {
|
||||
return s.s.Sites()
|
||||
}
|
||||
|
||||
func (s *siteWrapper) Current() Site {
|
||||
return s.s.Current()
|
||||
}
|
||||
|
||||
func (s *siteWrapper) Config() SiteConfig {
|
||||
return s.s.Config()
|
||||
}
|
||||
|
||||
func (s *siteWrapper) Hugo() hugo.HugoInfo {
|
||||
return s.s.Hugo()
|
||||
}
|
||||
|
||||
func (s *siteWrapper) BaseURL() template.URL {
|
||||
return s.s.BaseURL()
|
||||
}
|
||||
|
||||
func (s *siteWrapper) Taxonomies() TaxonomyList {
|
||||
return s.s.Taxonomies()
|
||||
}
|
||||
|
||||
func (s *siteWrapper) LastChange() time.Time {
|
||||
return s.s.LastChange()
|
||||
}
|
||||
|
||||
func (s *siteWrapper) Menus() navigation.Menus {
|
||||
return s.s.Menus()
|
||||
}
|
||||
|
||||
func (s *siteWrapper) MainSections() []string {
|
||||
return s.s.MainSections()
|
||||
}
|
||||
|
||||
func (s *siteWrapper) Params() maps.Params {
|
||||
return s.s.Params()
|
||||
}
|
||||
|
||||
func (s *siteWrapper) Data() map[string]any {
|
||||
return s.s.Data()
|
||||
}
|
||||
|
||||
func (s *siteWrapper) GetIdentity() identity.Identity {
|
||||
return s.s.GetIdentity()
|
||||
}
|
||||
|
||||
func (s *siteWrapper) GetPageWithTemplateInfo(info tpl.Info, ref ...string) (Page, error) {
|
||||
return s.s.GetPageWithTemplateInfo(info, ref...)
|
||||
}
|
||||
|
||||
func (s *siteWrapper) DisqusShortname() string {
|
||||
return s.s.DisqusShortname()
|
||||
}
|
||||
|
||||
type testSite struct {
|
||||
h hugo.Info
|
||||
h hugo.HugoInfo
|
||||
l *langs.Language
|
||||
}
|
||||
|
||||
func (t testSite) Hugo() hugo.Info {
|
||||
func (s testSite) Author() map[string]interface{} {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s testSite) Social() map[string]string {
|
||||
return make(map[string]string)
|
||||
}
|
||||
|
||||
func (t testSite) Hugo() hugo.HugoInfo {
|
||||
return t.h
|
||||
}
|
||||
|
||||
@@ -113,14 +273,34 @@ func (t testSite) Title() string {
|
||||
return "foo"
|
||||
}
|
||||
|
||||
func (t testSite) LanguageCode() string {
|
||||
return t.l.Lang
|
||||
}
|
||||
|
||||
func (t testSite) Copyright() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func (t testSite) Sites() Sites {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (t testSite) GetPage(ref ...string) (Page, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (t testSite) Current() Site {
|
||||
return t
|
||||
}
|
||||
|
||||
func (t testSite) GoogleAnalytics() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func (t testSite) MainSections() []string {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (t testSite) GetIdentity() identity.Identity {
|
||||
return identity.KeyValueIdentity{Key: "site", Value: t.l.Lang}
|
||||
}
|
||||
@@ -165,10 +345,34 @@ func (t testSite) Data() map[string]any {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s testSite) Config() SiteConfig {
|
||||
return SiteConfig{}
|
||||
}
|
||||
|
||||
func (testSite) GetPageWithTemplateInfo(info tpl.Info, ref ...string) (Page, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (testSite) DisqusShortname() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
// NewDummyHugoSite creates a new minimal test site.
|
||||
func NewDummyHugoSite(cfg config.Provider) Site {
|
||||
return testSite{
|
||||
h: hugo.NewInfo(hugo.EnvironmentProduction, nil),
|
||||
l: langs.NewLanguage("en", cfg),
|
||||
l: &langs.Language{
|
||||
Lang: "en",
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// SiteConfig holds the config in site.Config.
|
||||
type SiteConfig struct {
|
||||
// This contains all privacy related settings that can be used to
|
||||
// make the YouTube template etc. GDPR compliant.
|
||||
Privacy privacy.Config
|
||||
|
||||
// Services contains config for services such as Google Analytics etc.
|
||||
Services services.Config
|
||||
}
|
||||
|
38
resources/page/testhelpers_page_test.go
Normal file
38
resources/page/testhelpers_page_test.go
Normal file
@@ -0,0 +1,38 @@
|
||||
// Copyright 2023 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 (
|
||||
"github.com/gohugoio/hugo/common/loggers"
|
||||
"github.com/gohugoio/hugo/config"
|
||||
"github.com/gohugoio/hugo/config/testconfig"
|
||||
"github.com/gohugoio/hugo/helpers"
|
||||
"github.com/gohugoio/hugo/hugofs"
|
||||
"github.com/spf13/afero"
|
||||
)
|
||||
|
||||
func newTestPathSpec() *helpers.PathSpec {
|
||||
return newTestPathSpecFor(config.New())
|
||||
}
|
||||
|
||||
func newTestPathSpecFor(cfg config.Provider) *helpers.PathSpec {
|
||||
mfs := afero.NewMemMapFs()
|
||||
conf := testconfig.GetTestConfig(mfs, cfg)
|
||||
fs := hugofs.NewFrom(mfs, conf.BaseConfig())
|
||||
ps, err := helpers.NewPathSpec(fs, conf, loggers.NewErrorLogger())
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return ps
|
||||
}
|
@@ -1,4 +1,4 @@
|
||||
// Copyright 2019 The Hugo Authors. All rights reserved.
|
||||
// Copyright 2023 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.
|
||||
@@ -26,9 +26,6 @@ import (
|
||||
"github.com/gohugoio/hugo/markup/tableofcontents"
|
||||
"github.com/gohugoio/hugo/tpl"
|
||||
|
||||
"github.com/gohugoio/hugo/modules"
|
||||
|
||||
"github.com/gohugoio/hugo/helpers"
|
||||
"github.com/gohugoio/hugo/resources/resource"
|
||||
|
||||
"github.com/gohugoio/hugo/navigation"
|
||||
@@ -58,6 +55,19 @@ func newTestPage() *testPage {
|
||||
func newTestPageWithFile(filename string) *testPage {
|
||||
filename = filepath.FromSlash(filename)
|
||||
file := source.NewTestFile(filename)
|
||||
|
||||
l, err := langs.NewLanguage(
|
||||
"en",
|
||||
"en",
|
||||
"UTC",
|
||||
langs.LanguageConfig{
|
||||
LanguageName: "English",
|
||||
},
|
||||
)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
return &testPage{
|
||||
params: make(map[string]any),
|
||||
data: make(map[string]any),
|
||||
@@ -65,30 +75,10 @@ func newTestPageWithFile(filename string) *testPage {
|
||||
currentSection: &testPage{
|
||||
sectionEntries: []string{"a", "b", "c"},
|
||||
},
|
||||
site: testSite{l: langs.NewDefaultLanguage(config.New())},
|
||||
site: testSite{l: l},
|
||||
}
|
||||
}
|
||||
|
||||
func newTestPathSpec() *helpers.PathSpec {
|
||||
return newTestPathSpecFor(config.New())
|
||||
}
|
||||
|
||||
func newTestPathSpecFor(cfg config.Provider) *helpers.PathSpec {
|
||||
config.SetBaseTestDefaults(cfg)
|
||||
langs.LoadLanguageSettings(cfg, nil)
|
||||
mod, err := modules.CreateProjectModule(cfg)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
cfg.Set("allModules", modules.Modules{mod})
|
||||
fs := hugofs.NewMem(cfg)
|
||||
s, err := helpers.NewPathSpec(fs, cfg, nil)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
||||
type testPage struct {
|
||||
kind string
|
||||
description string
|
||||
@@ -128,15 +118,15 @@ func (p *testPage) Err() resource.ResourceError {
|
||||
}
|
||||
|
||||
func (p *testPage) Aliases() []string {
|
||||
panic("not implemented")
|
||||
panic("tespage: not implemented")
|
||||
}
|
||||
|
||||
func (p *testPage) AllTranslations() Pages {
|
||||
panic("not implemented")
|
||||
panic("tespage: not implemented")
|
||||
}
|
||||
|
||||
func (p *testPage) AlternativeOutputFormats() OutputFormats {
|
||||
panic("not implemented")
|
||||
panic("tespage: not implemented")
|
||||
}
|
||||
|
||||
func (p *testPage) Author() Author {
|
||||
@@ -148,19 +138,19 @@ func (p *testPage) Authors() AuthorList {
|
||||
}
|
||||
|
||||
func (p *testPage) BaseFileName() string {
|
||||
panic("not implemented")
|
||||
panic("tespage: not implemented")
|
||||
}
|
||||
|
||||
func (p *testPage) BundleType() files.ContentClass {
|
||||
panic("not implemented")
|
||||
panic("tespage: not implemented")
|
||||
}
|
||||
|
||||
func (p *testPage) Content(context.Context) (any, error) {
|
||||
panic("not implemented")
|
||||
panic("tespage: not implemented")
|
||||
}
|
||||
|
||||
func (p *testPage) ContentBaseName() string {
|
||||
panic("not implemented")
|
||||
panic("tespage: not implemented")
|
||||
}
|
||||
|
||||
func (p *testPage) CurrentSection() Page {
|
||||
@@ -171,8 +161,8 @@ func (p *testPage) Data() any {
|
||||
return p.data
|
||||
}
|
||||
|
||||
func (p *testPage) Sitemap() config.Sitemap {
|
||||
return config.Sitemap{}
|
||||
func (p *testPage) Sitemap() config.SitemapConfig {
|
||||
return config.SitemapConfig{}
|
||||
}
|
||||
|
||||
func (p *testPage) Layout() string {
|
||||
@@ -188,11 +178,11 @@ func (p *testPage) Description() string {
|
||||
}
|
||||
|
||||
func (p *testPage) Dir() string {
|
||||
panic("not implemented")
|
||||
panic("tespage: not implemented")
|
||||
}
|
||||
|
||||
func (p *testPage) Draft() bool {
|
||||
panic("not implemented")
|
||||
panic("tespage: not implemented")
|
||||
}
|
||||
|
||||
func (p *testPage) Eq(other any) bool {
|
||||
@@ -204,11 +194,11 @@ func (p *testPage) ExpiryDate() time.Time {
|
||||
}
|
||||
|
||||
func (p *testPage) Ext() string {
|
||||
panic("not implemented")
|
||||
panic("tespage: not implemented")
|
||||
}
|
||||
|
||||
func (p *testPage) Extension() string {
|
||||
panic("not implemented")
|
||||
panic("tespage: not implemented")
|
||||
}
|
||||
|
||||
func (p *testPage) File() source.File {
|
||||
@@ -216,15 +206,15 @@ func (p *testPage) File() source.File {
|
||||
}
|
||||
|
||||
func (p *testPage) FileInfo() hugofs.FileMetaInfo {
|
||||
panic("not implemented")
|
||||
panic("tespage: not implemented")
|
||||
}
|
||||
|
||||
func (p *testPage) Filename() string {
|
||||
panic("not implemented")
|
||||
panic("tespage: not implemented")
|
||||
}
|
||||
|
||||
func (p *testPage) FirstSection() Page {
|
||||
panic("not implemented")
|
||||
panic("tespage: not implemented")
|
||||
}
|
||||
|
||||
func (p *testPage) FuzzyWordCount(context.Context) int {
|
||||
@@ -232,19 +222,19 @@ func (p *testPage) FuzzyWordCount(context.Context) int {
|
||||
}
|
||||
|
||||
func (p *testPage) GetPage(ref string) (Page, error) {
|
||||
panic("not implemented")
|
||||
panic("tespage: not implemented")
|
||||
}
|
||||
|
||||
func (p *testPage) GetPageWithTemplateInfo(info tpl.Info, ref string) (Page, error) {
|
||||
panic("not implemented")
|
||||
panic("tespage: not implemented")
|
||||
}
|
||||
|
||||
func (p *testPage) GetParam(key string) any {
|
||||
panic("not implemented")
|
||||
panic("tespage: not implemented")
|
||||
}
|
||||
|
||||
func (p *testPage) GetTerms(taxonomy string) Pages {
|
||||
panic("not implemented")
|
||||
panic("tespage: not implemented")
|
||||
}
|
||||
|
||||
func (p *testPage) GetRelatedDocsHandler() *RelatedDocsHandler {
|
||||
@@ -260,27 +250,27 @@ func (p *testPage) CodeOwners() []string {
|
||||
}
|
||||
|
||||
func (p *testPage) HasMenuCurrent(menuID string, me *navigation.MenuEntry) bool {
|
||||
panic("not implemented")
|
||||
panic("tespage: not implemented")
|
||||
}
|
||||
|
||||
func (p *testPage) HasShortcode(name string) bool {
|
||||
panic("not implemented")
|
||||
panic("tespage: not implemented")
|
||||
}
|
||||
|
||||
func (p *testPage) Hugo() hugo.Info {
|
||||
panic("not implemented")
|
||||
func (p *testPage) Hugo() hugo.HugoInfo {
|
||||
panic("tespage: not implemented")
|
||||
}
|
||||
|
||||
func (p *testPage) InSection(other any) (bool, error) {
|
||||
panic("not implemented")
|
||||
panic("tespage: not implemented")
|
||||
}
|
||||
|
||||
func (p *testPage) IsAncestor(other any) (bool, error) {
|
||||
panic("not implemented")
|
||||
panic("tespage: not implemented")
|
||||
}
|
||||
|
||||
func (p *testPage) IsDescendant(other any) (bool, error) {
|
||||
panic("not implemented")
|
||||
panic("tespage: not implemented")
|
||||
}
|
||||
|
||||
func (p *testPage) IsDraft() bool {
|
||||
@@ -288,27 +278,27 @@ func (p *testPage) IsDraft() bool {
|
||||
}
|
||||
|
||||
func (p *testPage) IsHome() bool {
|
||||
panic("not implemented")
|
||||
panic("tespage: not implemented")
|
||||
}
|
||||
|
||||
func (p *testPage) IsMenuCurrent(menuID string, inme *navigation.MenuEntry) bool {
|
||||
panic("not implemented")
|
||||
panic("tespage: not implemented")
|
||||
}
|
||||
|
||||
func (p *testPage) IsNode() bool {
|
||||
panic("not implemented")
|
||||
panic("tespage: not implemented")
|
||||
}
|
||||
|
||||
func (p *testPage) IsPage() bool {
|
||||
panic("not implemented")
|
||||
panic("tespage: not implemented")
|
||||
}
|
||||
|
||||
func (p *testPage) IsSection() bool {
|
||||
panic("not implemented")
|
||||
panic("tespage: not implemented")
|
||||
}
|
||||
|
||||
func (p *testPage) IsTranslated() bool {
|
||||
panic("not implemented")
|
||||
panic("tespage: not implemented")
|
||||
}
|
||||
|
||||
func (p *testPage) Keywords() []string {
|
||||
@@ -324,7 +314,7 @@ func (p *testPage) Lang() string {
|
||||
}
|
||||
|
||||
func (p *testPage) Language() *langs.Language {
|
||||
panic("not implemented")
|
||||
panic("tespage: not implemented")
|
||||
}
|
||||
|
||||
func (p *testPage) LanguagePrefix() string {
|
||||
@@ -358,11 +348,11 @@ func (p *testPage) LinkTitle() string {
|
||||
}
|
||||
|
||||
func (p *testPage) LogicalName() string {
|
||||
panic("not implemented")
|
||||
panic("tespage: not implemented")
|
||||
}
|
||||
|
||||
func (p *testPage) MediaType() media.Type {
|
||||
panic("not implemented")
|
||||
panic("tespage: not implemented")
|
||||
}
|
||||
|
||||
func (p *testPage) Menus() navigation.PageMenus {
|
||||
@@ -370,11 +360,11 @@ func (p *testPage) Menus() navigation.PageMenus {
|
||||
}
|
||||
|
||||
func (p *testPage) Name() string {
|
||||
panic("not implemented")
|
||||
panic("tespage: not implemented")
|
||||
}
|
||||
|
||||
func (p *testPage) Next() Page {
|
||||
panic("not implemented")
|
||||
panic("tespage: not implemented")
|
||||
}
|
||||
|
||||
func (p *testPage) NextInSection() Page {
|
||||
@@ -386,19 +376,19 @@ func (p *testPage) NextPage() Page {
|
||||
}
|
||||
|
||||
func (p *testPage) OutputFormats() OutputFormats {
|
||||
panic("not implemented")
|
||||
panic("tespage: not implemented")
|
||||
}
|
||||
|
||||
func (p *testPage) Pages() Pages {
|
||||
panic("not implemented")
|
||||
panic("tespage: not implemented")
|
||||
}
|
||||
|
||||
func (p *testPage) RegularPages() Pages {
|
||||
panic("not implemented")
|
||||
panic("tespage: not implemented")
|
||||
}
|
||||
|
||||
func (p *testPage) RegularPagesRecursive() Pages {
|
||||
panic("not implemented")
|
||||
panic("tespage: not implemented")
|
||||
}
|
||||
|
||||
func (p *testPage) Paginate(seq any, options ...any) (*Pager, error) {
|
||||
@@ -422,11 +412,11 @@ func (p *testPage) Page() Page {
|
||||
}
|
||||
|
||||
func (p *testPage) Parent() Page {
|
||||
panic("not implemented")
|
||||
panic("tespage: not implemented")
|
||||
}
|
||||
|
||||
func (p *testPage) Ancestors() Pages {
|
||||
panic("not implemented")
|
||||
panic("tespage: not implemented")
|
||||
}
|
||||
|
||||
func (p *testPage) Path() string {
|
||||
@@ -438,19 +428,19 @@ func (p *testPage) Pathc() string {
|
||||
}
|
||||
|
||||
func (p *testPage) Permalink() string {
|
||||
panic("not implemented")
|
||||
panic("tespage: not implemented")
|
||||
}
|
||||
|
||||
func (p *testPage) Plain(context.Context) string {
|
||||
panic("not implemented")
|
||||
panic("tespage: not implemented")
|
||||
}
|
||||
|
||||
func (p *testPage) PlainWords(context.Context) []string {
|
||||
panic("not implemented")
|
||||
panic("tespage: not implemented")
|
||||
}
|
||||
|
||||
func (p *testPage) Prev() Page {
|
||||
panic("not implemented")
|
||||
panic("tespage: not implemented")
|
||||
}
|
||||
|
||||
func (p *testPage) PrevInSection() Page {
|
||||
@@ -470,15 +460,15 @@ func (p *testPage) RSSLink() template.URL {
|
||||
}
|
||||
|
||||
func (p *testPage) RawContent() string {
|
||||
panic("not implemented")
|
||||
panic("tespage: not implemented")
|
||||
}
|
||||
|
||||
func (p *testPage) ReadingTime(context.Context) int {
|
||||
panic("not implemented")
|
||||
panic("tespage: not implemented")
|
||||
}
|
||||
|
||||
func (p *testPage) Ref(argsm map[string]any) (string, error) {
|
||||
panic("not implemented")
|
||||
panic("tespage: not implemented")
|
||||
}
|
||||
|
||||
func (p *testPage) RefFrom(argsm map[string]any, source any) (string, error) {
|
||||
@@ -486,11 +476,11 @@ func (p *testPage) RefFrom(argsm map[string]any, source any) (string, error) {
|
||||
}
|
||||
|
||||
func (p *testPage) RelPermalink() string {
|
||||
panic("not implemented")
|
||||
panic("tespage: not implemented")
|
||||
}
|
||||
|
||||
func (p *testPage) RelRef(argsm map[string]any) (string, error) {
|
||||
panic("not implemented")
|
||||
panic("tespage: not implemented")
|
||||
}
|
||||
|
||||
func (p *testPage) RelRefFrom(argsm map[string]any, source any) (string, error) {
|
||||
@@ -498,27 +488,27 @@ func (p *testPage) RelRefFrom(argsm map[string]any, source any) (string, error)
|
||||
}
|
||||
|
||||
func (p *testPage) Render(ctx context.Context, layout ...string) (template.HTML, error) {
|
||||
panic("not implemented")
|
||||
panic("tespage: not implemented")
|
||||
}
|
||||
|
||||
func (p *testPage) RenderString(ctx context.Context, args ...any) (template.HTML, error) {
|
||||
panic("not implemented")
|
||||
panic("tespage: not implemented")
|
||||
}
|
||||
|
||||
func (p *testPage) ResourceType() string {
|
||||
panic("not implemented")
|
||||
panic("tespage: not implemented")
|
||||
}
|
||||
|
||||
func (p *testPage) Resources() resource.Resources {
|
||||
panic("not implemented")
|
||||
panic("tespage: not implemented")
|
||||
}
|
||||
|
||||
func (p *testPage) Scratch() *maps.Scratch {
|
||||
panic("not implemented")
|
||||
panic("tespage: not implemented")
|
||||
}
|
||||
|
||||
func (p *testPage) Store() *maps.Scratch {
|
||||
panic("not implemented")
|
||||
panic("tespage: not implemented")
|
||||
}
|
||||
|
||||
func (p *testPage) RelatedKeywords(cfg related.IndexConfig) ([]related.Keyword, error) {
|
||||
@@ -535,7 +525,7 @@ func (p *testPage) Section() string {
|
||||
}
|
||||
|
||||
func (p *testPage) Sections() Pages {
|
||||
panic("not implemented")
|
||||
panic("tespage: not implemented")
|
||||
}
|
||||
|
||||
func (p *testPage) SectionsEntries() []string {
|
||||
@@ -551,7 +541,7 @@ func (p *testPage) Site() Site {
|
||||
}
|
||||
|
||||
func (p *testPage) Sites() Sites {
|
||||
panic("not implemented")
|
||||
panic("tespage: not implemented")
|
||||
}
|
||||
|
||||
func (p *testPage) Slug() string {
|
||||
@@ -563,11 +553,11 @@ func (p *testPage) String() string {
|
||||
}
|
||||
|
||||
func (p *testPage) Summary(context.Context) template.HTML {
|
||||
panic("not implemented")
|
||||
panic("tespage: not implemented")
|
||||
}
|
||||
|
||||
func (p *testPage) TableOfContents(context.Context) template.HTML {
|
||||
panic("not implemented")
|
||||
panic("tespage: not implemented")
|
||||
}
|
||||
|
||||
func (p *testPage) Title() string {
|
||||
@@ -575,7 +565,7 @@ func (p *testPage) Title() string {
|
||||
}
|
||||
|
||||
func (p *testPage) TranslationBaseName() string {
|
||||
panic("not implemented")
|
||||
panic("tespage: not implemented")
|
||||
}
|
||||
|
||||
func (p *testPage) TranslationKey() string {
|
||||
@@ -583,11 +573,11 @@ func (p *testPage) TranslationKey() string {
|
||||
}
|
||||
|
||||
func (p *testPage) Translations() Pages {
|
||||
panic("not implemented")
|
||||
panic("tespage: not implemented")
|
||||
}
|
||||
|
||||
func (p *testPage) Truncated(context.Context) bool {
|
||||
panic("not implemented")
|
||||
panic("tespage: not implemented")
|
||||
}
|
||||
|
||||
func (p *testPage) Type() string {
|
||||
@@ -599,7 +589,7 @@ func (p *testPage) URL() string {
|
||||
}
|
||||
|
||||
func (p *testPage) UniqueID() string {
|
||||
panic("not implemented")
|
||||
panic("tespage: not implemented")
|
||||
}
|
||||
|
||||
func (p *testPage) Weight() int {
|
||||
@@ -607,11 +597,11 @@ func (p *testPage) Weight() int {
|
||||
}
|
||||
|
||||
func (p *testPage) WordCount(context.Context) int {
|
||||
panic("not implemented")
|
||||
panic("tespage: not implemented")
|
||||
}
|
||||
|
||||
func (p *testPage) GetIdentity() identity.Identity {
|
||||
panic("not implemented")
|
||||
panic("tespage: not implemented")
|
||||
}
|
||||
|
||||
func createTestPages(num int) Pages {
|
||||
|
Reference in New Issue
Block a user