return weightNoMatch
}
- w := this.doCompare(category, isEmbedded, other)
+ w := this.doCompare(category, isEmbedded, s.opts.DefaultContentLanguage, other)
if w.w1 <= 0 {
if category == CategoryMarkup && (this.Variant1 == other.Variant1) && (this.Variant2 == other.Variant2 || this.Variant2 != "" && other.Variant2 == "") {
}
//lint:ignore ST1006 this vs other makes it easier to reason about.
-func (this TemplateDescriptor) doCompare(category Category, isEmbedded bool, other TemplateDescriptor) weight {
+func (this TemplateDescriptor) doCompare(category Category, isEmbedded bool, defaultContentLanguage string, other TemplateDescriptor) weight {
w := weightNoMatch
// HTML in plain text is OK, but not the other way around.
// Continue.
}
+ if other.MediaType != this.MediaType {
+ return w
+ }
+
// One example of variant1 and 2 is for render codeblocks:
// variant1=codeblock, variant2=go (language).
if other.Variant1 != "" && other.Variant1 != this.Variant1 {
}
const (
- weightKind = 3 // page, home, section, taxonomy, term (and only those)
- weightcustomLayout = 4 // custom layout (mylayout, set in e.g. front matter)
- weightLayoutStandard = 2 // standard layouts (single,list,all)
- weightOutputFormat = 2 // a configured output format (e.g. rss, html, json)
+ weightKind = 5 // page, home, section, taxonomy, term (and only those)
+ weightcustomLayout = 6 // custom layout (mylayout, set in e.g. front matter)
+ weightLayoutStandard = 4 // standard layouts (single,list)
+ weightLayoutAll = 2 // the "all" layout
+ weightOutputFormat = 4 // a configured output format (e.g. rss, html, json)
weightMediaType = 1 // a configured media type (e.g. text/html, text/plain)
weightLang = 1 // a configured language (e.g. en, nn, fr, ...)
- weightVariant1 = 4 // currently used for render hooks, e.g. "link", "image"
- weightVariant2 = 2 // currently used for render hooks, e.g. the language "go" in code blocks.
+ weightVariant1 = 6 // currently used for render hooks, e.g. "link", "image"
+ weightVariant2 = 4 // currently used for render hooks, e.g. the language "go" in code blocks.
// We will use the values for group 2 and 3
// if the distance up to the template is shorter than
w.w2 = weight2Group1
}
- if other.LayoutFromTemplate != "" && (other.LayoutFromTemplate == this.LayoutFromTemplate || other.LayoutFromTemplate == layoutAll) {
+ if other.LayoutFromTemplate != "" && (other.LayoutFromTemplate == this.LayoutFromTemplate) {
w.w1 += weightLayoutStandard
w.w2 = weight2Group1
-
+ } else if other.LayoutFromTemplate == layoutAll {
+ w.w1 += weightLayoutAll
+ w.w2 = weight2Group1
}
// LayoutCustom is only set in this (usually from Page.Layout).
w.w2 = weight2Group2
}
- if other.Lang != "" && other.Lang == this.Lang {
+ if (other.Lang != "" && other.Lang == this.Lang) || (other.Lang == "" && this.Lang == defaultContentLanguage) {
w.w1 += weightLang
w.w3 += weight3
}
import (
"context"
"io"
+ "strings"
"testing"
qt "github.com/frankban/quicktest"
b.AssertFileContent("public/en/foo/index.xml", "layouts/list.xml")
}
+func TestLookupOrderIssue13636(t *testing.T) {
+ t.Parallel()
+
+ filesTemplate := `
+-- hugo.toml --
+defaultContentLanguage = "en"
+defaultContentLanguageInSubdir = true
+[languages]
+[languages.en]
+weight = 1
+[languages.nn]
+weight = 2
+-- content/s1/p1.en.md --
+---
+outputs: ["html", "amp", "json"]
+---
+-- content/s1/p1.nn.md --
+---
+outputs: ["html", "amp", "json"]
+---
+-- layouts/L1 --
+L1
+-- layouts/L2 --
+L2
+-- layouts/L3 --
+L3
+
+`
+
+ tests := []struct {
+ Lang string
+ L1 string
+ L2 string
+ L3 string
+ ExpectHTML string
+ ExpectAmp string
+ ExpectJSON string
+ }{
+ {"en", "all.en.html", "all.html", "single.html", "single.html", "single.html", ""},
+ {"en", "all.amp.html", "all.html", "page.html", "page.html", "all.amp.html", ""},
+ {"en", "all.amp.html", "all.html", "list.html", "all.html", "all.amp.html", ""},
+ {"en", "all.en.html", "all.json", "single.html", "single.html", "single.html", "all.json"},
+ {"en", "all.en.html", "single.json", "single.html", "single.html", "single.html", "single.json"},
+ {"en", "all.en.html", "all.html", "list.html", "all.en.html", "all.en.html", ""},
+ {"en", "list.en.html", "list.html", "list.en.html", "", "", ""},
+ {"nn", "all.en.html", "all.html", "single.html", "single.html", "single.html", ""},
+ {"nn", "all.en.html", "all.nn.html", "single.html", "single.html", "single.html", ""},
+ {"nn", "all.en.html", "all.nn.html", "single.nn.html", "single.nn.html", "single.nn.html", ""},
+ {"nn", "single.json", "single.nn.json", "all.json", "", "", "single.nn.json"},
+ {"nn", "single.json", "single.en.json", "all.nn.json", "", "", "single.json"},
+ }
+
+ for i, test := range tests {
+ if i != 8 {
+ // continue
+ }
+ files := strings.ReplaceAll(filesTemplate, "L1", test.L1)
+ files = strings.ReplaceAll(files, "L2", test.L2)
+ files = strings.ReplaceAll(files, "L3", test.L3)
+ t.Logf("Test %d: %s %s %s %s", i, test.Lang, test.L1, test.L2, test.L3)
+
+ for range 3 {
+ b := hugolib.Test(t, files)
+ b.Assert(len(b.H.Sites), qt.Equals, 2)
+
+ var (
+ pubhHTML = "public/LANG/s1/p1/index.html"
+ pubhAmp = "public/LANG/amp/s1/p1/index.html"
+ pubhJSON = "public/LANG/s1/p1/index.json"
+ )
+
+ pubhHTML = strings.ReplaceAll(pubhHTML, "LANG", test.Lang)
+ pubhAmp = strings.ReplaceAll(pubhAmp, "LANG", test.Lang)
+ pubhJSON = strings.ReplaceAll(pubhJSON, "LANG", test.Lang)
+
+ if test.ExpectHTML != "" {
+ b.AssertFileContent(pubhHTML, test.ExpectHTML)
+ } else {
+ b.AssertFileExists(pubhHTML, false)
+ }
+
+ if test.ExpectAmp != "" {
+ b.AssertFileContent(pubhAmp, test.ExpectAmp)
+ } else {
+ b.AssertFileExists(pubhAmp, false)
+ }
+
+ if test.ExpectJSON != "" {
+ b.AssertFileContent(pubhJSON, test.ExpectJSON)
+ } else {
+ b.AssertFileExists(pubhJSON, false)
+ }
+ }
+ }
+}
+
func TestLookupShortcodeDepth(t *testing.T) {
t.Parallel()