From 7b472e46084b603045b87cea870ffc73ac1cf7e7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B8rn=20Erik=20Pedersen?= Date: Sat, 27 Jan 2018 10:22:42 +0100 Subject: 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 --- resource/resource.go | 21 ++++++++++++++++----- resource/resource_test.go | 42 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 58 insertions(+), 5 deletions(-) (limited to 'resource') diff --git a/resource/resource.go b/resource/resource.go index 2e5c8011a..dfda1ae7a 100644 --- a/resource/resource.go +++ b/resource/resource.go @@ -447,6 +447,8 @@ func (l *genericResource) Publish() error { 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 @@ func AssignMetadata(metadata []map[string]interface{}, resources ...Resource) er var ( nameSet, titleSet bool currentCounter = 0 + counterFound bool resourceSrcKey = strings.ToLower(r.Name()) ) @@ -487,12 +490,16 @@ func AssignMetadata(metadata []map[string]interface{}, resources ...Resource) er 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 @@ func AssignMetadata(metadata []map[string]interface{}, resources ...Resource) er 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 AssignMetadata(metadata []map[string]interface{}, resources ...Resource) er } 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 { diff --git a/resource/resource_test.go b/resource/resource_test.go index 54d200c1c..fc6416e6a 100644 --- a/resource/resource_test.go +++ b/resource/resource_test.go @@ -311,6 +311,48 @@ func TestAssignMetadata(t *testing.T) { assert.Equal("Other Logo #2", logo1.Title()) 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{}{ -- cgit v1.2.3