mirror of
https://github.com/gohugoio/hugo.git
synced 2025-08-16 20:53:59 +02:00
@@ -214,3 +214,18 @@ All.
|
|||||||
b.AssertFileContent("public/index.html", "All.")
|
b.AssertFileContent("public/index.html", "All.")
|
||||||
b.AssertFileContent("public/amp/index.html", "All.")
|
b.AssertFileContent("public/amp/index.html", "All.")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Issue #13584.
|
||||||
|
func TestLegacySectionSection(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
files := `
|
||||||
|
-- hugo.toml --
|
||||||
|
-- content/mysection/_index.md --
|
||||||
|
-- layouts/section/section.html --
|
||||||
|
layouts/section/section.html
|
||||||
|
|
||||||
|
`
|
||||||
|
b := hugolib.Test(t, files)
|
||||||
|
b.AssertFileContent("public/mysection/index.html", "layouts/section/section.html")
|
||||||
|
}
|
||||||
|
@@ -3,7 +3,9 @@ package tplimpl
|
|||||||
import (
|
import (
|
||||||
"io"
|
"io"
|
||||||
"regexp"
|
"regexp"
|
||||||
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
"sync/atomic"
|
||||||
"unicode"
|
"unicode"
|
||||||
"unicode/utf8"
|
"unicode/utf8"
|
||||||
|
|
||||||
@@ -49,11 +51,6 @@ func (t *templateNamespace) parseTemplate(ti *TemplInfo) error {
|
|||||||
}
|
}
|
||||||
pi := ti.PathInfo
|
pi := ti.PathInfo
|
||||||
name := pi.PathNoLeadingSlash()
|
name := pi.PathNoLeadingSlash()
|
||||||
if ti.isLegacyMapped {
|
|
||||||
// When mapping the old taxonomy structure to the new one, we may map the same path to multiple templates per kind.
|
|
||||||
// Append the kind here to make the name unique.
|
|
||||||
name += ("-" + ti.D.Kind)
|
|
||||||
}
|
|
||||||
|
|
||||||
var (
|
var (
|
||||||
templ tpl.Template
|
templ tpl.Template
|
||||||
@@ -62,12 +59,18 @@ func (t *templateNamespace) parseTemplate(ti *TemplInfo) error {
|
|||||||
|
|
||||||
if ti.D.IsPlainText {
|
if ti.D.IsPlainText {
|
||||||
prototype := t.parseText
|
prototype := t.parseText
|
||||||
|
if prototype.Lookup(name) != nil {
|
||||||
|
name += "-" + strconv.FormatUint(t.nameCounter.Add(1), 10)
|
||||||
|
}
|
||||||
templ, err = prototype.New(name).Parse(ti.content)
|
templ, err = prototype.New(name).Parse(ti.content)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
prototype := t.parseHTML
|
prototype := t.parseHTML
|
||||||
|
if prototype.Lookup(name) != nil {
|
||||||
|
name += "-" + strconv.FormatUint(t.nameCounter.Add(1), 10)
|
||||||
|
}
|
||||||
templ, err = prototype.New(name).Parse(ti.content)
|
templ, err = prototype.New(name).Parse(ti.content)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@@ -296,6 +299,8 @@ type templateNamespace struct {
|
|||||||
prototypeText *texttemplate.Template
|
prototypeText *texttemplate.Template
|
||||||
prototypeHTML *htmltemplate.Template
|
prototypeHTML *htmltemplate.Template
|
||||||
|
|
||||||
|
nameCounter atomic.Uint64
|
||||||
|
|
||||||
standaloneText *texttemplate.Template
|
standaloneText *texttemplate.Template
|
||||||
|
|
||||||
baseofTextClones []*texttemplate.Template
|
baseofTextClones []*texttemplate.Template
|
||||||
|
@@ -690,7 +690,7 @@ func (t *TemplateStore) UnusedTemplates() []*TemplInfo {
|
|||||||
var unused []*TemplInfo
|
var unused []*TemplInfo
|
||||||
|
|
||||||
for vv := range t.templates() {
|
for vv := range t.templates() {
|
||||||
if vv.subCategory != SubCategoryMain {
|
if vv.subCategory != SubCategoryMain || vv.isLegacyMapped {
|
||||||
// Skip inline partials and internal templates.
|
// Skip inline partials and internal templates.
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
@@ -1169,8 +1169,8 @@ func (s *TemplateStore) insertTemplates(include func(fi hugofs.FileMetaInfo) boo
|
|||||||
case containerPartials, containerShortcodes, containerMarkup:
|
case containerPartials, containerShortcodes, containerMarkup:
|
||||||
// OK.
|
// OK.
|
||||||
default:
|
default:
|
||||||
applyLegacyMapping = true
|
|
||||||
pi = fromLegacyPath(pi)
|
pi = fromLegacyPath(pi)
|
||||||
|
applyLegacyMapping = strings.Count(pi.Path(), "/") <= 2
|
||||||
}
|
}
|
||||||
|
|
||||||
if applyLegacyMapping {
|
if applyLegacyMapping {
|
||||||
@@ -1183,6 +1183,7 @@ func (s *TemplateStore) insertTemplates(include func(fi hugofs.FileMetaInfo) boo
|
|||||||
ext: pi.Ext(),
|
ext: pi.Ext(),
|
||||||
outputFormat: pi.OutputFormat(),
|
outputFormat: pi.OutputFormat(),
|
||||||
}
|
}
|
||||||
|
|
||||||
if m2, ok := legacyOrdinalMappings[key]; ok {
|
if m2, ok := legacyOrdinalMappings[key]; ok {
|
||||||
if m1.ordinal < m2.m.ordinal {
|
if m1.ordinal < m2.m.ordinal {
|
||||||
// Higher up == better match.
|
// Higher up == better match.
|
||||||
@@ -1208,26 +1209,74 @@ func (s *TemplateStore) insertTemplates(include func(fi hugofs.FileMetaInfo) boo
|
|||||||
|
|
||||||
base := piOrig.PathBeforeLangAndOutputFormatAndExt()
|
base := piOrig.PathBeforeLangAndOutputFormatAndExt()
|
||||||
identifiers := pi.IdentifiersUnknown()
|
identifiers := pi.IdentifiersUnknown()
|
||||||
|
if pi.Kind() != "" {
|
||||||
// Tokens on e.g. form /SECTIONKIND/THESECTION
|
identifiers = append(identifiers, pi.Kind())
|
||||||
insertSectionTokens := func(section string, kindOnly bool) string {
|
|
||||||
s := base
|
|
||||||
if !kindOnly {
|
|
||||||
s = strings.Replace(s, section, sectionToken, 1)
|
|
||||||
}
|
|
||||||
s = strings.Replace(s, kinds.KindSection, sectionKindToken, 1)
|
|
||||||
return s
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, section := range identifiers {
|
shouldIncludeSection := func(section string) bool {
|
||||||
if section == baseNameBaseof {
|
switch section {
|
||||||
|
case containerShortcodes, containerPartials, containerMarkup:
|
||||||
|
return false
|
||||||
|
case "taxonomy", "":
|
||||||
|
return false
|
||||||
|
default:
|
||||||
|
for k, v := range s.opts.TaxonomySingularPlural {
|
||||||
|
if k == section || v == section {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if shouldIncludeSection(pi.Section()) {
|
||||||
|
identifiers = append(identifiers, pi.Section())
|
||||||
|
}
|
||||||
|
|
||||||
|
identifiers = helpers.UniqueStrings(identifiers)
|
||||||
|
|
||||||
|
// Tokens on e.g. form /SECTIONKIND/THESECTION
|
||||||
|
insertSectionTokens := func(section string) []string {
|
||||||
|
kindOnly := isLayoutStandard(section)
|
||||||
|
var ss []string
|
||||||
|
s1 := base
|
||||||
|
if !kindOnly {
|
||||||
|
s1 = strings.ReplaceAll(s1, section, sectionToken)
|
||||||
|
}
|
||||||
|
s1 = strings.ReplaceAll(s1, kinds.KindSection, sectionKindToken)
|
||||||
|
if s1 != base {
|
||||||
|
ss = append(ss, s1)
|
||||||
|
}
|
||||||
|
s1 = strings.ReplaceAll(base, kinds.KindSection, sectionKindToken)
|
||||||
|
if !kindOnly {
|
||||||
|
s1 = strings.ReplaceAll(s1, section, sectionToken)
|
||||||
|
}
|
||||||
|
if s1 != base {
|
||||||
|
ss = append(ss, s1)
|
||||||
|
}
|
||||||
|
|
||||||
|
helpers.UniqueStringsReuse(ss)
|
||||||
|
|
||||||
|
return ss
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, id := range identifiers {
|
||||||
|
if id == "" {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
kindOnly := isLayoutStandard(section)
|
|
||||||
p := insertSectionTokens(section, kindOnly)
|
p := insertSectionTokens(id)
|
||||||
if m1, ok := s.opts.legacyMappingSection[p]; ok {
|
for _, ss := range p {
|
||||||
m1.mapping.targetPath = strings.Replace(m1.mapping.targetPath, sectionToken, section, 1)
|
if m1, ok := s.opts.legacyMappingSection[ss]; ok {
|
||||||
handleMapping(m1)
|
targetPath := m1.mapping.targetPath
|
||||||
|
|
||||||
|
if targetPath != "" {
|
||||||
|
targetPath = strings.ReplaceAll(targetPath, sectionToken, id)
|
||||||
|
targetPath = strings.ReplaceAll(targetPath, sectionKindToken, id)
|
||||||
|
targetPath = strings.ReplaceAll(targetPath, "//", "/")
|
||||||
|
}
|
||||||
|
m1.mapping.targetPath = targetPath
|
||||||
|
handleMapping(m1)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -441,7 +441,7 @@ title: "P1"
|
|||||||
{{ define "main" }}FOO{{ end }}
|
{{ define "main" }}FOO{{ end }}
|
||||||
-- layouts/_default/single.json --
|
-- layouts/_default/single.json --
|
||||||
-- layouts/_default/single.html --
|
-- layouts/_default/single.html --
|
||||||
{{ define "main" }}MAIN{{ end }}
|
{{ define "main" }}MAIN /_default/single.html{{ end }}
|
||||||
-- layouts/post/single.html --
|
-- layouts/post/single.html --
|
||||||
{{ define "main" }}MAIN{{ end }}
|
{{ define "main" }}MAIN{{ end }}
|
||||||
-- layouts/_partials/usedpartial.html --
|
-- layouts/_partials/usedpartial.html --
|
||||||
@@ -461,6 +461,8 @@ title: "P1"
|
|||||||
)
|
)
|
||||||
b.Build()
|
b.Build()
|
||||||
|
|
||||||
|
b.AssertFileContent("public/p1/index.html", "MAIN /_default/single.html")
|
||||||
|
|
||||||
unused := b.H.GetTemplateStore().UnusedTemplates()
|
unused := b.H.GetTemplateStore().UnusedTemplates()
|
||||||
var names []string
|
var names []string
|
||||||
for _, tmpl := range unused {
|
for _, tmpl := range unused {
|
||||||
@@ -468,8 +470,9 @@ title: "P1"
|
|||||||
names = append(names, fi.Meta().PathInfo.PathNoLeadingSlash())
|
names = append(names, fi.Meta().PathInfo.PathNoLeadingSlash())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
b.Assert(len(unused), qt.Equals, 5, qt.Commentf("%#v", names))
|
|
||||||
b.Assert(names, qt.DeepEquals, []string{"_partials/unusedpartial.html", "shortcodes/unusedshortcode.html", "baseof.json", "post/single.html", "_default/single.json"})
|
b.Assert(names, qt.DeepEquals, []string{"_partials/unusedpartial.html", "shortcodes/unusedshortcode.html", "baseof.json", "post/single.html", "_default/single.json"})
|
||||||
|
b.Assert(len(unused), qt.Equals, 5, qt.Commentf("%#v", names))
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestCreateManyTemplateStores(t *testing.T) {
|
func TestCreateManyTemplateStores(t *testing.T) {
|
||||||
|
Reference in New Issue
Block a user