func (s *TemplateStore) LookupPartial(pth string) *TemplInfo {
ti, _ := s.cacheLookupPartials.GetOrCreate(pth, func() (*TemplInfo, error) {
- d := s.templateDescriptorFromPath(pth)
- desc := d.Desc
- if desc.LayoutFromTemplate != "" {
- panic("shortcode template descriptor must not have a layout")
+ pi := s.opts.PathParser.Parse(files.ComponentFolderLayouts, pth).ForType(paths.TypePartial)
+ k1, _, _, desc, err := s.toKeyCategoryAndDescriptor(pi)
+ if err != nil {
+ return nil, err
+ }
+ if desc.OutputFormat == "" && desc.MediaType == "" {
+ // Assume HTML.
+ desc.OutputFormat = s.htmlFormat.Name
+ desc.MediaType = s.htmlFormat.MediaType.Type
+ desc.IsPlainText = s.htmlFormat.IsPlainText
}
+
best := s.getBest()
defer s.putBest(best)
- s.findBestMatchGet(s.key(path.Join(containerPartials, d.Path)), CategoryPartial, nil, desc, best)
+ s.findBestMatchGet(s.key(path.Join(containerPartials, k1)), CategoryPartial, nil, desc, best)
return best.templ, nil
})
Desc TemplateDescriptor
}
-// templateDescriptorFromPath returns a template descriptor from the given path.
-// This is currently used in partial lookups only.
-func (s *TemplateStore) templateDescriptorFromPath(pth string) PathTemplateDescriptor {
- var (
- mt media.Type
- of output.Format
- )
-
- // Common cases.
- dotCount := strings.Count(pth, ".")
- if dotCount <= 1 {
- if dotCount == 0 {
- // Asume HTML.
- of, mt = s.resolveOutputFormatAndOrMediaType("html", "")
- } else {
- pth = strings.TrimPrefix(pth, "/")
- ext := path.Ext(pth)
- pth = strings.TrimSuffix(pth, ext)
- ext = ext[1:]
- of, mt = s.resolveOutputFormatAndOrMediaType("", ext)
- }
- } else {
- path := s.opts.PathParser.Parse(files.ComponentFolderLayouts, pth)
- pth = path.PathNoIdentifier()
- of, mt = s.resolveOutputFormatAndOrMediaType(path.OutputFormat(), path.Ext())
- }
-
- return PathTemplateDescriptor{
- Path: pth,
- Desc: TemplateDescriptor{
- OutputFormat: of.Name,
- MediaType: mt.Type,
- IsPlainText: of.IsPlainText,
- },
- }
-}
-
// resolveOutputFormatAndOrMediaType resolves the output format and/or media type
// based on the given output format suffix and media type suffix.
// Either of the suffixes can be empty, and the function will try to find a match
// Just make sure it doesn't fail.
hugolib.Test(t, files)
}
+
+func TestPartialsLangIssue13612(t *testing.T) {
+ t.Parallel()
+
+ files := `
+-- hugo.toml --
+disableKinds = ['page','section','sitemap','taxonomy','term']
+
+defaultContentLanguage = 'ru'
+defaultContentLanguageInSubdir = true
+
+[languages.ru]
+weight = 1
+
+[languages.en]
+weight = 2
+
+[outputs]
+home = ['html','rss']
+
+-- layouts/_partials/comment.en.html --
+layouts/_partials/comment.en.html
+-- layouts/_partials/comment.en.xml --
+layouts/_partials/comment.en.xml
+-- layouts/_partials/comment.ru.html --
+layouts/_partials/comment.ru.html
+-- layouts/_partials/comment.ru.xml --
+layouts/_partials/comment.ru.xml
+-- layouts/home.html --
+{{ partial (print "comment." (default "ru" .Lang) ".html") . }}
+-- layouts/home.rss.xml --
+{{ partial (print "comment." (default "ru" .Lang) ".xml") . }}
+`
+
+ b := hugolib.Test(t, files)
+
+ b.AssertFileContent("public/en/index.html", "layouts/_partials/comment.en.html")
+ b.AssertFileContent("public/en/index.xml", "layouts/_partials/comment.en.xml") // fail
+ b.AssertFileContent("public/ru/index.html", "layouts/_partials/comment.ru.html") // fail
+ b.AssertFileContent("public/ru/index.xml", "layouts/_partials/comment.ru.xml") // fail
+}