import (
"io"
"regexp"
+ "strconv"
"strings"
+ "sync/atomic"
"unicode"
"unicode/utf8"
}
pi := ti.PathInfo
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 (
templ tpl.Template
if ti.D.IsPlainText {
prototype := t.parseText
+ if prototype.Lookup(name) != nil {
+ name += "-" + strconv.FormatUint(t.nameCounter.Add(1), 10)
+ }
templ, err = prototype.New(name).Parse(ti.content)
if err != nil {
return err
}
} else {
prototype := t.parseHTML
+ if prototype.Lookup(name) != nil {
+ name += "-" + strconv.FormatUint(t.nameCounter.Add(1), 10)
+ }
templ, err = prototype.New(name).Parse(ti.content)
if err != nil {
return err
prototypeText *texttemplate.Template
prototypeHTML *htmltemplate.Template
+ nameCounter atomic.Uint64
+
standaloneText *texttemplate.Template
baseofTextClones []*texttemplate.Template
var unused []*TemplInfo
for vv := range t.templates() {
- if vv.subCategory != SubCategoryMain {
+ if vv.subCategory != SubCategoryMain || vv.isLegacyMapped {
// Skip inline partials and internal templates.
continue
}
case containerPartials, containerShortcodes, containerMarkup:
// OK.
default:
- applyLegacyMapping = true
pi = fromLegacyPath(pi)
+ applyLegacyMapping = strings.Count(pi.Path(), "/") <= 2
}
if applyLegacyMapping {
ext: pi.Ext(),
outputFormat: pi.OutputFormat(),
}
+
if m2, ok := legacyOrdinalMappings[key]; ok {
if m1.ordinal < m2.m.ordinal {
// Higher up == better match.
base := piOrig.PathBeforeLangAndOutputFormatAndExt()
identifiers := pi.IdentifiersUnknown()
+ if pi.Kind() != "" {
+ identifiers = append(identifiers, pi.Kind())
+ }
+
+ shouldIncludeSection := func(section string) bool {
+ 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, kindOnly bool) string {
- s := base
+ 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 {
- s = strings.Replace(s, section, sectionToken, 1)
+ s1 = strings.ReplaceAll(s1, section, sectionToken)
+ }
+ if s1 != base {
+ ss = append(ss, s1)
}
- s = strings.Replace(s, kinds.KindSection, sectionKindToken, 1)
- return s
+
+ helpers.UniqueStringsReuse(ss)
+
+ return ss
}
- for _, section := range identifiers {
- if section == baseNameBaseof {
+ for _, id := range identifiers {
+ if id == "" {
continue
}
- kindOnly := isLayoutStandard(section)
- p := insertSectionTokens(section, kindOnly)
- if m1, ok := s.opts.legacyMappingSection[p]; ok {
- m1.mapping.targetPath = strings.Replace(m1.mapping.targetPath, sectionToken, section, 1)
- handleMapping(m1)
+
+ p := insertSectionTokens(id)
+ for _, ss := range p {
+ if m1, ok := s.opts.legacyMappingSection[ss]; ok {
+ 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)
+ }
}
}
{{ define "main" }}FOO{{ end }}
-- layouts/_default/single.json --
-- layouts/_default/single.html --
-{{ define "main" }}MAIN{{ end }}
+{{ define "main" }}MAIN /_default/single.html{{ end }}
-- layouts/post/single.html --
{{ define "main" }}MAIN{{ end }}
-- layouts/_partials/usedpartial.html --
)
b.Build()
+ b.AssertFileContent("public/p1/index.html", "MAIN /_default/single.html")
+
unused := b.H.GetTemplateStore().UnusedTemplates()
var names []string
for _, tmpl := range unused {
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(len(unused), qt.Equals, 5, qt.Commentf("%#v", names))
}
func TestCreateManyTemplateStores(t *testing.T) {