]> git.maquefel.me Git - brevno-suite/hugo/commitdiff
tpl/tplimpl: Prefer early suffixes when media type matches
authorBjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com>
Sun, 8 Mar 2026 12:38:38 +0000 (13:38 +0100)
committerBjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com>
Sun, 8 Mar 2026 20:42:36 +0000 (21:42 +0100)
Fixes #13877
Close #14601

Co-Authored-By: Joe Mooring <joe.mooring@veriphor.com>
hugolib/template_test.go
tpl/tplimpl/templatestore.go

index 1a03a41e5750d78adf8d373c78d2786c49e3d890..90b8a575af67366348b6a6f762415b0b7b6abb57 100644 (file)
@@ -644,3 +644,35 @@ Overridden.
 
        b.AssertFileContent("public/index.html", "Overridden.")
 }
+
+// Issue 13877
+func TestTemplateSelectionFirstMediaTypeSuffix(t *testing.T) {
+       t.Parallel()
+
+       files := `
+-- hugo.toml --
+disableKinds = ['home','rss','section','sitemap','taxonomy','term']
+
+[mediaTypes.'text/html']
+suffixes = ['b','a','d','c']
+
+[outputFormats.html]
+mediaType = 'text/html'
+-- content/p1.md --
+---
+title: p1
+---
+-- layouts/page.html.a --
+page.html.a
+-- layouts/page.html.b --
+page.html.b
+-- layouts/page.html.c --
+page.html.c
+-- layouts/page.html.d --
+page.html.d
+`
+
+       b := Test(t, files)
+
+       b.AssertFileContent("public/p1/index.b", "page.html.b")
+}
index 1d4e537fda670439336dda09adf33e233e7cb3ed..57a0c4f69904f7cab0e67803183b298c16b55ff2 100644 (file)
@@ -29,6 +29,7 @@ import (
        "path/filepath"
        "reflect"
        "regexp"
+       "slices"
        "sort"
        "strings"
        "sync"
@@ -1271,8 +1272,25 @@ func (s *TemplateStore) insertTemplate2(
 
        if !replace && existingFound {
                if len(pi.Identifiers()) >= len(nkExisting.PathInfo.Identifiers()) {
-                       // e.g. /pages/home.foo.html and  /pages/home.html where foo may be a valid language name in another site.
-                       return nil, nil
+                       if d.MediaType != "" && pi.Ext() != nkExisting.PathInfo.Ext() {
+                               // Issue #13877: when multiple templates differ only in their file extension
+                               // and both extensions are valid suffixes for the same media type,
+                               // prefer the one whose extension matches an earlier suffix.
+                               if mt, ok := s.opts.MediaTypes.GetByType(d.MediaType); ok {
+                                       suffixes := mt.Suffixes()
+                                       newIdx := slices.Index(suffixes, pi.Ext())
+                                       if newIdx != -1 {
+                                               existingIdx := slices.Index(suffixes, nkExisting.PathInfo.Ext())
+                                               if existingIdx == -1 || newIdx < existingIdx {
+                                                       replace = true
+                                               }
+                                       }
+                               }
+                       }
+                       if !replace {
+                               // e.g. /pages/home.foo.html and  /pages/home.html where foo may be a valid language name in another site.
+                               return nil, nil
+                       }
                }
        }