hugolib: Restore 0.48 slash handling in taxonomies
authorBjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com>
Sat, 29 Dec 2018 09:35:46 +0000 (10:35 +0100)
committerBjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com>
Sun, 30 Dec 2018 17:50:09 +0000 (18:50 +0100)
Fixes #5571

hugolib/hugo_sites.go
hugolib/hugo_sites_build_test.go
hugolib/page.go
hugolib/permalinks.go
hugolib/permalinks_test.go
hugolib/site.go
hugolib/taxonomy_test.go
hugolib/testhelpers_test.go

index 6a4893473b83e5377fb4ec65b3d65805d7f6ed87..9ce1c438e755ef46bb20ecfc817d4873e2646795 100644 (file)
@@ -548,7 +548,7 @@ func (h *HugoSites) createMissingPages() error {
                                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 @@ func (h *HugoSites) createMissingPages() error {
                                                        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 @@ func (h *HugoSites) setupTranslations() {
        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) {
index 91ae8434d9bec8cf8f77bab661ce11fce1fbe69e..f772ce1926d9a53d711483af620b538f98dd41a0 100644 (file)
@@ -100,8 +100,8 @@ func doTestMultiSitesMainLangInRoot(t *testing.T, defaultInSubDir bool) {
        // 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
index 15ed631c176c5064d1f97da692671e5cd2328ae7..9f09dc9bd71136c9141d346e74165a114416b8c9 100644 (file)
@@ -2048,10 +2048,41 @@ func kindFromFileInfo(fi *fileInfo) string {
        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))
index 55dcd7db60cf4b31192e8a6ee6a8c335d58b5030..3d261a113e32f7bad1ab3b29bfedb75ddc5a9a5a 100644 (file)
@@ -40,7 +40,7 @@ type PermalinkOverrides map[string]pathPattern
 // 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 pageToPermalinkSlugElseTitle(p *Page, a string) (string, error) {
 }
 
 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 @@ func init() {
                "filename":    pageToPermalinkFilename,
        }
 
-       attributeRegexp = regexp.MustCompile(`:\w+`)
 }
index b542e1665b0c24effd3097cc91569d118f313616..7bc24295584e53523be8c1e3f971fbd98079f0f4 100644 (file)
@@ -14,6 +14,7 @@
 package hugolib
 
 import (
+       "path/filepath"
        "strings"
        "testing"
 )
@@ -62,7 +63,7 @@ func TestPermalinkValidation(t *testing.T) {
 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)
index 1b3a317a1dc486b047b1bc0ada4bfceacf76b263..9c225b332ed3fbd52c84e67e951b848ae3c70ac0 100644 (file)
@@ -1586,20 +1586,6 @@ func (s *Site) resetBuildState() {
        }
 }
 
-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)
 }
index 6ea3971736de4aec5e2bd78f602760b345b05a2f..1ae9fae228ff1ca2d9167d601001dda721a9ac6e 100644 (file)
@@ -76,10 +76,8 @@ category = "categories"
 other = "others"
 empty = "empties"
 permalinked = "permalinkeds"
-subcats = "subcats"
 [permalinks]
 permalinkeds = "/perma/:slug/"
-subcats = "/subcats/:slug/"
 `
 
        pageTemplate := `---
@@ -92,8 +90,6 @@ others:
 %s
 permalinkeds:
 %s
-subcats:
-%s
 ---
 # Doc
 `
@@ -105,16 +101,23 @@ subcats:
 
        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
@@ -132,11 +135,10 @@ subcats:
        // 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,57 +174,41 @@ subcats:
        // 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)
                }
        }
 
-       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())
-
-       catdog := s.getPage(KindTaxonomy, "categories", fixTerm("cAt/dOg"))
-       require.NotNil(t, catdog)
-       require.Equal(t, fixURL("/blog/categories/cat-dog/"), catdog.RelPermalink())
+       if uglyURLs {
+               require.Equal(t, "/blog/categories/cat1.html", cat1.RelPermalink())
+       } else {
+               require.Equal(t, "/blog/categories/cat1/", cat1.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())
-
-       // Issue #5223
-       sp1 := s.getPage(KindTaxonomy, "subcats", "sc0/sp1")
-       require.NotNil(t, sp1)
-       require.Equal(t, fixURL("/blog/subcats/sc0/sp1/"), sp1.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 #3070 preserveTaxonomyNames
        if preserveTaxonomyNames {
@@ -241,20 +227,26 @@ subcats:
 }
 
 // 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.
 `
@@ -266,11 +258,45 @@ Content.
 ---
 title: "This is B"
 ---
+`)
+
+       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/|")
+
 }
index a60ca29059641ffa9e9ba2dbc91128108608daa1..64d1ff96a23b22a0a0b982d26e8996777d0f03ae 100644 (file)
@@ -407,9 +407,7 @@ date: "2018-02-28"
 ---
 # doc1
 *some "content"*
-
 {{< shortcode >}}
-
 {{< lingo >}}
 `
 
@@ -420,12 +418,15 @@ date: "2018-02-28"
                        "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