Skip to content

Commit d9a78b6

Browse files
betaverosbep
authored andcommitted
Handle Taxonomy permalinks
Return the correct virtual Section for Taxonomy and TaxonomyTerm. Restrict permalink expansion to only Pages and Taxonomies, but then actually use expanded permalinks even for non-Pages. Fixes #1208.
1 parent 23ba779 commit d9a78b6

File tree

5 files changed

+48
-20
lines changed

5 files changed

+48
-20
lines changed

‎docs/content/content-management/taxonomies.md‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,7 @@ Note that if you use `preserveTaxonomyNames` and intend to manually construct UR
132132
{{% note %}}
133133
You can add content and front matter to your taxonomy list and taxonomy terms pages. See [Content Organization](/content-management/organization/) for more information on how to add an `_index.md` for this purpose.
134134

135-
Note also that taxonomy [permalinks](/content-management/urls/) are *not* configurable.
135+
Much like regular pages, taxonomy list [permalinks](/content-management/urls/) are configurable, but taxonomy term page permalinks are not.
136136
{{% /note %}}
137137

138138
## Add Taxonomies to Content

‎docs/content/content-management/urls.md‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,8 @@ permalinks:
4545

4646
Only the content under `post/` will have the new URL structure. For example, the file `content/post/sample-entry.md` with `date: 2017-02-27T19:20:00-05:00` in its front matter will render to `public/2017/02/sample-entry/index.html` at build time and therefore be reachable at `https://example.com/2013/11/sample-entry/`.
4747

48+
You can also configure permalinks of taxonomies with the same syntax, by using the plural form of the taxonomy instead of the section. You will probably only want to use the configuration values `:slug` or `:title`.
49+
4850
### Permalink Configuration Values
4951

5052
The following is a list of values that can be used in a `permalink` definition in your site `config` file. All references to time are dependent on the content's date.

‎hugolib/page.go‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -758,7 +758,7 @@ func (p *Page) Type() string {
758758
// since Hugo 0.22 we support nested sections, but this will always be the first
759759
// element of any nested path.
760760
func (p *Page) Section() string {
761-
if p.Kind == KindSection {
761+
if p.Kind == KindSection || p.Kind == KindTaxonomy || p.Kind == KindTaxonomyTerm {
762762
return p.sections[0]
763763
}
764764
return p.Source.Section()

‎hugolib/page_paths.go‎

Lines changed: 20 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -99,15 +99,22 @@ func (p *Page) initTargetPathDescriptor() error {
9999
d.LangPrefix = p.Lang()
100100
}
101101

102-
if override, ok := p.Site.Permalinks[p.Section()]; ok {
103-
opath, err := override.Expand(p)
104-
if err != nil {
105-
return err
106-
}
102+
// Expand only KindPage and KindTaxonomy; don't expand other Kinds of Pages
103+
// like KindSection or KindTaxonomyTerm because they are "shallower" and
104+
// the permalink configuration values are likely to be redundant, e.g.
105+
// naively expanding /category/:slug/ would give /category/categories/ for
106+
// the "categories" KindTaxonomyTerm.
107+
if p.Kind == KindPage || p.Kind == KindTaxonomy {
108+
if override, ok := p.Site.Permalinks[p.Section()]; ok {
109+
opath, err := override.Expand(p)
110+
if err != nil {
111+
return err
112+
}
107113

108-
opath, _ = url.QueryUnescape(opath)
109-
opath = filepath.FromSlash(opath)
110-
d.ExpandedPermalink = opath
114+
opath, _ = url.QueryUnescape(opath)
115+
opath = filepath.FromSlash(opath)
116+
d.ExpandedPermalink = opath
117+
}
111118
}
112119

113120
p.targetPathDescriptorPrototype = d
@@ -151,7 +158,11 @@ func createTargetPath(d targetPathDescriptor) string {
151158
}
152159

153160
if d.Kind != KindPage && len(d.Sections) > 0 {
154-
pagePath = filepath.Join(d.Sections...)
161+
if d.ExpandedPermalink != "" {
162+
pagePath = filepath.Join(pagePath, d.ExpandedPermalink)
163+
} else {
164+
pagePath = filepath.Join(d.Sections...)
165+
}
155166
needsBase = false
156167
}
157168

‎hugolib/taxonomy_test.go‎

Lines changed: 24 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,10 @@ tag = "tags"
7777
category = "categories"
7878
other = "others"
7979
empty = "empties"
80+
permalinked = "permalinkeds"
81+
82+
[permalinks]
83+
permalinkeds = "/perma/:slug/"
8084
`
8185

8286
pageTemplate := `---
@@ -87,6 +91,8 @@ categories:
8791
%s
8892
others:
8993
%s
94+
permalinkeds:
95+
%s
9096
---
9197
# Doc
9298
`
@@ -99,15 +105,15 @@ others:
99105
fs := th.Fs
100106

101107
if preserveTaxonomyNames {
102-
writeSource(t, fs, "content/p1.md", fmt.Sprintf(pageTemplate, "t1/c1", "- tag1", "- cat1", "- o1"))
108+
writeSource(t, fs, "content/p1.md", fmt.Sprintf(pageTemplate, "t1/c1", "- tag1", "- cat1", "- o1", "- pl1"))
103109
} else {
104110
// Check lower-casing of tags
105-
writeSource(t, fs, "content/p1.md", fmt.Sprintf(pageTemplate, "t1/c1", "- Tag1", "- cAt1", "- o1"))
111+
writeSource(t, fs, "content/p1.md", fmt.Sprintf(pageTemplate, "t1/c1", "- Tag1", "- cAt1", "- o1", "- pl1"))
106112

107113
}
108-
writeSource(t, fs, "content/p2.md", fmt.Sprintf(pageTemplate, "t2/c1", "- tag2", "- cat1", "- o1"))
109-
writeSource(t, fs, "content/p3.md", fmt.Sprintf(pageTemplate, "t2/c12", "- tag2", "- cat2", "- o1"))
110-
writeSource(t, fs, "content/p4.md", fmt.Sprintf(pageTemplate, "Hello World", "", "", "- \"Hello Hugo world\""))
114+
writeSource(t, fs, "content/p2.md", fmt.Sprintf(pageTemplate, "t2/c1", "- tag2", "- cat1", "- o1", "- pl1"))
115+
writeSource(t, fs, "content/p3.md", fmt.Sprintf(pageTemplate, "t2/c12", "- tag2", "- cat2", "- o1", "- pl1"))
116+
writeSource(t, fs, "content/p4.md", fmt.Sprintf(pageTemplate, "Hello World", "", "", "- \"Hello Hugo world\"", "- pl1"))
111117

112118
writeNewContentFile(t, fs, "Category Terms", "2017-01-01", "content/categories/_index.md", 10)
113119
writeNewContentFile(t, fs, "Tag1 List", "2017-01-01", "content/tags/tag1/_index.md", 10)
@@ -146,10 +152,11 @@ others:
146152
// Make sure that each KindTaxonomyTerm page has an appropriate number
147153
// of KindTaxonomy pages in its Pages slice.
148154
taxonomyTermPageCounts := map[string]int{
149-
"tags": 2,
150-
"categories": 2,
151-
"others": 2,
152-
"empties": 0,
155+
"tags": 2,
156+
"categories": 2,
157+
"others": 2,
158+
"empties": 0,
159+
"permalinkeds": 1,
153160
}
154161

155162
for taxonomy, count := range taxonomyTermPageCounts {
@@ -170,6 +177,14 @@ others:
170177
require.Equal(t, "/blog/categories/cat1/", cat1.RelPermalink())
171178
}
172179

180+
pl1 := s.getPage(KindTaxonomy, "permalinkeds", "pl1")
181+
require.NotNil(t, pl1)
182+
if uglyURLs {
183+
require.Equal(t, "/blog/perma/pl1.html", pl1.RelPermalink())
184+
} else {
185+
require.Equal(t, "/blog/perma/pl1/", pl1.RelPermalink())
186+
}
187+
173188
// Issue #3070 preserveTaxonomyNames
174189
if preserveTaxonomyNames {
175190
helloWorld := s.getPage(KindTaxonomy, "others", "Hello Hugo world")

0 commit comments

Comments
 (0)