shithub: hugo

Download patch

ref: 7b472e46084b603045b87cea870ffc73ac1cf7e7
parent: 96e3fbcf23ceb946504d7e82ea08bf1c30b0fe5f
author: Bjørn Erik Pedersen <[email protected]>
date: Sat Jan 27 05:22:42 EST 2018

resource: Start Resources :counter first time they're used

This is less surprising and more flexible than the original implementation.

Given:

```toml
[[resources]]
  src = "documents/photo_specs.pdf"
  title = "Photo Specifications"
[[resources]]
  src = "**.pdf"
  name = "pdf-file-:counter"
```

Every `pdf` in the bundle will have an unique counter, but the `photo_specs.pdf` is still allowed to have its specific `title`.

If you change the above example to:

```toml
[[resources]]
  src = "documents/*specs.pdf"
  title = "Photo Specifications #:conter"
[[resources]]
  src = "**.pdf"
  name = "pdf-file-:counter"
```

We are talking about two different groups of documents, each with its own counters starting at 1.

Fixes #4335

--- a/resource/resource.go
+++ b/resource/resource.go
@@ -447,6 +447,8 @@
 	return helpers.WriteToDisk(target, f, l.spec.Fs.Destination)
 }
 
+const counterPlaceHolder = ":counter"
+
 // AssignMetadata assigns the given metadata to those resources that supports updates
 // and matching by wildcard given in `src` using `filepath.Match` with lower cased values.
 // This assignment is additive, but the most specific match needs to be first.
@@ -464,6 +466,7 @@
 		var (
 			nameSet, titleSet bool
 			currentCounter    = 0
+			counterFound      bool
 			resourceSrcKey    = strings.ToLower(r.Name())
 		)
 
@@ -487,12 +490,16 @@
 				if !nameSet {
 					name, found := meta["name"]
 					if found {
-						if currentCounter == 0 {
+						name := cast.ToString(name)
+						if !counterFound {
+							counterFound = strings.Contains(name, counterPlaceHolder)
+						}
+						if counterFound && currentCounter == 0 {
 							currentCounter = counters[srcKey] + 1
 							counters[srcKey] = currentCounter
 						}
 
-						ma.setName(replaceResourcePlaceholders(cast.ToString(name), currentCounter))
+						ma.setName(replaceResourcePlaceholders(name, currentCounter))
 						nameSet = true
 					}
 				}
@@ -500,11 +507,15 @@
 				if !titleSet {
 					title, found := meta["title"]
 					if found {
-						if currentCounter == 0 {
+						title := cast.ToString(title)
+						if !counterFound {
+							counterFound = strings.Contains(title, counterPlaceHolder)
+						}
+						if counterFound && currentCounter == 0 {
 							currentCounter = counters[srcKey] + 1
 							counters[srcKey] = currentCounter
 						}
-						ma.setTitle((replaceResourcePlaceholders(cast.ToString(title), currentCounter)))
+						ma.setTitle((replaceResourcePlaceholders(title, currentCounter)))
 						titleSet = true
 					}
 				}
@@ -524,7 +535,7 @@
 }
 
 func replaceResourcePlaceholders(in string, counter int) string {
-	return strings.Replace(in, ":counter", strconv.Itoa(counter), -1)
+	return strings.Replace(in, counterPlaceHolder, strconv.Itoa(counter), -1)
 }
 
 func (l *genericResource) target() string {
--- a/resource/resource_test.go
+++ b/resource/resource_test.go
@@ -312,6 +312,48 @@
 			assert.Equal("Name #2", logo1.Name())
 
 		}},
+		// Start counting first time :counter is used
+		// See https://github.com/gohugoio/hugo/issues/4335
+		{[]map[string]interface{}{
+			map[string]interface{}{
+				"title": "Third Logo",
+				"src":   "logo3.png",
+			},
+			map[string]interface{}{
+				"title": "Other Logo #:counter",
+				"name":  "Name #:counter",
+				"src":   "logo*",
+			},
+		}, func(err error) {
+			assert.NoError(err)
+			assert.Equal("Third Logo", logo3.Title())
+			assert.Equal("Name #3", logo3.Name())
+			assert.Equal("Other Logo #1", logo2.Title())
+			assert.Equal("Name #1", logo2.Name())
+			assert.Equal("Other Logo #2", logo1.Title())
+			assert.Equal("Name #2", logo1.Name())
+
+		}},
+		{[]map[string]interface{}{
+			map[string]interface{}{
+				"name": "third-logo",
+				"src":  "logo3.png",
+			},
+			map[string]interface{}{
+				"title": "Logo #:counter",
+				"name":  "Name #:counter",
+				"src":   "logo*",
+			},
+		}, func(err error) {
+			assert.NoError(err)
+			assert.Equal("Logo #3", logo3.Title())
+			assert.Equal("third-logo", logo3.Name())
+			assert.Equal("Logo #1", logo2.Title())
+			assert.Equal("Name #1", logo2.Name())
+			assert.Equal("Logo #2", logo1.Title())
+			assert.Equal("Name #2", logo1.Name())
+
+		}},
 		{[]map[string]interface{}{
 			map[string]interface{}{
 				"title": "Third Logo #:counter",