Rename taxonomy kinds from taxonomy to term, taxonomyTerm to taxonomy
authorBjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com>
Tue, 16 Jun 2020 13:43:50 +0000 (15:43 +0200)
committerBjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com>
Thu, 18 Jun 2020 07:09:56 +0000 (09:09 +0200)
And we have taken great measures to limit potential site breakage:

* For `disableKinds` and `outputs` we try to map from old to new values if possible, if not we print an ERROR that can be toggled off if not relevant.
* The layout lookup is mostly compatible with more options for the new `term` kind.

That leaves:

* Where queries in site.Pages using taxonomy/taxonomyTerm Kind values as filter.
* Other places where these kind value are used in the templates (classes etc.)

Fixes #6911
Fixes #7395

44 files changed:
common/constants/constants.go [new file with mode: 0644]
common/loggers/ignorableLogger.go [new file with mode: 0644]
docs/content/en/content-management/taxonomies.md
docs/content/en/getting-started/configuration.md
docs/content/en/templates/lookup-order.md
docs/content/en/templates/output-formats.md
docs/content/en/templates/section-templates.md
docs/data/docs.json
docs/layouts/shortcodes/content-tree.html [new file with mode: 0644]
docs/layouts/shortcodes/page-kinds.html [new file with mode: 0644]
hugolib/breaking_changes_test.go [new file with mode: 0644]
hugolib/cascade_test.go
hugolib/content_map.go
hugolib/content_map_page.go
hugolib/content_map_test.go
hugolib/disableKinds_test.go
hugolib/hugo_sites.go
hugolib/hugo_sites_build_test.go
hugolib/hugo_smoke_test.go
hugolib/page.go
hugolib/page__data.go
hugolib/page__meta.go
hugolib/page__paginator.go
hugolib/page__paths.go
hugolib/page__tree.go
hugolib/page_kinds.go
hugolib/pagebundler_test.go
hugolib/pagecollections_test.go
hugolib/resource_chain_babel_test.go
hugolib/resource_chain_test.go
hugolib/shortcode_test.go
hugolib/site.go
hugolib/site_output.go
hugolib/site_output_test.go
hugolib/site_test.go
hugolib/taxonomy_test.go
hugolib/testhelpers_test.go
output/docshelper.go
output/layout.go
output/layout_test.go
resources/page/page.go
resources/page/page_kinds.go
resources/page/page_kinds_test.go
resources/page/page_paths_test.go

diff --git a/common/constants/constants.go b/common/constants/constants.go
new file mode 100644 (file)
index 0000000..25bd7c7
--- /dev/null
@@ -0,0 +1,21 @@
+// Copyright 2020 The Hugo Authors. All rights reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package constants
+
+// Error IDs.
+// Do not change these values.
+const (
+       ErrIDAmbigousDisableKindTaxonomy = "error-disable-taxonomy"
+       ErrIDAmbigousOutputKindTaxonomy  = "error-output-taxonomy"
+)
diff --git a/common/loggers/ignorableLogger.go b/common/loggers/ignorableLogger.go
new file mode 100644 (file)
index 0000000..e12e41d
--- /dev/null
@@ -0,0 +1,52 @@
+// Copyright 2020 The Hugo Authors. All rights reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package loggers
+
+import (
+       "fmt"
+       "strings"
+)
+
+// IgnorableLogger is a logger that ignores certain log statements.
+type IgnorableLogger struct {
+       logger     *Logger
+       statements map[string]bool
+}
+
+// NewIgnorableLogger wraps the given logger and ignores the log statement IDs given.
+func NewIgnorableLogger(logger *Logger, statements ...string) IgnorableLogger {
+       statementsSet := make(map[string]bool)
+       for _, s := range statements {
+               statementsSet[strings.ToLower(s)] = true
+
+       }
+       return IgnorableLogger{
+               logger:     logger,
+               statements: statementsSet,
+       }
+}
+
+func (l IgnorableLogger) Errorf(statementID, format string, v ...interface{}) {
+       if l.statements[statementID] {
+               // Ignore.
+               return
+       }
+       ignoreMsg := fmt.Sprintf(`
+If you feel that this should not be logged as an ERROR, you can ignore it by adding this to your site config:
+ignoreErrors = [%q]`, statementID)
+
+       format += ignoreMsg
+
+       l.logger.ERROR.Printf(format, v...)
+}
index 03747e72bc4df212eb4d967f1693e4b9819c1891..869193cb3f7eddb4339434ff72b0adf529082b14 100644 (file)
@@ -1,10 +1,9 @@
 ---
 title: Taxonomies
 linktitle:
-description: Hugo includes support for user-defined taxonomies to help you  demonstrate logical relationships between content for the end users of your website.
+description: Hugo includes support for user-defined taxonomies..
 date: 2017-02-01
 publishdate: 2017-02-01
-lastmod: 2017-02-01
 keywords: [taxonomies,metadata,front matter,terms]
 categories: [content management]
 menu:
@@ -32,7 +31,6 @@ Term
 Value
 : a piece of content assigned to a term
 
-{{< youtube pCPCQgqC8RA >}}
 
 ## Example Taxonomy: Movie Website
 
@@ -97,9 +95,13 @@ Without adding a single line to your [site config][config] file, Hugo will autom
 If you do not want Hugo to create any taxonomies, set `disableKinds` in your [site config][config] to the following:
 
 {{< code-toggle copy="false" >}}
-disableKinds = ["taxonomy","taxonomyTerm"]
+disableKinds = ["taxonomy","term"]
 {{</ code-toggle >}}
 
+{{< new-in "0.73.0" >}} We have fixed the before confusing page kinds used for taxonomies (see the listing below) to be in line with the terms used when we talk about taxonomies. We have been careful to avoid site breakage, and you should get an ERROR in the console if you need to adjust your `disableKinds` section.
+
+{{< page-kinds >}}
+
 ### Default Destinations
 
 When taxonomies are used---and [taxonomy templates][] are provided---Hugo will automatically create both a page listing all the taxonomy's terms and individual pages with lists of content associated with each term. For example, a `categories` taxonomy declared in your configuration and used in your content front matter will create the following pages:
@@ -190,7 +192,7 @@ By using taxonomic weight, the same piece of content can appear in different pos
 Currently taxonomies only support the [default `weight => date` ordering of list content](/templates/lists/#default-weight-date). For more information, see the documentation on [taxonomy templates](/templates/taxonomy-templates/).
 {{% /note %}}
 
-## Add custom metadata to a Taxonomy Term
+## Add custom metadata a Taxonomy or Term
 
 If you need to add custom metadata to your taxonomy terms, you will need to create a page for that term at `/content/<TAXONOMY>/<TERM>/_index.md` and add your metadata in it's front matter. Continuing with our 'Actors' example, let's say you want to add a wikipedia page link to each actor. Your terms pages would be something like this:
 
@@ -201,7 +203,6 @@ If you need to add custom metadata to your taxonomy terms, you will need to crea
   ---
 {{< /code >}}
 
-You can later use your custom metadata as shown in the [Taxonomy Terms Templates documentation](/templates/taxonomy-templates/#displaying-custom-metadata-in-taxonomy-terms-templates).
 
 [`urlize` template function]: /functions/urlize/
 [content section]: /content-management/sections/
index be46870d60042f657caad9d73252ee0f3b220af3..ffc11938c4c4d2efeb1c51190b09c584296dafff 100644 (file)
@@ -124,7 +124,7 @@ disableHugoGeneratorInject (false)
 : Hugo will, by default, inject a generator meta tag in the HTML head on the _home page only_. You can turn it off, but we would really appreciate if you don't, as this is a good way to watch Hugo's popularity on the rise.
 
 disableKinds ([])
-: Enable disabling of all pages of the specified *Kinds*. Allowed values in this list: `"page"`, `"home"`, `"section"`, `"taxonomy"`, `"taxonomyTerm"`, `"RSS"`, `"sitemap"`, `"robotsTXT"`, `"404"`.
+: Enable disabling of all pages of the specified *Kinds*. Allowed values in this list: `"page"`, `"home"`, `"section"`, `"taxonomy"`, `"term"`, `"RSS"`, `"sitemap"`, `"robotsTXT"`, `"404"`.
 
 disableLiveReload (false)
 : Disable automatic live reloading of browser window.
index 629f437c9487d602422d4027d989466f1fedd936..e4cb8e552defde091e2f3c579581bbac17c37dde 100644 (file)
@@ -41,7 +41,7 @@ Type
 : Is value of `type` if set in front matter, else it is the name of the root section (e.g. "blog"). It will always have a value, so if not set, the value is "page". 
 
 Section
-: Is relevant for `section`, `taxonomy` and `taxonomyTerm` types.
+: Is relevant for `section`, `taxonomy` and `term` types.
 
 {{% note %}}
 **Tip:** The examples below looks long and complex. That is the flexibility talking. Most Hugo sites contain just a handful of templates:
@@ -72,13 +72,13 @@ In Hugo, layouts can live in either the project's or the themes' layout folders,
 
 {{< datatable-filtered "output" "layouts" "Kind == section" "Example" "OutputFormat" "Suffix" "Template Lookup Order" >}}
 
-## Examples: Layout Lookup for Taxonomy List Pages
+## Examples: Layout Lookup for Taxonomy Pages
 
 {{< datatable-filtered "output" "layouts" "Kind == taxonomy" "Example" "OutputFormat" "Suffix" "Template Lookup Order" >}}
 
-## Examples: Layout Lookup for Taxonomy Terms Pages
+## Examples: Layout Lookup for Term Pages
 
-{{< datatable-filtered "output" "layouts" "Kind == taxonomyTerm" "Example" "OutputFormat" "Suffix" "Template Lookup Order" >}}
+{{< datatable-filtered "output" "layouts" "Kind == term" "Example" "OutputFormat" "Suffix" "Template Lookup Order" >}}
 
 
 
index cbc667da3eca33c5bb673c03cebd1c45b8aae167..619ac449e483a23fa083aab1a51f5be1e38e77bd 100644 (file)
@@ -137,8 +137,8 @@ Formats are set based on that.
 | `page`         | HTML                   |
 | `home`         | HTML, RSS              |
 | `section`      | HTML, RSS              |
-| `taxonomyTerm` | HTML, RSS              |
-| `taxonomy`     | HTML, RSS              |
+| `taxonomy` | HTML, RSS              |
+| `term`     | HTML, RSS              |
 
 ### Customizing Output Formats
 
@@ -156,10 +156,14 @@ Example from site config file:
 
 
 Note that in the above examples, the *output formats* for `section`,
-`taxonomyTerm` and `taxonomy` will stay at their default value `["HTML",
+`taxonomy` and `term` will stay at their default value `["HTML",
 "RSS"]`.
 
-* The `outputs` definition is per [`Page` `Kind`][page_kinds] (`page`, `home`, `section`, `taxonomy`, or `taxonomyTerm`).
+{{< new-in "0.73.0" >}} We have fixed the before confusing page kinds used for taxonomies (see the listing below) to be in line with the terms used when we talk about taxonomies. We have been careful to avoid site breakage, and you should get an ERROR in the console if you need to adjust your `outputs` section.
+
+{{% page-kinds %}}
+
+* The `outputs` definition is per [`Page` `Kind`][page_kinds] (`page`, `home`, `section`, `taxonomy`, or `term`).
 * The names (e.g. `HTML`, `AMP`) used must match the `Name` of a defined *Output Format*.
   * These names are case insensitive.
 * These can be overridden per `Page` in the front matter of content files.
index 577529e3f289c48bf90e275e534f3ef135fcaa3e..a40e2a2d7b4abb2fe1f44da1d064178c79d7cfee 100644 (file)
@@ -30,13 +30,7 @@ See [Template Lookup](/templates/lookup-order/).
 
 Every `Page` in Hugo has a `.Kind` attribute.
 
-| Kind           | Description                                                        | Example                                                                       |
-|----------------|--------------------------------------------------------------------|-------------------------------------------------------------------------------|
-| `home`         | The home page                                                      | `/index.html`                                                                 |
-| `page`         | A page showing a _regular page_                                    | `my-post` page (`/posts/my-post/index.html`)                                  |
-| `section`      | A page listing _regular pages_ from a given [_section_][sections]  | `posts` section (`/posts/index.html`)                                         |
-| `taxonomy`     | A page listing _regular pages_ from a given _taxonomy term_        | page for the term `awesome` from `tags` taxonomy (`/tags/awesome/index.html`) |
-| `taxonomyTerm` | A page listing terms from a given _taxonomy_                       | page for the `tags` taxonomy (`/tags/index.html`)                             |
+{{% page-kinds %}}
 
 ## `.Site.GetPage` with Sections
 
index 01b8b8d5458c4fcc3557f8b178081ef589f2ae9e..2a2a0bf520043a1b3b6d395993db719ee04b5a37 100644 (file)
           "genshitext"
         ]
       },
+      {
+        "Name": "Gherkin",
+        "Aliases": [
+          "Cucumber",
+          "FEATURE",
+          "Gherkin",
+          "cucumber",
+          "feature",
+          "gherkin"
+        ]
+      },
       {
         "Name": "Gnuplot",
         "Aliases": [
           "hcl"
         ]
       },
+      {
+        "Name": "HLB",
+        "Aliases": [
+          "hlb"
+        ]
+      },
       {
         "Name": "HTML",
         "Aliases": [
           "ragel"
         ]
       },
+      {
+        "Name": "ReasonML",
+        "Aliases": [
+          "re",
+          "reason",
+          "reasonml",
+          "rei"
+        ]
+      },
       {
         "Name": "Rexx",
         "Aliases": [
           "rust"
         ]
       },
+      {
+        "Name": "SAS",
+        "Aliases": [
+          "SAS",
+          "sas"
+        ]
+      },
       {
         "Name": "SCSS",
         "Aliases": [
         "Name": "TypoScript",
         "Aliases": [
           "ts",
-          "txt",
           "typoscript"
         ]
       },
           "yml"
         ]
       },
+      {
+        "Name": "YANG",
+        "Aliases": [
+          "yang"
+        ]
+      },
       {
         "Name": "cfstatement",
         "Aliases": [
           "keepDefaultAttrVals": true,
           "keepDocumentTags": true,
           "keepEndTags": true,
+          "keepQuotes": false,
           "keepWhitespace": false
         },
         "css": {
         ]
       },
       {
-        "Example": "Taxonomy list in categories",
+        "Example": "Taxonomy in categories",
         "Kind": "taxonomy",
         "OutputFormat": "RSS",
         "Suffix": "xml",
         "Template Lookup Order": [
-          "layouts/categories/category.rss.xml",
+          "layouts/categories/category.terms.rss.xml",
+          "layouts/categories/terms.rss.xml",
           "layouts/categories/taxonomy.rss.xml",
           "layouts/categories/rss.xml",
           "layouts/categories/list.rss.xml",
-          "layouts/categories/category.xml",
+          "layouts/categories/category.terms.xml",
+          "layouts/categories/terms.xml",
           "layouts/categories/taxonomy.xml",
           "layouts/categories/list.xml",
-          "layouts/taxonomy/category.rss.xml",
-          "layouts/taxonomy/taxonomy.rss.xml",
-          "layouts/taxonomy/rss.xml",
-          "layouts/taxonomy/list.rss.xml",
-          "layouts/taxonomy/category.xml",
-          "layouts/taxonomy/taxonomy.xml",
-          "layouts/taxonomy/list.xml",
-          "layouts/category/category.rss.xml",
+          "layouts/category/category.terms.rss.xml",
+          "layouts/category/terms.rss.xml",
           "layouts/category/taxonomy.rss.xml",
           "layouts/category/rss.xml",
           "layouts/category/list.rss.xml",
-          "layouts/category/category.xml",
+          "layouts/category/category.terms.xml",
+          "layouts/category/terms.xml",
           "layouts/category/taxonomy.xml",
           "layouts/category/list.xml",
-          "layouts/_default/category.rss.xml",
+          "layouts/taxonomy/category.terms.rss.xml",
+          "layouts/taxonomy/terms.rss.xml",
+          "layouts/taxonomy/taxonomy.rss.xml",
+          "layouts/taxonomy/rss.xml",
+          "layouts/taxonomy/list.rss.xml",
+          "layouts/taxonomy/category.terms.xml",
+          "layouts/taxonomy/terms.xml",
+          "layouts/taxonomy/taxonomy.xml",
+          "layouts/taxonomy/list.xml",
+          "layouts/_default/category.terms.rss.xml",
+          "layouts/_default/terms.rss.xml",
           "layouts/_default/taxonomy.rss.xml",
           "layouts/_default/rss.xml",
           "layouts/_default/list.rss.xml",
-          "layouts/_default/category.xml",
+          "layouts/_default/category.terms.xml",
+          "layouts/_default/terms.xml",
           "layouts/_default/taxonomy.xml",
           "layouts/_default/list.xml",
           "layouts/_internal/_default/rss.xml"
         ]
       },
       {
-        "Example": "Taxonomy terms in categories",
-        "Kind": "taxonomyTerm",
+        "Example": "Term in categories",
+        "Kind": "term",
         "OutputFormat": "RSS",
         "Suffix": "xml",
         "Template Lookup Order": [
-          "layouts/categories/category.terms.rss.xml",
-          "layouts/categories/terms.rss.xml",
+          "layouts/categories/term.rss.xml",
+          "layouts/categories/category.rss.xml",
+          "layouts/categories/taxonomy.rss.xml",
           "layouts/categories/rss.xml",
           "layouts/categories/list.rss.xml",
-          "layouts/categories/category.terms.xml",
-          "layouts/categories/terms.xml",
+          "layouts/categories/term.xml",
+          "layouts/categories/category.xml",
+          "layouts/categories/taxonomy.xml",
           "layouts/categories/list.xml",
-          "layouts/taxonomy/category.terms.rss.xml",
-          "layouts/taxonomy/terms.rss.xml",
+          "layouts/term/term.rss.xml",
+          "layouts/term/category.rss.xml",
+          "layouts/term/taxonomy.rss.xml",
+          "layouts/term/rss.xml",
+          "layouts/term/list.rss.xml",
+          "layouts/term/term.xml",
+          "layouts/term/category.xml",
+          "layouts/term/taxonomy.xml",
+          "layouts/term/list.xml",
+          "layouts/taxonomy/term.rss.xml",
+          "layouts/taxonomy/category.rss.xml",
+          "layouts/taxonomy/taxonomy.rss.xml",
           "layouts/taxonomy/rss.xml",
           "layouts/taxonomy/list.rss.xml",
-          "layouts/taxonomy/category.terms.xml",
-          "layouts/taxonomy/terms.xml",
+          "layouts/taxonomy/term.xml",
+          "layouts/taxonomy/category.xml",
+          "layouts/taxonomy/taxonomy.xml",
           "layouts/taxonomy/list.xml",
-          "layouts/category/category.terms.rss.xml",
-          "layouts/category/terms.rss.xml",
+          "layouts/category/term.rss.xml",
+          "layouts/category/category.rss.xml",
+          "layouts/category/taxonomy.rss.xml",
           "layouts/category/rss.xml",
           "layouts/category/list.rss.xml",
-          "layouts/category/category.terms.xml",
-          "layouts/category/terms.xml",
+          "layouts/category/term.xml",
+          "layouts/category/category.xml",
+          "layouts/category/taxonomy.xml",
           "layouts/category/list.xml",
-          "layouts/_default/category.terms.rss.xml",
-          "layouts/_default/terms.rss.xml",
+          "layouts/_default/term.rss.xml",
+          "layouts/_default/category.rss.xml",
+          "layouts/_default/taxonomy.rss.xml",
           "layouts/_default/rss.xml",
           "layouts/_default/list.rss.xml",
-          "layouts/_default/category.terms.xml",
-          "layouts/_default/terms.xml",
+          "layouts/_default/term.xml",
+          "layouts/_default/category.xml",
+          "layouts/_default/taxonomy.xml",
           "layouts/_default/list.xml",
           "layouts/_internal/_default/rss.xml"
         ]
         "OutputFormat": "HTML",
         "Suffix": "html",
         "Template Lookup Order": [
-          "layouts/categories/category.html.html",
+          "layouts/categories/category.terms.html.html",
+          "layouts/categories/terms.html.html",
           "layouts/categories/taxonomy.html.html",
           "layouts/categories/list.html.html",
-          "layouts/categories/category.html",
+          "layouts/categories/category.terms.html",
+          "layouts/categories/terms.html",
           "layouts/categories/taxonomy.html",
           "layouts/categories/list.html",
-          "layouts/taxonomy/category.html.html",
-          "layouts/taxonomy/taxonomy.html.html",
-          "layouts/taxonomy/list.html.html",
-          "layouts/taxonomy/category.html",
-          "layouts/taxonomy/taxonomy.html",
-          "layouts/taxonomy/list.html",
-          "layouts/category/category.html.html",
+          "layouts/category/category.terms.html.html",
+          "layouts/category/terms.html.html",
           "layouts/category/taxonomy.html.html",
           "layouts/category/list.html.html",
-          "layouts/category/category.html",
+          "layouts/category/category.terms.html",
+          "layouts/category/terms.html",
           "layouts/category/taxonomy.html",
           "layouts/category/list.html",
-          "layouts/_default/category.html.html",
+          "layouts/taxonomy/category.terms.html.html",
+          "layouts/taxonomy/terms.html.html",
+          "layouts/taxonomy/taxonomy.html.html",
+          "layouts/taxonomy/list.html.html",
+          "layouts/taxonomy/category.terms.html",
+          "layouts/taxonomy/terms.html",
+          "layouts/taxonomy/taxonomy.html",
+          "layouts/taxonomy/list.html",
+          "layouts/_default/category.terms.html.html",
+          "layouts/_default/terms.html.html",
           "layouts/_default/taxonomy.html.html",
           "layouts/_default/list.html.html",
-          "layouts/_default/category.html",
+          "layouts/_default/category.terms.html",
+          "layouts/_default/terms.html",
           "layouts/_default/taxonomy.html",
           "layouts/_default/list.html"
         ]
       },
       {
         "Example": "Taxonomy term in categories",
-        "Kind": "taxonomyTerm",
+        "Kind": "term",
         "OutputFormat": "HTML",
         "Suffix": "html",
         "Template Lookup Order": [
-          "layouts/categories/category.terms.html.html",
-          "layouts/categories/terms.html.html",
+          "layouts/categories/term.html.html",
+          "layouts/categories/category.html.html",
+          "layouts/categories/taxonomy.html.html",
           "layouts/categories/list.html.html",
-          "layouts/categories/category.terms.html",
-          "layouts/categories/terms.html",
+          "layouts/categories/term.html",
+          "layouts/categories/category.html",
+          "layouts/categories/taxonomy.html",
           "layouts/categories/list.html",
-          "layouts/taxonomy/category.terms.html.html",
-          "layouts/taxonomy/terms.html.html",
+          "layouts/term/term.html.html",
+          "layouts/term/category.html.html",
+          "layouts/term/taxonomy.html.html",
+          "layouts/term/list.html.html",
+          "layouts/term/term.html",
+          "layouts/term/category.html",
+          "layouts/term/taxonomy.html",
+          "layouts/term/list.html",
+          "layouts/taxonomy/term.html.html",
+          "layouts/taxonomy/category.html.html",
+          "layouts/taxonomy/taxonomy.html.html",
           "layouts/taxonomy/list.html.html",
-          "layouts/taxonomy/category.terms.html",
-          "layouts/taxonomy/terms.html",
+          "layouts/taxonomy/term.html",
+          "layouts/taxonomy/category.html",
+          "layouts/taxonomy/taxonomy.html",
           "layouts/taxonomy/list.html",
-          "layouts/category/category.terms.html.html",
-          "layouts/category/terms.html.html",
+          "layouts/category/term.html.html",
+          "layouts/category/category.html.html",
+          "layouts/category/taxonomy.html.html",
           "layouts/category/list.html.html",
-          "layouts/category/category.terms.html",
-          "layouts/category/terms.html",
+          "layouts/category/term.html",
+          "layouts/category/category.html",
+          "layouts/category/taxonomy.html",
           "layouts/category/list.html",
-          "layouts/_default/category.terms.html.html",
-          "layouts/_default/terms.html.html",
+          "layouts/_default/term.html.html",
+          "layouts/_default/category.html.html",
+          "layouts/_default/taxonomy.html.html",
           "layouts/_default/list.html.html",
-          "layouts/_default/category.terms.html",
-          "layouts/_default/terms.html",
+          "layouts/_default/term.html",
+          "layouts/_default/category.html",
+          "layouts/_default/taxonomy.html",
           "layouts/_default/list.html"
         ]
       }
         }
       },
       "crypto": {
+        "HMAC": {
+          "Description": "HMAC returns a cryptographic hash that uses a key to sign a message.",
+          "Args": [
+            "h",
+            "k",
+            "m"
+          ],
+          "Aliases": [
+            "hmac"
+          ],
+          "Examples": [
+            [
+              "{{ hmac \"sha256\" \"Secret key\" \"Hello world, gophers!\" }}",
+              "b6d11b6c53830b9d87036272ca9fe9d19306b8f9d8aa07b15da27d89e6e34f40"
+            ]
+          ]
+        },
         "MD5": {
           "Description": "MD5 hashes the given input and returns its MD5 checksum.",
           "Args": [
               "6ec43b78da9669f50e4e422575c54bf87536954ccd58280219c393f2ce352b46"
             ]
           ]
-        },
-        "HMAC": {
-          "Description": "HMAC hashes the concatenation of a message and a secret key with the given hash function and returns its checksum.",
-          "Args": [
-            "hash function",
-            "message",
-            "key"
-          ],
-          "Aliases": [
-            "hmac"
-          ],
-          "Examples": [
-            [
-              "{{ hmac \"sha256\" \"Hello Gopher!\" \"Hello world, gophers!\" }}",
-              "32aea97d5688891fb35175c5518012323a3079994b909dd6f1bc481e4d0e7ce9"
-            ]
-          ]
         }
       },
       "data": {
             ]
           ]
         },
+        "Pow": {
+          "Description": "Pow returns a raised to the power of b.",
+          "Args": [
+            "a",
+            "b"
+          ],
+          "Aliases": [
+            "pow"
+          ],
+          "Examples": [
+            [
+              "{{math.Pow 2 3}}",
+              "8"
+            ]
+          ]
+        },
         "Round": {
           "Description": "Round returns the nearest integer, rounding half away from zero.",
           "Args": [
         }
       },
       "resources": {
+        "Babel": {
+          "Description": "Babel processes the given Resource with Babel.",
+          "Args": [
+            "args"
+          ],
+          "Aliases": [
+            "babel"
+          ],
+          "Examples": []
+        },
         "Concat": {
           "Description": "",
           "Args": null,
diff --git a/docs/layouts/shortcodes/content-tree.html b/docs/layouts/shortcodes/content-tree.html
new file mode 100644 (file)
index 0000000..0cb527c
--- /dev/null
@@ -0,0 +1,14 @@
+<div class="code">
+    <pre><code>
+        ├── blog
+        │   ├── _index.md [section]
+        │   ├── first-post.md [page]
+        │   └── second-post
+        │       ├── index.md [page bundle]
+        │       └── photo.jpg [page resource]
+        └── tags
+            ├── _index.md [taxonomy]
+            └── funny
+                └── _index.md [term]
+    </code></pre>
+</div>
\ No newline at end of file
diff --git a/docs/layouts/shortcodes/page-kinds.html b/docs/layouts/shortcodes/page-kinds.html
new file mode 100644 (file)
index 0000000..f6cb288
--- /dev/null
@@ -0,0 +1,7 @@
+| Kind | Description | Example |
+|----------------|--------------------------------------------------------------------|-------------------------------------------------------------------------------|
+| `home` | The landing page for the home page | `/index.html` |
+| `page` | The landing page for a given page | `my-post` page (`/posts/my-post/index.html`) |
+| `section` | The landing page of a given section | `posts` section (`/posts/index.html`) |
+| `taxonomy` | The landing page for a taxonomy | `tags` taxonomy (`/tags/index.html`) |
+| `term ` | The landing page for one taxonomy's term | term `awesome` in `tags` taxonomy (`/tags/awesome/index.html`) |
\ No newline at end of file
diff --git a/hugolib/breaking_changes_test.go b/hugolib/breaking_changes_test.go
new file mode 100644 (file)
index 0000000..c935d6e
--- /dev/null
@@ -0,0 +1,141 @@
+// Copyright 2020 The Hugo Authors. All rights reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package hugolib
+
+import (
+       "fmt"
+       "testing"
+
+       qt "github.com/frankban/quicktest"
+)
+
+func Test073(t *testing.T) {
+
+       asertDisabledTaxonomyAndTerm := func(b *sitesBuilder, taxonomy, term bool) {
+               b.Assert(b.CheckExists("public/tags/index.html"), qt.Equals, taxonomy)
+               b.Assert(b.CheckExists("public/tags/tag1/index.html"), qt.Equals, term)
+
+       }
+
+       assertOutputTaxonomyAndTerm := func(b *sitesBuilder, taxonomy, term bool) {
+               b.Assert(b.CheckExists("public/tags/index.json"), qt.Equals, taxonomy)
+               b.Assert(b.CheckExists("public/tags/tag1/index.json"), qt.Equals, term)
+       }
+
+       for _, this := range []struct {
+               name   string
+               config string
+               assert func(err error, out string, b *sitesBuilder)
+       }{
+               {
+                       "Outputs for both taxonomy and taxonomyTerm",
+                       `[outputs]
+ taxonomy = ["JSON"]
+ taxonomyTerm = ["JSON"]
+
+`,
+                       func(err error, out string, b *sitesBuilder) {
+                               b.Assert(err, qt.IsNil)
+                               assertOutputTaxonomyAndTerm(b, true, true)
+
+                       },
+               },
+               {
+                       "Outputs for taxonomyTerm",
+                       `[outputs]
+taxonomyTerm = ["JSON"]
+
+`,
+                       func(err error, out string, b *sitesBuilder) {
+                               b.Assert(err, qt.IsNil)
+                               assertOutputTaxonomyAndTerm(b, true, false)
+
+                       },
+               },
+               {
+                       "Outputs for taxonomy only",
+                       `[outputs]
+taxonomy = ["JSON"]
+
+`,
+                       func(err error, out string, b *sitesBuilder) {
+                               b.Assert(err, qt.Not(qt.IsNil))
+                               b.Assert(out, qt.Contains, `ignoreErrors = ["error-output-taxonomy"]`)
+
+                       },
+               },
+               {
+                       "Outputs for taxonomy only, ignore error",
+                       `
+ignoreErrors = ["error-output-taxonomy"]
+[outputs]
+taxonomy = ["JSON"]
+
+`,
+                       func(err error, out string, b *sitesBuilder) {
+                               b.Assert(err, qt.IsNil)
+                               assertOutputTaxonomyAndTerm(b, true, false)
+
+                       },
+               },
+               {
+                       "Disable both taxonomy and taxonomyTerm",
+                       `disableKinds = ["taxonomy", "taxonomyTerm"]`,
+                       func(err error, out string, b *sitesBuilder) {
+                               b.Assert(err, qt.IsNil)
+                               asertDisabledTaxonomyAndTerm(b, false, false)
+
+                       },
+               },
+               {
+                       "Disable only taxonomyTerm",
+                       `disableKinds = ["taxonomyTerm"]`,
+                       func(err error, out string, b *sitesBuilder) {
+                               b.Assert(err, qt.IsNil)
+                               asertDisabledTaxonomyAndTerm(b, false, true)
+
+                       },
+               },
+               {
+                       "Disable only taxonomy",
+                       `disableKinds = ["taxonomy"]`,
+                       func(err error, out string, b *sitesBuilder) {
+                               b.Assert(err, qt.Not(qt.IsNil))
+                               b.Assert(out, qt.Contains, `ignoreErrors = ["error-disable-taxonomy"]`)
+                       },
+               },
+               {
+                       "Disable only taxonomy, ignore error",
+                       `disableKinds = ["taxonomy"]
+                       ignoreErrors = ["error-disable-taxonomy"]`,
+                       func(err error, out string, b *sitesBuilder) {
+                               b.Assert(err, qt.IsNil)
+                               asertDisabledTaxonomyAndTerm(b, false, true)
+                       },
+               },
+       } {
+
+               t.Run(this.name, func(t *testing.T) {
+                       b := newTestSitesBuilder(t).WithConfigFile("toml", this.config)
+                       b.WithTemplatesAdded("_default/list.json", "JSON")
+                       out, err := captureStdout(func() error {
+                               return b.BuildE(BuildCfg{})
+                       })
+                       fmt.Println(out)
+                       this.assert(err, out, b)
+               })
+
+       }
+
+}
index dd3aa72a683d9f8f9bd753c143f0bba5441d4de9..33fc7ceec275f3fe2590e49ad81c8903b70790b5 100644 (file)
@@ -61,13 +61,13 @@ func TestCascade(t *testing.T) {
                b.Build(BuildCfg{})
 
                b.AssertFileContent("public/index.html", `
-12|taxonomy|categories/cool/_index.md|Cascade Category|cat.png|categories|HTML-|
-12|taxonomy|categories/catsect1|catsect1|cat.png|categories|HTML-|
-12|taxonomy|categories/funny|funny|cat.png|categories|HTML-|
-12|taxonomyTerm|categories/_index.md|My Categories|cat.png|categories|HTML-|
-32|taxonomy|categories/sad/_index.md|Cascade Category|sad.png|categories|HTML-|
-42|taxonomy|tags/blue|blue|home.png|tags|HTML-|
-42|taxonomyTerm|tags|Cascade Home|home.png|tags|HTML-|
+12|term|categories/cool/_index.md|Cascade Category|cat.png|categories|HTML-|
+12|term|categories/catsect1|catsect1|cat.png|categories|HTML-|
+12|term|categories/funny|funny|cat.png|categories|HTML-|
+12|taxonomy|categories/_index.md|My Categories|cat.png|categories|HTML-|
+32|term|categories/sad/_index.md|Cascade Category|sad.png|categories|HTML-|
+42|term|tags/blue|blue|home.png|tags|HTML-|
+42|taxonomy|tags|Cascade Home|home.png|tags|HTML-|
 42|section|sectnocontent|Cascade Home|home.png|sectnocontent|HTML-|
 42|section|sect3|Cascade Home|home.png|sect3|HTML-|
 42|page|bundle1/index.md|Cascade Home|home.png|page|HTML-|
@@ -77,7 +77,7 @@ func TestCascade(t *testing.T) {
 42|page|sect3/p1.md|Cascade Home|home.png|sect3|HTML-|
 42|page|sectnocontent/p1.md|Cascade Home|home.png|sectnocontent|HTML-|
 42|section|sectnofrontmatter/_index.md|Cascade Home|home.png|sectnofrontmatter|HTML-|
-42|taxonomy|tags/green|green|home.png|tags|HTML-|
+42|term|tags/green|green|home.png|tags|HTML-|
 42|home|_index.md|Home|home.png|page|HTML-|
 42|page|p1.md|p1|home.png|page|HTML-|
 42|section|sect1/_index.md|Sect1|sect1.png|stype|HTML-|
index 8af55347897befbc25f16653ac5c728bb2392540..43ad7745d8b3ae55993ff1f28b9abcf86a3f8f5e 100644 (file)
@@ -274,13 +274,13 @@ type contentBundleViewInfo struct {
 
 func (c *contentBundleViewInfo) kind() string {
        if c.termKey != "" {
-               return page.KindTaxonomy
+               return page.KindTerm
        }
-       return page.KindTaxonomyTerm
+       return page.KindTaxonomy
 }
 
 func (c *contentBundleViewInfo) sections() []string {
-       if c.kind() == page.KindTaxonomyTerm {
+       if c.kind() == page.KindTaxonomy {
                return []string{c.name.plural}
        }
 
index b5165b2a53c89a8af1c88999028f3fd74622611a..b32f808c971cc83c66a2b61dc8011e3dd58f2c07 100644 (file)
@@ -106,7 +106,7 @@ func (m *pageMap) newPageFromContentNode(n *contentNode, parentBucket *pagesMapB
        sections := s.sectionsFromFile(f)
 
        kind := s.kindFromFileInfoOrSections(f, sections)
-       if kind == page.KindTaxonomy {
+       if kind == page.KindTerm {
                s.PathSpec.MakePathsSanitized(sections)
        }
 
@@ -535,7 +535,7 @@ func (m *pageMap) assembleTaxonomies() error {
                        }
                } else {
                        title := ""
-                       if kind == page.KindTaxonomy {
+                       if kind == page.KindTerm {
                                title = n.viewInfo.term()
                        }
                        n.p = m.s.newPage(n, parent.p.bucket, kind, title, sections...)
index 9ec30201a388ce4ec7d8f4386a78de63706df542..42a69c26b685ecc1e254a9c1ca7134e185d9fed6 100644 (file)
@@ -451,8 +451,8 @@ Draft5: {{ if (.Site.GetPage "blog/draftsection/sub/page") }}FOUND{{ end }}|
         Pages: /blog/page3/|/blog/subsection/|/blog/page2/|/blog/page1/|/blog/bundle/|
         Sections: /blog/|/docs/|
         Categories: /categories/funny/; funny; 11|
-        Category Terms:  taxonomyTerm: /categories/funny/; funny; 11|
-               Category Funny:  taxonomy; funny: /blog/subsection/page4/;|/blog/page3/;|/blog/subsection/;|/blog/page2/;|/blog/page1/;|/blog/subsection/page5/;|/docs/page6/;|/blog/bundle/;|;|
+        Category Terms:  taxonomy: /categories/funny/; funny; 11|
+               Category Funny:  term; funny: /blog/subsection/page4/;|/blog/page3/;|/blog/subsection/;|/blog/page2/;|/blog/page1/;|/blog/subsection/page5/;|/docs/page6/;|/blog/bundle/;|;|
                Pag Num Pages: 7
         Pag Blog Num Pages: 4
         Blog Num RegularPages: 4
index 87c2b5d3d93a0ea11dc60a69e3f77a1210d57925..4f12ee2b5b4ae10b343100f615675a6fa8945bae 100644 (file)
@@ -28,6 +28,7 @@ func TestDisable(t *testing.T) {
                config := fmt.Sprintf(`
 baseURL = "http://example.com/blog"
 enableRobotsTXT = true
+ignoreErrors = ["error-disable-taxonomy"]
 disableKinds = [%q]
 `, disableKind)
 
@@ -141,7 +142,7 @@ title: Headless Local Lists Sub
                b.Assert(len(s.Taxonomies()["categories"]), qt.Equals, 0)
        })
 
-       disableKind = page.KindTaxonomy
+       disableKind = page.KindTerm
        c.Run("Disable "+disableKind, func(c *qt.C) {
                b := newSitesBuilder(c, disableKind)
                b.Build(BuildCfg{})
@@ -153,7 +154,7 @@ title: Headless Local Lists Sub
                b.Assert(getPage(b, "/categories/mycat"), qt.IsNil)
        })
 
-       disableKind = page.KindTaxonomyTerm
+       disableKind = page.KindTaxonomy
        c.Run("Disable "+disableKind, func(c *qt.C) {
                b := newSitesBuilder(c, disableKind)
                b.Build(BuildCfg{})
@@ -319,7 +320,7 @@ title: Headless Local Lists Sub
 // https://github.com/gohugoio/hugo/issues/6897#issuecomment-587947078
 func TestDisableRSSWithRSSInCustomOutputs(t *testing.T) {
        b := newTestSitesBuilder(t).WithConfigFile("toml", `
-disableKinds = ["taxonomy", "taxonomyTerm", "RSS"]
+disableKinds = ["term", "taxonomy", "RSS"]
 [outputs]
 home = [ "HTML", "RSS" ]
 `).Build(BuildCfg{})
index 16de27b0d07484db1ee8399fa8e5a7494709dbe1..e71e48d4124ff8a4ab87d83be8fdd0df504da3cb 100644 (file)
@@ -443,8 +443,8 @@ func applyDeps(cfg deps.DepsCfg, sites ...*Site) error {
                                contentMap: newContentMap(contentMapConfig{
                                        lang:                 s.Lang(),
                                        taxonomyConfig:       s.siteCfg.taxonomiesConfig.Values(),
-                                       taxonomyDisabled:     !s.isEnabled(page.KindTaxonomy),
-                                       taxonomyTermDisabled: !s.isEnabled(page.KindTaxonomyTerm),
+                                       taxonomyDisabled:     !s.isEnabled(page.KindTerm),
+                                       taxonomyTermDisabled: !s.isEnabled(page.KindTaxonomy),
                                        pageDisabled:         !s.isEnabled(page.KindPage),
                                }),
                                s: s,
@@ -493,6 +493,9 @@ func applyDeps(cfg deps.DepsCfg, sites ...*Site) error {
 
 // NewHugoSites creates HugoSites from the given config.
 func NewHugoSites(cfg deps.DepsCfg) (*HugoSites, error) {
+       if cfg.Logger == nil {
+               cfg.Logger = loggers.NewErrorLogger()
+       }
        sites, err := createSitesFromConfig(cfg)
        if err != nil {
                return nil, errors.Wrap(err, "from config")
index 59f228fef022b87a9a863ceb37d92e040e626f1b..84655c1f20d455bb8ba17a3af8caf0beef50ffe9 100644 (file)
@@ -339,14 +339,14 @@ func doTestMultiSitesBuild(t *testing.T, configTemplate, configSuffix string) {
 
        nnSite := sites[2]
        c.Assert(nnSite.language.Lang, qt.Equals, "nn")
-       taxNn := nnSite.getPage(page.KindTaxonomyTerm, "lag")
+       taxNn := nnSite.getPage(page.KindTaxonomy, "lag")
        c.Assert(taxNn, qt.Not(qt.IsNil))
        c.Assert(len(taxNn.Translations()), qt.Equals, 1)
        c.Assert(taxNn.Translations()[0].Language().Lang, qt.Equals, "nb")
 
-       taxTermNn := nnSite.getPage(page.KindTaxonomy, "lag", "sogndal")
+       taxTermNn := nnSite.getPage(page.KindTerm, "lag", "sogndal")
        c.Assert(taxTermNn, qt.Not(qt.IsNil))
-       c.Assert(nnSite.getPage(page.KindTaxonomy, "LAG", "SOGNDAL"), qt.Equals, taxTermNn)
+       c.Assert(nnSite.getPage(page.KindTerm, "LAG", "SOGNDAL"), qt.Equals, taxTermNn)
        c.Assert(len(taxTermNn.Translations()), qt.Equals, 1)
        c.Assert(taxTermNn.Translations()[0].Language().Lang, qt.Equals, "nb")
 
index 406255d51c74acfe0c225d815b9b7216eeab9a57..5aa5082901f62fc144d30f34075400e7721eb5ab 100644 (file)
@@ -27,7 +27,7 @@ func TestHello(t *testing.T) {
        b := newTestSitesBuilder(t)
        b.WithConfigFile("toml", `
 baseURL="https://example.org"
-disableKinds = ["taxonomy", "taxonomyTerm", "section", "page"]
+disableKinds = ["term", "taxonomy", "section", "page"]
 `)
        b.WithContent("p1", `
 ---
index baf5e7f69151a573407d0757b74990e513123fcd..28ef1e156ab9442b49f4743553f13c4b9cf4215d 100644 (file)
@@ -212,9 +212,9 @@ func (p *pageState) RegularPages() page.Pages {
 
                switch p.Kind() {
                case page.KindPage:
-               case page.KindSection, page.KindHome, page.KindTaxonomyTerm:
+               case page.KindSection, page.KindHome, page.KindTaxonomy:
                        pages = p.getPages()
-               case page.KindTaxonomy:
+               case page.KindTerm:
                        all := p.Pages()
                        for _, p := range all {
                                if p.IsPage() {
@@ -240,9 +240,9 @@ func (p *pageState) Pages() page.Pages {
                case page.KindPage:
                case page.KindSection, page.KindHome:
                        pages = p.getPagesAndSections()
-               case page.KindTaxonomy:
+               case page.KindTerm:
                        pages = p.bucket.getTaxonomyEntries()
-               case page.KindTaxonomyTerm:
+               case page.KindTaxonomy:
                        pages = p.bucket.getTaxonomies()
                default:
                        pages = p.s.Pages()
@@ -436,7 +436,7 @@ func (p *pageState) getLayoutDescriptor() output.LayoutDescriptor {
                        if len(sections) > 0 {
                                section = sections[0]
                        }
-               case page.KindTaxonomyTerm, page.KindTaxonomy:
+               case page.KindTaxonomy, page.KindTerm:
                        b := p.getTreeRef().n
                        section = b.viewInfo.name.singular
                default:
index 131bf8d5d27f41b119d5c72c4283b513fa96a86a..9fc97f8f614cef025f17723ceeb0a0f308f2e663 100644 (file)
@@ -35,7 +35,7 @@ func (p *pageData) Data() interface{} {
                }
 
                switch p.Kind() {
-               case page.KindTaxonomy:
+               case page.KindTerm:
                        b := p.treeRef.n
                        name := b.viewInfo.name
                        termKey := b.viewInfo.termKey
@@ -46,7 +46,7 @@ func (p *pageData) Data() interface{} {
                        p.data["Singular"] = name.singular
                        p.data["Plural"] = name.plural
                        p.data["Term"] = b.viewInfo.term()
-               case page.KindTaxonomyTerm:
+               case page.KindTaxonomy:
                        b := p.treeRef.n
                        name := b.viewInfo.name
 
index 435b95473386d1cb77a6febe598b25541ee30711..c7226c6f2fa286c1e3450b66a27b6ea5ff7ae981 100644 (file)
@@ -52,7 +52,7 @@ type pageMeta struct {
        // in the different page collections. This can, as an example, be used
        // to to filter regular pages, find sections etc.
        // Kind will, for the pages available to the templates, be one of:
-       // page, home, section, taxonomy and taxonomyTerm.
+       // page, home, section, taxonomy and term.
        // It is of string type to make it easy to reason about in
        // the templates.
        kind string
@@ -678,11 +678,11 @@ func (p *pageMeta) applyDefaultValues(n *contentNode) error {
                        } else {
                                p.title = sectionName
                        }
-               case page.KindTaxonomy:
+               case page.KindTerm:
                        // TODO(bep) improve
                        key := p.sections[len(p.sections)-1]
                        p.title = strings.Replace(p.s.titleFunc(key), "-", " ", -1)
-               case page.KindTaxonomyTerm:
+               case page.KindTaxonomy:
                        p.title = p.s.titleFunc(p.sections[0])
                case kind404:
                        p.title = "404 Page not found"
index 942597e04e6f5b74a5fda654298fb142a6fc1e28..5948735d1bcf1a198756dc109b0daa7c52178eca 100644 (file)
@@ -89,7 +89,7 @@ func (p *pagePaginator) Paginator(options ...interface{}) (*page.Pager, error) {
                        // section. To avoid the default paginators for the home page
                        // changing in the wild, we make this a special case.
                        pages = p.source.s.RegularPages()
-               case page.KindTaxonomy, page.KindTaxonomyTerm:
+               case page.KindTerm, page.KindTaxonomy:
                        pages = p.source.Pages()
                default:
                        pages = p.source.RegularPages()
index 5dc42bc2ac829ca6c11c5ee312df5054f99be894..d0bf26961dfa78af4860d6e07f16f6ad0fc6ee60 100644 (file)
@@ -147,7 +147,7 @@ func createTargetPathDescriptor(s *Site, p page.Page, pm *pageMeta) (page.Target
        // the permalink configuration values are likely to be redundant, e.g.
        // naively expanding /category/:slug/ would give /category/categories/ for
        // the "categories" page.KindTaxonomyTerm.
-       if p.Kind() == page.KindPage || p.Kind() == page.KindTaxonomy {
+       if p.Kind() == page.KindPage || p.Kind() == page.KindTerm {
                opath, err := d.ResourceSpec.Permalinks.Expand(p.Section(), p)
                if err != nil {
                        return desc, err
index d2ef00e7614798dfb33f28d6ad4b65bd55762915..a617ad38453bf85e0afd39798abac8aca9cf10d3 100644 (file)
@@ -171,7 +171,7 @@ func (pt pageTree) Parent() page.Page {
 
        tree := p.getTreeRef()
 
-       if tree == nil || pt.p.Kind() == page.KindTaxonomyTerm {
+       if tree == nil || pt.p.Kind() == page.KindTaxonomy {
                return pt.p.s.home
        }
 
index 4f000c3e58fac411b5c2a6c947bf5d9b6c0db084..683d12c1bf1342a5ccd6101a9314214f3ab4d3b3 100644 (file)
@@ -22,7 +22,7 @@ import (
 var (
 
        // This is all the kinds we can expect to find in .Site.Pages.
-       allKindsInPages = []string{page.KindPage, page.KindHome, page.KindSection, page.KindTaxonomy, page.KindTaxonomyTerm}
+       allKindsInPages = []string{page.KindPage, page.KindHome, page.KindSection, page.KindTerm, page.KindTaxonomy}
 )
 
 const (
index 4566c5f976dcb15492bbe63f1e57d0a658f65595..fa420a025aaafa7cd03f80c2d03e4c066308a0e9 100644 (file)
@@ -1145,7 +1145,7 @@ func TestPageBundlerPartialTranslations(t *testing.T) {
 baseURL = "https://example.org"
 defaultContentLanguage = "en"
 defaultContentLanguageInSubDir = true
-disableKinds = ["taxonomyTerm", "taxonomy"]
+disableKinds = ["taxonomy", "term"]
 [languages]
 [languages.nn]
 languageName = "Nynorsk"
index bb846da854ee1e6b6a46f9dae6c00cf2ed04f272..b9623eb34373dfe40df946d5efe2d97ea78f6084 100644 (file)
@@ -279,8 +279,8 @@ func TestGetPage(t *testing.T) {
                {"Abs, ignore context, page deep", "NoPage", sec3, []string{"/subsect/deep.md"}, ""},
 
                // Taxonomies
-               {"Taxonomy term", page.KindTaxonomyTerm, nil, []string{"categories"}, "Categories"},
-               {"Taxonomy", page.KindTaxonomy, nil, []string{"categories/hugo", "categories/Hugo"}, "Hugo"},
+               {"Taxonomy term", page.KindTaxonomy, nil, []string{"categories"}, "Categories"},
+               {"Taxonomy", page.KindTerm, nil, []string{"categories/hugo", "categories/Hugo"}, "Hugo"},
 
                // Bundle variants
                {"Bundle regular", page.KindPage, nil, []string{"sect3/b1", "sect3/b1/index.md", "sect3/b1/index.en.md"}, "b1 bundle"},
index c9ddb2140b1e5835775184f6fdc7aa4cc4f17b1b..d3351dfd46812f28367bcce16e49c500233825b8 100644 (file)
@@ -82,7 +82,7 @@ class Car {
 
        v := viper.New()
        v.Set("workingDir", workDir)
-       v.Set("disableKinds", []string{"taxonomyTerm", "taxonomy", "page"})
+       v.Set("disableKinds", []string{"taxonomy", "term", "page"})
        b := newTestSitesBuilder(t).WithLogger(loggers.NewWarningLogger())
 
        // Need to use OS fs for this.
index 67641bdb8b6b308e7b6f23484ec74815df1275cd..c687ca3421b217224a6419ab2b8309b9944f50d7 100644 (file)
@@ -895,7 +895,7 @@ h1 {
 
        newTestBuilder := func(v *viper.Viper) *sitesBuilder {
                v.Set("workingDir", workDir)
-               v.Set("disableKinds", []string{"taxonomyTerm", "taxonomy", "page"})
+               v.Set("disableKinds", []string{"taxonomy", "term", "page"})
                b := newTestSitesBuilder(t).WithLogger(loggers.NewWarningLogger())
                // Need to use OS fs for this.
                b.Fs = hugofs.NewDefault(v)
index 8bb46846512640020b3f00405661a2871d8ff259..961450cb856ae21589bf7f0e017fb701fdcf97a6 100644 (file)
@@ -626,7 +626,7 @@ baseURL = "http://example.com/blog"
 
 paginate = 1
 
-disableKinds = ["section", "taxonomy", "taxonomyTerm", "RSS", "sitemap", "robotsTXT", "404"]
+disableKinds = ["section", "term", "taxonomy", "RSS", "sitemap", "robotsTXT", "404"]
 
 [outputs]
 home = [ "HTML", "AMP", "Calendar" ]
index a0390780aa92302fde1dcffca83fc53c63c3f353..5507d7a787eb9baf4c52435ffb1fbc9d19c956fd 100644 (file)
@@ -28,6 +28,10 @@ import (
        "strings"
        "time"
 
+       "github.com/gohugoio/hugo/common/constants"
+
+       "github.com/gohugoio/hugo/common/loggers"
+
        "github.com/gohugoio/hugo/resources"
 
        "github.com/gohugoio/hugo/identity"
@@ -397,12 +401,34 @@ func newSite(cfg deps.DepsCfg) (*Site, error) {
        if cfg.Language == nil {
                cfg.Language = langs.NewDefaultLanguage(cfg.Cfg)
        }
+       if cfg.Logger == nil {
+               panic("logger must be set")
+       }
+
+       ignoreErrors := cast.ToStringSlice(cfg.Language.Get("ignoreErrors"))
+       ignorableLogger := loggers.NewIgnorableLogger(cfg.Logger, ignoreErrors...)
 
        disabledKinds := make(map[string]bool)
        for _, disabled := range cast.ToStringSlice(cfg.Language.Get("disableKinds")) {
                disabledKinds[disabled] = true
        }
 
+       if disabledKinds["taxonomyTerm"] {
+               // Correct from the value it had before Hugo 0.73.0.
+               if disabledKinds[page.KindTaxonomy] {
+                       disabledKinds[page.KindTerm] = true
+               } else {
+                       disabledKinds[page.KindTaxonomy] = true
+               }
+
+               delete(disabledKinds, "taxonomyTerm")
+       } else if disabledKinds[page.KindTaxonomy] && !disabledKinds[page.KindTerm] {
+               // This is a potentially ambigous situation. It may be correct.
+               ignorableLogger.Errorf(constants.ErrIDAmbigousDisableKindTaxonomy, `You have the value 'taxonomy' in the disabledKinds list. In Hugo 0.73.0 we fixed these to be what most people expect (taxonomy and term).
+But this also means that your site configuration may not do what you expect. If it is correct, you can suppress this message by following the instructions below.`)
+
+       }
+
        var (
                mediaTypesConfig    []map[string]interface{}
                outputFormatsConfig []map[string]interface{}
@@ -444,7 +470,30 @@ func newSite(cfg deps.DepsCfg) (*Site, error) {
                siteOutputFormatsConfig = tmp
        }
 
-       outputFormats, err := createSiteOutputFormats(siteOutputFormatsConfig, cfg.Language, rssDisabled)
+       var siteOutputs map[string]interface{}
+       if cfg.Language.IsSet("outputs") {
+               siteOutputs = cfg.Language.GetStringMap("outputs")
+
+               // Check and correct taxonomy kinds vs pre Hugo 0.73.0.
+               v1, hasTaxonomyTerm := siteOutputs["taxonomyterm"]
+               v2, hasTaxonomy := siteOutputs[page.KindTaxonomy]
+               _, hasTerm := siteOutputs[page.KindTerm]
+               if hasTaxonomy && hasTaxonomyTerm {
+                       siteOutputs[page.KindTaxonomy] = v1
+                       siteOutputs[page.KindTerm] = v2
+                       delete(siteOutputs, "taxonomyTerm")
+               } else if hasTaxonomy && !hasTerm {
+                       // This is a potentially ambigous situation. It may be correct.
+                       ignorableLogger.Errorf(constants.ErrIDAmbigousOutputKindTaxonomy, `You have configured output formats for 'taxonomy' in your site configuration. In Hugo 0.73.0 we fixed these to be what most people expect (taxonomy and term).
+But this also means that your site configuration may not do what you expect. If it is correct, you can suppress this message by following the instructions below.`)
+               }
+               if !hasTaxonomy && hasTaxonomyTerm {
+                       siteOutputs[page.KindTaxonomy] = v1
+                       delete(siteOutputs, "taxonomyterm")
+               }
+       }
+
+       outputFormats, err := createSiteOutputFormats(siteOutputFormatsConfig, siteOutputs, rssDisabled)
        if err != nil {
                return nil, err
        }
@@ -1708,11 +1757,11 @@ func (s *Site) kindFromSections(sections []string) string {
 func (s *Site) kindFromSectionPath(sectionPath string) string {
        for _, plural := range s.siteCfg.taxonomiesConfig {
                if plural == sectionPath {
-                       return page.KindTaxonomyTerm
+                       return page.KindTaxonomy
                }
 
                if strings.HasPrefix(sectionPath, plural) {
-                       return page.KindTaxonomy
+                       return page.KindTerm
                }
 
        }
index d064348a64882504a7da5db7004bdfdeb86200aa..6a630f4eacc157eced75090f5684e4d50f68cc74 100644 (file)
@@ -17,13 +17,12 @@ import (
        "fmt"
        "strings"
 
-       "github.com/gohugoio/hugo/config"
        "github.com/gohugoio/hugo/output"
        "github.com/gohugoio/hugo/resources/page"
        "github.com/spf13/cast"
 )
 
-func createDefaultOutputFormats(allFormats output.Formats, cfg config.Provider) map[string]output.Formats {
+func createDefaultOutputFormats(allFormats output.Formats) map[string]output.Formats {
        rssOut, rssFound := allFormats.GetByName(output.RSSFormat.Name)
        htmlOut, _ := allFormats.GetByName(output.HTMLFormat.Name)
        robotsOut, _ := allFormats.GetByName(output.RobotsTxtFormat.Name)
@@ -35,11 +34,11 @@ func createDefaultOutputFormats(allFormats output.Formats, cfg config.Provider)
        }
 
        m := map[string]output.Formats{
-               page.KindPage:         {htmlOut},
-               page.KindHome:         defaultListTypes,
-               page.KindSection:      defaultListTypes,
-               page.KindTaxonomy:     defaultListTypes,
-               page.KindTaxonomyTerm: defaultListTypes,
+               page.KindPage:     {htmlOut},
+               page.KindHome:     defaultListTypes,
+               page.KindSection:  defaultListTypes,
+               page.KindTerm:     defaultListTypes,
+               page.KindTaxonomy: defaultListTypes,
                // Below are for consistency. They are currently not used during rendering.
                kindSitemap:   {sitemapOut},
                kindRobotsTXT: {robotsOut},
@@ -55,17 +54,15 @@ func createDefaultOutputFormats(allFormats output.Formats, cfg config.Provider)
 
 }
 
-func createSiteOutputFormats(allFormats output.Formats, cfg config.Provider, rssDisabled bool) (map[string]output.Formats, error) {
-       defaultOutputFormats := createDefaultOutputFormats(allFormats, cfg)
+func createSiteOutputFormats(allFormats output.Formats, outputs map[string]interface{}, rssDisabled bool) (map[string]output.Formats, error) {
+       defaultOutputFormats := createDefaultOutputFormats(allFormats)
 
-       if !cfg.IsSet("outputs") {
+       if outputs == nil {
                return defaultOutputFormats, nil
        }
 
        outFormats := make(map[string]output.Formats)
 
-       outputs := cfg.GetStringMap("outputs")
-
        if len(outputs) == 0 {
                return outFormats, nil
        }
index 232364577e8bde0e66dd4a70ddf1b80ab85de9e3..c324be7dde1c76e57c0b426fb065196894d8881a 100644 (file)
@@ -49,7 +49,7 @@ baseURL = "http://example.com/blog"
 paginate = 1
 defaultContentLanguage = "en"
 
-disableKinds = ["section", "taxonomy", "taxonomyTerm", "RSS", "sitemap", "robotsTXT", "404"]
+disableKinds = ["section", "term", "taxonomy", "RSS", "sitemap", "robotsTXT", "404"]
 
 [Taxonomies]
 tag = "tags"
@@ -226,7 +226,7 @@ baseURL = "http://example.com/blog"
 paginate = 1
 defaultContentLanguage = "en"
 
-disableKinds = ["page", "section", "taxonomy", "taxonomyTerm", "sitemap", "robotsTXT", "404"]
+disableKinds = ["page", "section", "term", "taxonomy", "sitemap", "robotsTXT", "404"]
 
 [outputFormats]
 [outputFormats.RSS]
@@ -263,7 +263,7 @@ baseURL = "http://example.com/blog"
 paginate = 1
 defaultContentLanguage = "en"
 
-disableKinds = ["page", "section", "taxonomy", "taxonomyTerm", "sitemap", "robotsTXT", "404"]
+disableKinds = ["page", "section", "term", "taxonomy", "sitemap", "robotsTXT", "404"]
 
 [mediaTypes]
 [mediaTypes."text/nodot"]
@@ -341,14 +341,14 @@ func TestCreateSiteOutputFormats(t *testing.T) {
                cfg := viper.New()
                cfg.Set("outputs", outputsConfig)
 
-               outputs, err := createSiteOutputFormats(output.DefaultFormats, cfg, false)
+               outputs, err := createSiteOutputFormats(output.DefaultFormats, cfg.GetStringMap("outputs"), false)
                c.Assert(err, qt.IsNil)
                c.Assert(outputs[page.KindSection], deepEqualsOutputFormats, output.Formats{output.JSONFormat})
                c.Assert(outputs[page.KindHome], deepEqualsOutputFormats, output.Formats{output.HTMLFormat, output.JSONFormat})
 
                // Defaults
+               c.Assert(outputs[page.KindTerm], deepEqualsOutputFormats, output.Formats{output.HTMLFormat, output.RSSFormat})
                c.Assert(outputs[page.KindTaxonomy], deepEqualsOutputFormats, output.Formats{output.HTMLFormat, output.RSSFormat})
-               c.Assert(outputs[page.KindTaxonomyTerm], deepEqualsOutputFormats, output.Formats{output.HTMLFormat, output.RSSFormat})
                c.Assert(outputs[page.KindPage], deepEqualsOutputFormats, output.Formats{output.HTMLFormat})
 
                // These aren't (currently) in use when rendering in Hugo,
@@ -367,13 +367,15 @@ func TestCreateSiteOutputFormats(t *testing.T) {
                cfg := viper.New()
 
                outputsConfig := map[string]interface{}{
+                       // Note that we in Hugo 0.53.0 renamed this Kind to "taxonomy",
+                       // but keep this test to test the legacy mapping.
                        "taxonomyterm": []string{"JSON"},
                }
                cfg.Set("outputs", outputsConfig)
 
-               outputs, err := createSiteOutputFormats(output.DefaultFormats, cfg, false)
+               outputs, err := createSiteOutputFormats(output.DefaultFormats, cfg.GetStringMap("outputs"), false)
                c.Assert(err, qt.IsNil)
-               c.Assert(outputs[page.KindTaxonomyTerm], deepEqualsOutputFormats, output.Formats{output.JSONFormat})
+               c.Assert(outputs[page.KindTaxonomy], deepEqualsOutputFormats, output.Formats{output.JSONFormat})
 
        })
 
@@ -389,7 +391,7 @@ func TestCreateSiteOutputFormatsInvalidConfig(t *testing.T) {
        cfg := viper.New()
        cfg.Set("outputs", outputsConfig)
 
-       _, err := createSiteOutputFormats(output.DefaultFormats, cfg, false)
+       _, err := createSiteOutputFormats(output.DefaultFormats, cfg.GetStringMap("outputs"), false)
        c.Assert(err, qt.Not(qt.IsNil))
 }
 
@@ -403,7 +405,7 @@ func TestCreateSiteOutputFormatsEmptyConfig(t *testing.T) {
        cfg := viper.New()
        cfg.Set("outputs", outputsConfig)
 
-       outputs, err := createSiteOutputFormats(output.DefaultFormats, cfg, false)
+       outputs, err := createSiteOutputFormats(output.DefaultFormats, cfg.GetStringMap("outputs"), false)
        c.Assert(err, qt.IsNil)
        c.Assert(outputs[page.KindHome], deepEqualsOutputFormats, output.Formats{output.HTMLFormat, output.RSSFormat})
 }
@@ -423,7 +425,7 @@ func TestCreateSiteOutputFormatsCustomFormats(t *testing.T) {
                customHTML = output.Format{Name: "HTML", BaseName: "customHTML"}
        )
 
-       outputs, err := createSiteOutputFormats(output.Formats{customRSS, customHTML}, cfg, false)
+       outputs, err := createSiteOutputFormats(output.Formats{customRSS, customHTML}, cfg.GetStringMap("outputs"), false)
        c.Assert(err, qt.IsNil)
        c.Assert(outputs[page.KindHome], deepEqualsOutputFormats, output.Formats{customHTML, customRSS})
 }
index 54c2fbe59d4a5b9a9b146cc36fd1289144c0e389..a2b3a04515f3c8f3a0683606bc2185dd138c185b 100644 (file)
@@ -1066,7 +1066,7 @@ func TestClassCollectorStress(t *testing.T) {
        b := newTestSitesBuilder(t)
        b.WithConfigFile("toml", `
        
-disableKinds = ["home", "section", "taxonomy", "taxonomyTerm" ]
+disableKinds = ["home", "section", "term", "taxonomy" ]
 
 [languages]
 [languages.en]
index 64f560d251a4371b5b90afaaeee1d0f1ece26acf..4eeb92e06a01384ffb739b5e56842681682aabc5 100644 (file)
@@ -167,16 +167,16 @@ permalinkeds:
 
        for taxonomy, count := range taxonomyTermPageCounts {
                msg := qt.Commentf(taxonomy)
-               term := s.getPage(page.KindTaxonomyTerm, taxonomy)
+               term := s.getPage(page.KindTaxonomy, taxonomy)
                b.Assert(term, qt.Not(qt.IsNil), msg)
                b.Assert(len(term.Pages()), qt.Equals, count, msg)
 
                for _, p := range term.Pages() {
-                       b.Assert(p.Kind(), qt.Equals, page.KindTaxonomy)
+                       b.Assert(p.Kind(), qt.Equals, page.KindTerm)
                }
        }
 
-       cat1 := s.getPage(page.KindTaxonomy, "categories", "cat1")
+       cat1 := s.getPage(page.KindTerm, "categories", "cat1")
        b.Assert(cat1, qt.Not(qt.IsNil))
        if uglyURLs {
                b.Assert(cat1.RelPermalink(), qt.Equals, "/blog/categories/cat1.html")
@@ -184,8 +184,8 @@ permalinkeds:
                b.Assert(cat1.RelPermalink(), qt.Equals, "/blog/categories/cat1/")
        }
 
-       pl1 := s.getPage(page.KindTaxonomy, "permalinkeds", "pl1")
-       permalinkeds := s.getPage(page.KindTaxonomyTerm, "permalinkeds")
+       pl1 := s.getPage(page.KindTerm, "permalinkeds", "pl1")
+       permalinkeds := s.getPage(page.KindTaxonomy, "permalinkeds")
        b.Assert(pl1, qt.Not(qt.IsNil))
        b.Assert(permalinkeds, qt.Not(qt.IsNil))
        if uglyURLs {
@@ -196,7 +196,7 @@ permalinkeds:
                b.Assert(permalinkeds.RelPermalink(), qt.Equals, "/blog/permalinkeds/")
        }
 
-       helloWorld := s.getPage(page.KindTaxonomy, "others", "hello-hugo-world")
+       helloWorld := s.getPage(page.KindTerm, "others", "hello-hugo-world")
        b.Assert(helloWorld, qt.Not(qt.IsNil))
        b.Assert(helloWorld.Title(), qt.Equals, "Hello Hugo world")
 
@@ -269,8 +269,8 @@ title: "This is S3s"
                return pages
        }
 
-       ta := filterbyKind(page.KindTaxonomy)
-       te := filterbyKind(page.KindTaxonomyTerm)
+       ta := filterbyKind(page.KindTerm)
+       te := filterbyKind(page.KindTaxonomy)
 
        b.Assert(len(te), qt.Equals, 4)
        b.Assert(len(ta), qt.Equals, 7)
@@ -637,7 +637,7 @@ Cats Paginator {{ range $cats.Paginator.Pages }}{{ .RelPermalink }}|{{ end }}:EN
        b.Assert(funny, qt.Not(qt.IsNil))
 
        b.Assert(cat.Parent().IsHome(), qt.Equals, true)
-       b.Assert(funny.Kind(), qt.Equals, "taxonomy")
+       b.Assert(funny.Kind(), qt.Equals, "term")
        b.Assert(funny.Parent(), qt.Equals, cat)
 
        b.AssertFileContent("public/index.html", `
@@ -697,13 +697,13 @@ abcdefgs: {{ template "print-page" $abcdefgs }}|IsAncestor: {{ $abcdefgs.IsAnces
     Page: /abcdefgh/|abcdefgh|section|Parent: /|CurrentSection: /abcdefgh/|
     Page: /abcdefgh/p1/|abcdefgh-p|page|Parent: /abcdefgh/|CurrentSection: /abcdefgh/|
     Page: /abcdefghijk/|abcdefghijk|page|Parent: /|CurrentSection: /|
-    Page: /abcdefghis/|Abcdefghis|taxonomyTerm|Parent: /|CurrentSection: /|
-    Page: /abcdefgs/|Abcdefgs|taxonomyTerm|Parent: /|CurrentSection: /|
-    Page: /abcdefs/|Abcdefs|taxonomyTerm|Parent: /|CurrentSection: /|
-    abc: /abcdefgs/abc/|abc|taxonomy|Parent: /abcdefgs/|CurrentSection: /abcdefgs/|
-    abcdefgs: /abcdefgs/|Abcdefgs|taxonomyTerm|Parent: /|CurrentSection: /|
-    abc: /abcdefgs/abc/|abc|taxonomy|Parent: /abcdefgs/|CurrentSection: /abcdefgs/|FirstSection: /|IsAncestor: false|IsDescendant: true
-    abcdefgs: /abcdefgs/|Abcdefgs|taxonomyTerm|Parent: /|CurrentSection: /|FirstSection: /|IsAncestor: true|IsDescendant: false
+    Page: /abcdefghis/|Abcdefghis|taxonomy|Parent: /|CurrentSection: /|
+    Page: /abcdefgs/|Abcdefgs|taxonomy|Parent: /|CurrentSection: /|
+    Page: /abcdefs/|Abcdefs|taxonomy|Parent: /|CurrentSection: /|
+    abc: /abcdefgs/abc/|abc|term|Parent: /abcdefgs/|CurrentSection: /abcdefgs/|
+    abcdefgs: /abcdefgs/|Abcdefgs|taxonomy|Parent: /|CurrentSection: /|
+    abc: /abcdefgs/abc/|abc|term|Parent: /abcdefgs/|CurrentSection: /abcdefgs/|FirstSection: /|IsAncestor: false|IsDescendant: true
+    abcdefgs: /abcdefgs/|Abcdefgs|taxonomy|Parent: /|CurrentSection: /|FirstSection: /|IsAncestor: true|IsDescendant: false
 `)
 
 }
index eace35c971e708d2974eb07a66367dd86bd07b75..c1ee27557eade35216685d6eb10bb94acc3ec59b 100644 (file)
@@ -1070,3 +1070,18 @@ func captureStderr(f func() error) (string, error) {
        io.Copy(&buf, r)
        return buf.String(), err
 }
+
+func captureStdout(f func() error) (string, error) {
+       old := os.Stdout
+       r, w, _ := os.Pipe()
+       os.Stdout = w
+
+       err := f()
+
+       w.Close()
+       os.Stdout = old
+
+       var buf bytes.Buffer
+       io.Copy(&buf, r)
+       return buf.String(), err
+}
index 13291ce9ae849f45e3f7b83356756c143946117d..450c323d1679a52f8f7fa4e3f622cf2c305ee1dd 100644 (file)
@@ -60,14 +60,14 @@ func createLayoutExamples() interface{} {
                {"JSON home", LayoutDescriptor{Kind: "home", Type: "page"}, JSONFormat},
                {"RSS home", LayoutDescriptor{Kind: "home", Type: "page"}, RSSFormat},
                {"RSS section posts", LayoutDescriptor{Kind: "section", Type: "posts"}, RSSFormat},
-               {"Taxonomy list in categories", LayoutDescriptor{Kind: "taxonomy", Type: "categories", Section: "category"}, RSSFormat},
-               {"Taxonomy terms in categories", LayoutDescriptor{Kind: "taxonomyTerm", Type: "categories", Section: "category"}, RSSFormat},
+               {"Taxonomy in categories", LayoutDescriptor{Kind: "taxonomy", Type: "categories", Section: "category"}, RSSFormat},
+               {"Term in categories", LayoutDescriptor{Kind: "term", Type: "categories", Section: "category"}, RSSFormat},
                {"Section list for \"posts\" section", LayoutDescriptor{Kind: "section", Type: "posts", Section: "posts"}, HTMLFormat},
                {"Section list for \"posts\" section with type set to \"blog\"", LayoutDescriptor{Kind: "section", Type: "blog", Section: "posts"}, HTMLFormat},
                {"Section list for \"posts\" section with layout set to \"demoLayout\"", LayoutDescriptor{Kind: "section", Layout: demoLayout, Section: "posts"}, HTMLFormat},
 
                {"Taxonomy list in categories", LayoutDescriptor{Kind: "taxonomy", Type: "categories", Section: "category"}, HTMLFormat},
-               {"Taxonomy term in categories", LayoutDescriptor{Kind: "taxonomyTerm", Type: "categories", Section: "category"}, HTMLFormat},
+               {"Taxonomy term in categories", LayoutDescriptor{Kind: "term", Type: "categories", Section: "category"}, HTMLFormat},
        } {
 
                l := NewLayoutHandler()
index 09ac7b2f62ab2b5edcbafe9278fc18a137758def..4dd37b7b186b6dc09e4f6f0251fe637ae511cd2c 100644 (file)
@@ -160,20 +160,22 @@ func resolvePageTemplate(d LayoutDescriptor, f Format) []string {
                }
                b.addSectionType()
                b.addKind()
-       case "taxonomy":
+       case "term":
+               b.addKind()
                if d.Section != "" {
                        b.addLayoutVariations(d.Section)
                }
-               b.addKind()
+               b.addLayoutVariations("taxonomy")
+               b.addTypeVariations("taxonomy")
                b.addSectionType()
-
-       case "taxonomyTerm":
+       case "taxonomy":
                if d.Section != "" {
                        b.addLayoutVariations(d.Section + ".terms")
                }
-               b.addTypeVariations("taxonomy")
                b.addSectionType()
                b.addLayoutVariations("terms")
+               // For legacy reasons this is deliberately put last.
+               b.addKind()
        case "404":
                b.addLayoutVariations("404")
                b.addTypeVariations("")
index d5b6c7bcaeb2ca163fac6305b9737cb60b318ded..a85f6fc6d1be5b1652b40685adbfc1b89d463c81 100644 (file)
@@ -88,10 +88,10 @@ func TestLayout(t *testing.T) {
                        []string{"sect1/sect1-baseof.amp.html", "sect1/section-baseof.amp.html", "sect1/list-baseof.amp.html", "sect1/baseof.amp.html", "sect1/sect1-baseof.html", "sect1/section-baseof.html", "sect1/list-baseof.html", "sect1/baseof.html"}, 24},
                {"Section with layout", LayoutDescriptor{Kind: "section", Section: "sect1", Layout: "mylayout"}, "", ampType,
                        []string{"sect1/mylayout.amp.html", "sect1/sect1.amp.html", "sect1/section.amp.html", "sect1/list.amp.html", "sect1/mylayout.html", "sect1/sect1.html"}, 24},
-               {"Taxonomy", LayoutDescriptor{Kind: "taxonomy", Section: "tag"}, "", ampType,
-                       []string{"taxonomy/tag.amp.html", "taxonomy/taxonomy.amp.html", "taxonomy/list.amp.html", "taxonomy/tag.html", "taxonomy/taxonomy.html"}, 18},
-               {"Taxonomy term", LayoutDescriptor{Kind: "taxonomyTerm", Section: "categories"}, "", ampType,
-                       []string{"taxonomy/categories.terms.amp.html", "taxonomy/terms.amp.html", "taxonomy/list.amp.html", "taxonomy/categories.terms.html", "taxonomy/terms.html"}, 18},
+               {"Term", LayoutDescriptor{Kind: "term", Section: "tags"}, "", ampType,
+                       []string{"term/term.amp.html", "term/tags.amp.html", "term/taxonomy.amp.html", "term/list.amp.html", "term/term.html", "term/tags.html", "term/taxonomy.html", "term/list.html", "taxonomy/term.amp.html", "taxonomy/tags.amp.html", "taxonomy/taxonomy.amp.html", "taxonomy/list.amp.html", "taxonomy/term.html", "taxonomy/tags.html", "taxonomy/taxonomy.html", "taxonomy/list.html", "tags/term.amp.html", "tags/tags.amp.html", "tags/taxonomy.amp.html", "tags/list.amp.html", "tags/term.html", "tags/tags.html", "tags/taxonomy.html", "tags/list.html", "_default/term.amp.html", "_default/tags.amp.html", "_default/taxonomy.amp.html", "_default/list.amp.html", "_default/term.html", "_default/tags.html", "_default/taxonomy.html", "_default/list.html"}, 32},
+               {"Taxonomy", LayoutDescriptor{Kind: "taxonomy", Section: "categories"}, "", ampType,
+                       []string{"categories/categories.terms.amp.html", "categories/terms.amp.html", "categories/taxonomy.amp.html", "categories/list.amp.html", "categories/categories.terms.html", "categories/terms.html", "categories/taxonomy.html", "categories/list.html", "taxonomy/categories.terms.amp.html", "taxonomy/terms.amp.html", "taxonomy/taxonomy.amp.html", "taxonomy/list.amp.html", "taxonomy/categories.terms.html", "taxonomy/terms.html", "taxonomy/taxonomy.html", "taxonomy/list.html", "_default/categories.terms.amp.html", "_default/terms.amp.html", "_default/taxonomy.amp.html", "_default/list.amp.html", "_default/categories.terms.html", "_default/terms.html", "_default/taxonomy.html", "_default/list.html"}, 24},
                {"Page", LayoutDescriptor{Kind: "page"}, "", ampType,
                        []string{"_default/single.amp.html", "_default/single.html"}, 2},
                {"Page, baseof", LayoutDescriptor{Kind: "page", Baseof: true}, "", ampType,
@@ -111,10 +111,10 @@ func TestLayout(t *testing.T) {
                        []string{"index-baseof.rss.xml", "home-baseof.rss.xml", "list-baseof.rss.xml", "baseof.rss.xml"}, 16},
                {"RSS Section", LayoutDescriptor{Kind: "section", Section: "sect1"}, "", RSSFormat,
                        []string{"sect1/sect1.rss.xml", "sect1/section.rss.xml", "sect1/rss.xml", "sect1/list.rss.xml", "sect1/sect1.xml", "sect1/section.xml"}, 22},
+               {"RSS Term", LayoutDescriptor{Kind: "term", Section: "tag"}, "", RSSFormat,
+                       []string{"term/term.rss.xml", "term/tag.rss.xml", "term/taxonomy.rss.xml", "term/rss.xml", "term/list.rss.xml", "term/term.xml", "term/tag.xml", "term/taxonomy.xml", "term/list.xml"}, 37},
                {"RSS Taxonomy", LayoutDescriptor{Kind: "taxonomy", Section: "tag"}, "", RSSFormat,
-                       []string{"taxonomy/tag.rss.xml", "taxonomy/taxonomy.rss.xml", "taxonomy/rss.xml", "taxonomy/list.rss.xml", "taxonomy/tag.xml", "taxonomy/taxonomy.xml"}, 22},
-               {"RSS Taxonomy term", LayoutDescriptor{Kind: "taxonomyTerm", Section: "tag"}, "", RSSFormat,
-                       []string{"taxonomy/tag.terms.rss.xml", "taxonomy/terms.rss.xml", "taxonomy/rss.xml", "taxonomy/list.rss.xml", "taxonomy/tag.terms.xml"}, 22},
+                       []string{"tag/tag.terms.rss.xml", "tag/terms.rss.xml", "tag/taxonomy.rss.xml", "tag/rss.xml", "tag/list.rss.xml", "tag/tag.terms.xml", "tag/terms.xml", "tag/taxonomy.xml", "tag/list.xml", "taxonomy/tag.terms.rss.xml", "taxonomy/terms.rss.xml", "taxonomy/taxonomy.rss.xml", "taxonomy/rss.xml", "taxonomy/list.rss.xml", "taxonomy/tag.terms.xml", "taxonomy/terms.xml", "taxonomy/taxonomy.xml", "taxonomy/list.xml", "_default/tag.terms.rss.xml", "_default/terms.rss.xml", "_default/taxonomy.rss.xml", "_default/rss.xml", "_default/list.rss.xml", "_default/tag.terms.xml", "_default/terms.xml", "_default/taxonomy.xml", "_default/list.xml", "_internal/_default/rss.xml"}, 28},
                {"Home plain text", LayoutDescriptor{Kind: "home"}, "", JSONFormat,
                        []string{"index.json.json", "home.json.json"}, 12},
                {"Page plain text", LayoutDescriptor{Kind: "page"}, "", JSONFormat,
@@ -157,7 +157,7 @@ func TestLayout(t *testing.T) {
 
 func BenchmarkLayout(b *testing.B) {
        c := qt.New(b)
-       descriptor := LayoutDescriptor{Kind: "taxonomyTerm", Section: "categories"}
+       descriptor := LayoutDescriptor{Kind: "taxonomy", Section: "categories"}
        l := NewLayoutHandler()
 
        for i := 0; i < b.N; i++ {
index 934427b0ed099c0b9096d88c3c19b8f3b1eefc5e..de417178f045c51b82fc006cbb351faa7e20bd9c 100644 (file)
@@ -151,7 +151,7 @@ type PageMetaProvider interface {
        // Configured keywords.
        Keywords() []string
 
-       // The Page Kind. One of page, home, section, taxonomy, taxonomyTerm.
+       // The Page Kind. One of page, home, section, taxonomy, term.
        Kind() string
 
        // The configured layout to use to render this page. Typically set in front matter.
index 1f59ec8699a42c701c634e4fa54de7a19984001a..719375f669b091dc6d6d4bdabcaa9ca87d8955a3 100644 (file)
@@ -20,18 +20,25 @@ const (
 
        // The rest are node types; home page, sections etc.
 
-       KindHome         = "home"
-       KindSection      = "section"
-       KindTaxonomy     = "taxonomy"
-       KindTaxonomyTerm = "taxonomyTerm"
+       KindHome    = "home"
+       KindSection = "section"
+
+       // Note tha before Hugo 0.73 these were confusingly named
+       // taxonomy (now: term)
+       // taxonomyTerm (now: taxonomy)
+       KindTaxonomy = "taxonomy"
+       KindTerm     = "term"
 )
 
 var kindMap = map[string]string{
-       strings.ToLower(KindPage):         KindPage,
-       strings.ToLower(KindHome):         KindHome,
-       strings.ToLower(KindSection):      KindSection,
-       strings.ToLower(KindTaxonomy):     KindTaxonomy,
-       strings.ToLower(KindTaxonomyTerm): KindTaxonomyTerm,
+       strings.ToLower(KindPage):     KindPage,
+       strings.ToLower(KindHome):     KindHome,
+       strings.ToLower(KindSection):  KindSection,
+       strings.ToLower(KindTaxonomy): KindTaxonomy,
+       strings.ToLower(KindTerm):     KindTerm,
+
+       // Legacy, pre v0.53.0.
+       "taxonomyterm": KindTaxonomy,
 }
 
 // GetKind gets the page kind given a string, empty if not found.
index 7fba7e1d2af9e006d46e1a809038fb0c603f34cd..8ad3493ee836a7efdbdbe8149758393d91f46447 100644 (file)
@@ -27,9 +27,9 @@ func TestKind(t *testing.T) {
        c.Assert(KindHome, qt.Equals, "home")
        c.Assert(KindSection, qt.Equals, "section")
        c.Assert(KindTaxonomy, qt.Equals, "taxonomy")
-       c.Assert(KindTaxonomyTerm, qt.Equals, "taxonomyTerm")
+       c.Assert(KindTerm, qt.Equals, "term")
 
-       c.Assert(GetKind("TAXONOMYTERM"), qt.Equals, KindTaxonomyTerm)
+       c.Assert(GetKind("TAXONOMYTERM"), qt.Equals, KindTaxonomy)
        c.Assert(GetKind("Taxonomy"), qt.Equals, KindTaxonomy)
        c.Assert(GetKind("Page"), qt.Equals, KindPage)
        c.Assert(GetKind("Home"), qt.Equals, KindHome)
index 4aaa41e8acc6bae6a302d68ed912d5bca59286f1..63df48a99f464310139f76b9b646e15dcca144f9 100644 (file)
@@ -58,12 +58,12 @@ func TestPageTargetPath(t *testing.T) {
                                                Sections: []string{"sect1"},
                                                BaseName: "_index",
                                                Type:     output.HTMLFormat}, TargetPaths{TargetFilename: "/sect1/index.html", SubResourceBaseTarget: "/sect1", Link: "/sect1/"}},
-                                       {"HTML taxonomy list", TargetPathDescriptor{
-                                               Kind:     KindTaxonomy,
+                                       {"HTML taxonomy term", TargetPathDescriptor{
+                                               Kind:     KindTerm,
                                                Sections: []string{"tags", "hugo"},
                                                BaseName: "_index",
                                                Type:     output.HTMLFormat}, TargetPaths{TargetFilename: "/tags/hugo/index.html", SubResourceBaseTarget: "/tags/hugo", Link: "/tags/hugo/"}},
-                                       {"HTML taxonomy term", TargetPathDescriptor{
+                                       {"HTML taxonomy", TargetPathDescriptor{
                                                Kind:     KindTaxonomy,
                                                Sections: []string{"tags"},
                                                BaseName: "_index",
@@ -143,8 +143,8 @@ func TestPageTargetPath(t *testing.T) {
                                                        Type:     output.HTMLFormat,
                                                        Addends:  "page/3"}, TargetPaths{TargetFilename: "/page/3/index.html", SubResourceBaseTarget: "/page/3", Link: "/page/3/"}},
                                        {
-                                               "Paginated Taxonomy list", TargetPathDescriptor{
-                                                       Kind:     KindTaxonomy,
+                                               "Paginated Taxonomy terms list", TargetPathDescriptor{
+                                                       Kind:     KindTerm,
                                                        BaseName: "_index",
                                                        Sections: []string{"tags", "hugo"},
                                                        Type:     output.HTMLFormat,