shithub: hugo

Download patch

ref: 40ffb0484b96b7b77fb66202b33073b241807199
parent: 4bae8b04aadd72d298bf2dd1bb1430806bf2869c
author: Bjørn Erik Pedersen <[email protected]>
date: Sat Dec 29 05:35:46 EST 2018

hugolib: Restore 0.48 slash handling in taxonomies

Fixes #5571

--- a/hugolib/hugo_sites.go
+++ b/hugolib/hugo_sites.go
@@ -548,7 +548,7 @@
 				if s.isEnabled(KindTaxonomyTerm) {
 					foundTaxonomyTermsPage := false
 					for _, p := range taxonomyTermsPages {
-						if p.sections[0] == plural {
+						if p.sectionsPath() == plural {
 							foundTaxonomyTermsPage = true
 							break
 						}
@@ -570,11 +570,21 @@
 							key = s.PathSpec.MakePathSanitized(key)
 						}
 						for _, p := range taxonomyPages {
+							sectionsPath := p.sectionsPath()
+
+							if !strings.HasPrefix(sectionsPath, plural) {
+								continue
+							}
+
+							singularKey := strings.TrimPrefix(sectionsPath, plural)
+							singularKey = strings.TrimPrefix(singularKey, "/")
+
 							// Some people may have /authors/MaxMustermann etc. as paths.
 							// p.sections contains the raw values from the file system.
 							// See https://github.com/gohugoio/hugo/issues/4238
-							singularKey := s.PathSpec.MakePathSanitized(p.sections[1])
-							if p.sections[0] == plural && singularKey == key {
+							singularKey = s.PathSpec.MakePathSanitized(singularKey)
+
+							if singularKey == key {
 								foundTaxonomyPage = true
 								break
 							}
@@ -622,7 +632,7 @@
 	for _, s := range h.Sites {
 		for _, p := range s.rawAllPages {
 			if p.Kind == kindUnknown {
-				p.Kind = p.s.kindFromSections(p.sections)
+				p.Kind = p.kindFromSections()
 			}
 
 			if !p.s.isEnabled(p.Kind) {
--- a/hugolib/hugo_sites_build_test.go
+++ b/hugolib/hugo_sites_build_test.go
@@ -100,8 +100,8 @@
 	// Check list pages
 	b.AssertFileContent(pathMod("public/fr/sect/index.html"), "List", "Bonjour")
 	b.AssertFileContent("public/en/sect/index.html", "List", "Hello")
-	b.AssertFileContent(pathMod("public/fr/plaques/frtag1/index.html"), "List", "Bonjour")
-	b.AssertFileContent("public/en/tags/tag1/index.html", "List", "Hello")
+	b.AssertFileContent(pathMod("public/fr/plaques/frtag1/index.html"), "Taxonomy List", "Bonjour")
+	b.AssertFileContent("public/en/tags/tag1/index.html", "Taxonomy List", "Hello")
 
 	// Check sitemaps
 	// Sitemaps behaves different: In a multilanguage setup there will always be a index file and
--- a/hugolib/page.go
+++ b/hugolib/page.go
@@ -2048,10 +2048,41 @@
 	return KindPage
 }
 
+func (p *Page) sectionsPath() string {
+	if len(p.sections) == 0 {
+		return ""
+	}
+	if len(p.sections) == 1 {
+		return p.sections[0]
+	}
+
+	return path.Join(p.sections...)
+}
+
+func (p *Page) kindFromSections() string {
+	if len(p.sections) == 0 || len(p.s.Taxonomies) == 0 {
+		return KindSection
+	}
+
+	sectionPath := p.sectionsPath()
+
+	for k, _ := range p.s.Taxonomies {
+		if k == sectionPath {
+			return KindTaxonomyTerm
+		}
+
+		if strings.HasPrefix(sectionPath, k) {
+			return KindTaxonomy
+		}
+	}
+
+	return KindSection
+}
+
 func (p *Page) setValuesForKind(s *Site) {
 	if p.Kind == kindUnknown {
 		// This is either a taxonomy list, taxonomy term or a section
-		nodeType := s.kindFromSections(p.sections)
+		nodeType := p.kindFromSections()
 
 		if nodeType == kindUnknown {
 			panic(fmt.Sprintf("Unable to determine page kind from %q", p.sections))
--- a/hugolib/permalinks.go
+++ b/hugolib/permalinks.go
@@ -40,7 +40,7 @@
 // to be used to replace that tag.
 var knownPermalinkAttributes map[string]pageToPermaAttribute
 
-var attributeRegexp *regexp.Regexp
+var attributeRegexp = regexp.MustCompile(`:\w+`)
 
 // validate determines if a PathPattern is well-formed
 func (pp pathPattern) validate() bool {
@@ -187,8 +187,7 @@
 }
 
 func pageToPermalinkSection(p *Page, _ string) (string, error) {
-	// Page contains Node contains URLPath which has Section
-	return p.s.PathSpec.URLize(p.Section()), nil
+	return p.Section(), nil
 }
 
 func pageToPermalinkSections(p *Page, _ string) (string, error) {
@@ -211,5 +210,4 @@
 		"filename":    pageToPermalinkFilename,
 	}
 
-	attributeRegexp = regexp.MustCompile(`:\w+`)
 }
--- a/hugolib/permalinks_test.go
+++ b/hugolib/permalinks_test.go
@@ -14,6 +14,7 @@
 package hugolib
 
 import (
+	"path/filepath"
 	"strings"
 	"testing"
 )
@@ -62,7 +63,7 @@
 func TestPermalinkExpansion(t *testing.T) {
 	t.Parallel()
 	s := newTestSite(t)
-	page, err := s.newPageFrom(strings.NewReader(simplePageJSON), "blue/test-page.md")
+	page, err := s.newPageFrom(strings.NewReader(simplePageJSON), filepath.FromSlash("blue/test-page.md"))
 
 	if err != nil {
 		t.Fatalf("failed before we began, could not parse simplePageJSON: %s", err)
--- a/hugolib/site.go
+++ b/hugolib/site.go
@@ -1586,20 +1586,6 @@
 	}
 }
 
-func (s *Site) kindFromSections(sections []string) string {
-	if len(sections) == 0 {
-		return KindSection
-	}
-
-	if _, isTaxonomy := s.Taxonomies[sections[0]]; isTaxonomy {
-		if len(sections) == 1 {
-			return KindTaxonomyTerm
-		}
-		return KindTaxonomy
-	}
-	return KindSection
-}
-
 func (s *Site) layouts(p *PageOutput) ([]string, error) {
 	return s.layoutHandler.For(p.layoutDescriptor, p.outputFormat)
 }
--- a/hugolib/taxonomy_test.go
+++ b/hugolib/taxonomy_test.go
@@ -76,10 +76,8 @@
 other = "others"
 empty = "empties"
 permalinked = "permalinkeds"
-subcats = "subcats"
 [permalinks]
 permalinkeds = "/perma/:slug/"
-subcats = "/subcats/:slug/"
 `
 
 	pageTemplate := `---
@@ -92,8 +90,6 @@
 %s
 permalinkeds:
 %s
-subcats:
-%s
 ---
 # Doc
 `
@@ -105,17 +101,24 @@
 
 	fs := th.Fs
 
-	writeSource(t, fs, "content/p1.md", fmt.Sprintf(pageTemplate, "t1/c1", "- Tag1", "- cat1\n- \"cAt/dOg\"", "- o1", "- pl1", ""))
-	writeSource(t, fs, "content/p2.md", fmt.Sprintf(pageTemplate, "t2/c1", "- tag2", "- cat1", "- o1", "- pl1", ""))
-	writeSource(t, fs, "content/p3.md", fmt.Sprintf(pageTemplate, "t2/c12", "- tag2", "- cat2", "- o1", "- pl1", ""))
-	writeSource(t, fs, "content/p4.md", fmt.Sprintf(pageTemplate, "Hello World", "", "", "- \"Hello Hugo world\"", "- pl1", ""))
-	writeSource(t, fs, "content/p5.md", fmt.Sprintf(pageTemplate, "Sub/categories", "", "", "", "", "- \"sc0/sp1\""))
+	if preserveTaxonomyNames {
+		writeSource(t, fs, "content/p1.md", fmt.Sprintf(pageTemplate, "t1/c1", "- tag1", "- cat1", "- o1", "- pl1"))
+	} else {
+		// Check lower-casing of tags
+		writeSource(t, fs, "content/p1.md", fmt.Sprintf(pageTemplate, "t1/c1", "- Tag1", "- cAt1", "- o1", "- pl1"))
 
+	}
+	writeSource(t, fs, "content/p2.md", fmt.Sprintf(pageTemplate, "t2/c1", "- tag2", "- cat1", "- o1", "- pl1"))
+	writeSource(t, fs, "content/p3.md", fmt.Sprintf(pageTemplate, "t2/c12", "- tag2", "- cat2", "- o1", "- pl1"))
+	writeSource(t, fs, "content/p4.md", fmt.Sprintf(pageTemplate, "Hello World", "", "", "- \"Hello Hugo world\"", "- pl1"))
+
 	writeNewContentFile(t, fs.Source, "Category Terms", "2017-01-01", "content/categories/_index.md", 10)
 	writeNewContentFile(t, fs.Source, "Tag1 List", "2017-01-01", "content/tags/Tag1/_index.md", 10)
 
-	require.NoError(t, h.Build(BuildCfg{}))
+	err := h.Build(BuildCfg{})
 
+	require.NoError(t, err)
+
 	// So what we have now is:
 	// 1. categories with terms content page, but no content page for the only c1 category
 	// 2. tags with no terms content page, but content page for one of 2 tags (tag1)
@@ -132,11 +135,10 @@
 	// 1.
 	if preserveTaxonomyNames {
 		th.assertFileContent(pathFunc("public/categories/cat1/index.html"), "List", "cat1")
-		th.assertFileContent(pathFunc("public/categories/cat-dog/index.html"), "List", "cAt/dOg")
 	} else {
 		th.assertFileContent(pathFunc("public/categories/cat1/index.html"), "List", "Cat1")
-		th.assertFileContent(pathFunc("public/categories/cat-dog/index.html"), "List", "Cat/Dog")
 	}
+
 	th.assertFileContent(pathFunc("public/categories/index.html"), "Terms List", "Category Terms")
 
 	// 2.
@@ -172,17 +174,16 @@
 	// of KindTaxonomy pages in its Pages slice.
 	taxonomyTermPageCounts := map[string]int{
 		"tags":         2,
-		"categories":   3,
+		"categories":   2,
 		"others":       2,
 		"empties":      0,
 		"permalinkeds": 1,
-		"subcats":      1,
 	}
 
 	for taxonomy, count := range taxonomyTermPageCounts {
 		term := s.getPage(KindTaxonomyTerm, taxonomy)
 		require.NotNil(t, term)
-		require.Len(t, term.Pages, count, taxonomy)
+		require.Len(t, term.Pages, count)
 
 		for _, page := range term.Pages {
 			require.Equal(t, KindTaxonomy, page.Kind)
@@ -189,41 +190,26 @@
 		}
 	}
 
-	fixTerm := func(s string) string {
-		if preserveTaxonomyNames {
-			return s
-		}
-		return strings.ToLower(s)
-	}
-
-	fixURL := func(s string) string {
-		if uglyURLs {
-			return strings.TrimRight(s, "/") + ".html"
-		}
-		return s
-	}
-
 	cat1 := s.getPage(KindTaxonomy, "categories", "cat1")
 	require.NotNil(t, cat1)
-	require.Equal(t, fixURL("/blog/categories/cat1/"), cat1.RelPermalink())
+	if uglyURLs {
+		require.Equal(t, "/blog/categories/cat1.html", cat1.RelPermalink())
+	} else {
+		require.Equal(t, "/blog/categories/cat1/", cat1.RelPermalink())
+	}
 
-	catdog := s.getPage(KindTaxonomy, "categories", fixTerm("cAt/dOg"))
-	require.NotNil(t, catdog)
-	require.Equal(t, fixURL("/blog/categories/cat-dog/"), catdog.RelPermalink())
-
 	pl1 := s.getPage(KindTaxonomy, "permalinkeds", "pl1")
-	require.NotNil(t, pl1)
-	require.Equal(t, fixURL("/blog/perma/pl1/"), pl1.RelPermalink())
-
 	permalinkeds := s.getPage(KindTaxonomyTerm, "permalinkeds")
+	require.NotNil(t, pl1)
 	require.NotNil(t, permalinkeds)
-	require.Equal(t, fixURL("/blog/permalinkeds/"), permalinkeds.RelPermalink())
+	if uglyURLs {
+		require.Equal(t, "/blog/perma/pl1.html", pl1.RelPermalink())
+		require.Equal(t, "/blog/permalinkeds.html", permalinkeds.RelPermalink())
+	} else {
+		require.Equal(t, "/blog/perma/pl1/", pl1.RelPermalink())
+		require.Equal(t, "/blog/permalinkeds/", permalinkeds.RelPermalink())
+	}
 
-	// Issue #5223
-	sp1 := s.getPage(KindTaxonomy, "subcats", "sc0/sp1")
-	require.NotNil(t, sp1)
-	require.Equal(t, fixURL("/blog/subcats/sc0/sp1/"), sp1.RelPermalink())
-
 	// Issue #3070 preserveTaxonomyNames
 	if preserveTaxonomyNames {
 		helloWorld := s.getPage(KindTaxonomy, "others", "Hello Hugo world")
@@ -241,20 +227,26 @@
 }
 
 // https://github.com/gohugoio/hugo/issues/5513
-func TestTaxonomyPathSeparation(t *testing.T) {
+// https://github.com/gohugoio/hugo/issues/5571
+func TestTaxonomiesPathSeparation(t *testing.T) {
 	t.Parallel()
 
+	assert := require.New(t)
+
 	config := `
 baseURL = "https://example.com"
 [taxonomies]
 "news/tag" = "news/tags"
 "news/category" = "news/categories"
+"t1/t2/t3" = "t1/t2/t3s"
+"s1/s2/s3" = "s1/s2/s3s"
 `
 
 	pageContent := `
 +++
 title = "foo"
-"news/categories" = ["a", "b", "c"]
+"news/categories" = ["a", "b", "c", "d/e", "f/g/h"]
+"t1/t2/t3s" = ["t4/t5", "t4/t5/t6"]
 +++
 Content.
 `
@@ -268,9 +260,43 @@
 ---
 `)
 
+	b.WithContent("news/categories/f/g/h/_index.md", `
+---
+title: "This is H"
+---
+`)
+
+	b.WithContent("t1/t2/t3s/t4/t5/_index.md", `
+---
+title: "This is T5"
+---
+`)
+
+	b.WithContent("s1/s2/s3s/_index.md", `
+---
+title: "This is S3s"
+---
+`)
+
 	b.CreateSites().Build(BuildCfg{})
 
-	b.AssertFileContent("public/news/categories/index.html", "Taxonomy Term Page 1|News/Categories|Hello|https://example.com/news/categories/|")
+	s := b.H.Sites[0]
+
+	ta := s.findPagesByKind(KindTaxonomy)
+	te := s.findPagesByKind(KindTaxonomyTerm)
+
+	assert.Equal(4, len(te))
+	assert.Equal(7, len(ta))
+
 	b.AssertFileContent("public/news/categories/a/index.html", "Taxonomy List Page 1|A|Hello|https://example.com/news/categories/a/|")
 	b.AssertFileContent("public/news/categories/b/index.html", "Taxonomy List Page 1|This is B|Hello|https://example.com/news/categories/b/|")
+	b.AssertFileContent("public/news/categories/d/e/index.html", "Taxonomy List Page 1|D/E|Hello|https://example.com/news/categories/d/e/|")
+	b.AssertFileContent("public/news/categories/f/g/h/index.html", "Taxonomy List Page 1|This is H|Hello|https://example.com/news/categories/f/g/h/|")
+	b.AssertFileContent("public/t1/t2/t3s/t4/t5/index.html", "Taxonomy List Page 1|This is T5|Hello|https://example.com/t1/t2/t3s/t4/t5/|")
+	b.AssertFileContent("public/t1/t2/t3s/t4/t5/t6/index.html", "Taxonomy List Page 1|T4/T5/T6|Hello|https://example.com/t1/t2/t3s/t4/t5/t6/|")
+
+	b.AssertFileContent("public/news/categories/index.html", "Taxonomy Term Page 1|News/Categories|Hello|https://example.com/news/categories/|")
+	b.AssertFileContent("public/t1/t2/t3s/index.html", "Taxonomy Term Page 1|T1/T2/T3s|Hello|https://example.com/t1/t2/t3s/|")
+	b.AssertFileContent("public/s1/s2/s3s/index.html", "Taxonomy Term Page 1|This is S3s|Hello|https://example.com/s1/s2/s3s/|")
+
 }
--- a/hugolib/testhelpers_test.go
+++ b/hugolib/testhelpers_test.go
@@ -407,9 +407,7 @@
 ---
 # doc1
 *some "content"*
-
 {{< shortcode >}}
-
 {{< lingo >}}
 `
 
@@ -420,12 +418,15 @@
 			"content/sect/doc1.nn.md", contentTemplate,
 		}
 
+		listTemplateCommon = "{{ $p := .Paginator }}{{ $p.PageNumber }}|{{ .Title }}|{{ i18n \"hello\" }}|{{ .Permalink }}|Pager: {{ template \"_internal/pagination.html\" . }}"
+
 		defaultTemplates = []string{
 			"_default/single.html", "Single: {{ .Title }}|{{ i18n \"hello\" }}|{{.Lang}}|{{ .Content }}",
-			"_default/list.html", "{{ $p := .Paginator }}List Page {{ $p.PageNumber }}: {{ .Title }}|{{ i18n \"hello\" }}|{{ .Permalink }}|Pager: {{ template \"_internal/pagination.html\" . }}",
+			"_default/list.html", "List Page " + listTemplateCommon,
 			"index.html", "{{ $p := .Paginator }}Default Home Page {{ $p.PageNumber }}: {{ .Title }}|{{ .IsHome }}|{{ i18n \"hello\" }}|{{ .Permalink }}|{{  .Site.Data.hugo.slogan }}|String Resource: {{ ( \"Hugo Pipes\" | resources.FromString \"text/pipes.txt\").RelPermalink  }}",
 			"index.fr.html", "{{ $p := .Paginator }}French Home Page {{ $p.PageNumber }}: {{ .Title }}|{{ .IsHome }}|{{ i18n \"hello\" }}|{{ .Permalink }}|{{  .Site.Data.hugo.slogan }}|String Resource: {{ ( \"Hugo Pipes\" | resources.FromString \"text/pipes.txt\").RelPermalink  }}",
-
+			"_default/terms.html", "Taxonomy Term Page " + listTemplateCommon,
+			"_default/taxonomy.html", "Taxonomy List Page " + listTemplateCommon,
 			// Shortcodes
 			"shortcodes/shortcode.html", "Shortcode: {{ i18n \"hello\" }}",
 			// A shortcode in multiple languages