diff options
author | Cameron Moore <[email protected]> | 2020-08-27 21:59:20 -0500 |
---|---|---|
committer | Bjørn Erik Pedersen <[email protected]> | 2020-08-28 08:55:58 +0200 |
commit | f9ebaaed1be1e4a26eef2aebd2c7554c979f29fa (patch) | |
tree | e9d4e39da776a1cf1bd2b577893904a113177d05 /tpl | |
parent | d39636a5fc6bb82b3e0bd013858c7d116faa0c6b (diff) | |
download | hugo-f9ebaaed1be1e4a26eef2aebd2c7554c979f29fa.tar.gz hugo-f9ebaaed1be1e4a26eef2aebd2c7554c979f29fa.zip |
tpl: Add limit option to replace template function
Updates #7586
Diffstat (limited to 'tpl')
-rw-r--r-- | tpl/strings/init.go | 11 | ||||
-rw-r--r-- | tpl/strings/strings.go | 54 | ||||
-rw-r--r-- | tpl/strings/strings_test.go | 30 |
3 files changed, 59 insertions, 36 deletions
diff --git a/tpl/strings/init.go b/tpl/strings/init.go index fe0cff83b..09419a51f 100644 --- a/tpl/strings/init.go +++ b/tpl/strings/init.go @@ -63,7 +63,8 @@ func init() { [][2]string{ { `{{ findRE "[G|g]o" "Hugo is a static side generator written in Go." "1" }}`, - `[go]`}, + `[go]`, + }, }, ) @@ -87,7 +88,12 @@ func init() { [][2]string{ { `{{ replace "Batman and Robin" "Robin" "Catwoman" }}`, - `Batman and Catwoman`}, + `Batman and Catwoman`, + }, + { + `{{ replace "aabbaabb" "a" "z" 2 }}`, + `zzbbaabb`, + }, }, ) @@ -192,7 +198,6 @@ func init() { ) return ns - } internal.AddTemplateFuncsNamespace(f) diff --git a/tpl/strings/strings.go b/tpl/strings/strings.go index d78234e41..c87b532d3 100644 --- a/tpl/strings/strings.go +++ b/tpl/strings/strings.go @@ -19,14 +19,12 @@ import ( "fmt" "html/template" "strings" - - _strings "strings" "unicode/utf8" - _errors "github.com/pkg/errors" - "github.com/gohugoio/hugo/deps" "github.com/gohugoio/hugo/helpers" + + _errors "github.com/pkg/errors" "github.com/spf13/cast" ) @@ -79,7 +77,7 @@ func (ns *Namespace) CountWords(s interface{}) (int, error) { } counter := 0 - for _, word := range _strings.Fields(helpers.StripHTML(ss)) { + for _, word := range strings.Fields(helpers.StripHTML(ss)) { runeCount := utf8.RuneCountInString(word) if len(word) == runeCount { counter++ @@ -112,14 +110,13 @@ func (ns *Namespace) Chomp(s interface{}) (interface{}, error) { return "", err } - res := _strings.TrimRight(ss, "\r\n") + res := strings.TrimRight(ss, "\r\n") switch s.(type) { case template.HTML: return template.HTML(res), nil default: return res, nil } - } // Contains reports whether substr is in s. @@ -134,7 +131,7 @@ func (ns *Namespace) Contains(s, substr interface{}) (bool, error) { return false, err } - return _strings.Contains(ss, su), nil + return strings.Contains(ss, su), nil } // ContainsAny reports whether any Unicode code points in chars are within s. @@ -149,7 +146,7 @@ func (ns *Namespace) ContainsAny(s, chars interface{}) (bool, error) { return false, err } - return _strings.ContainsAny(ss, sc), nil + return strings.ContainsAny(ss, sc), nil } // HasPrefix tests whether the input s begins with prefix. @@ -164,7 +161,7 @@ func (ns *Namespace) HasPrefix(s, prefix interface{}) (bool, error) { return false, err } - return _strings.HasPrefix(ss, sx), nil + return strings.HasPrefix(ss, sx), nil } // HasSuffix tests whether the input s begins with suffix. @@ -179,12 +176,13 @@ func (ns *Namespace) HasSuffix(s, suffix interface{}) (bool, error) { return false, err } - return _strings.HasSuffix(ss, sx), nil + return strings.HasSuffix(ss, sx), nil } // Replace returns a copy of the string s with all occurrences of old replaced -// with new. -func (ns *Namespace) Replace(s, old, new interface{}) (string, error) { +// with new. The number of replacements can be limited with an optional fourth +// parameter. +func (ns *Namespace) Replace(s, old, new interface{}, limit ...interface{}) (string, error) { ss, err := cast.ToStringE(s) if err != nil { return "", err @@ -200,7 +198,16 @@ func (ns *Namespace) Replace(s, old, new interface{}) (string, error) { return "", err } - return _strings.Replace(ss, so, sn, -1), nil + if len(limit) == 0 { + return strings.ReplaceAll(ss, so, sn), nil + } + + lim, err := cast.ToIntE(limit[0]) + if err != nil { + return "", err + } + + return strings.Replace(ss, so, sn, lim), nil } // SliceString slices a string by specifying a half-open range with @@ -247,7 +254,6 @@ func (ns *Namespace) SliceString(a interface{}, startEnd ...interface{}) (string } else { return string(asRunes[:]), nil } - } // Split slices an input string into all substrings separated by delimiter. @@ -257,7 +263,7 @@ func (ns *Namespace) Split(a interface{}, delimiter string) ([]string, error) { return []string{}, err } - return _strings.Split(aStr, delimiter), nil + return strings.Split(aStr, delimiter), nil } // Substr extracts parts of a string, beginning at the character at the specified @@ -362,7 +368,7 @@ func (ns *Namespace) ToLower(s interface{}) (string, error) { return "", err } - return _strings.ToLower(ss), nil + return strings.ToLower(ss), nil } // ToUpper returns a copy of the input s with all Unicode letters mapped to their @@ -373,7 +379,7 @@ func (ns *Namespace) ToUpper(s interface{}) (string, error) { return "", err } - return _strings.ToUpper(ss), nil + return strings.ToUpper(ss), nil } // Trim returns a string with all leading and trailing characters defined @@ -389,7 +395,7 @@ func (ns *Namespace) Trim(s, cutset interface{}) (string, error) { return "", err } - return _strings.Trim(ss, sc), nil + return strings.Trim(ss, sc), nil } // TrimLeft returns a slice of the string s with all leading characters @@ -405,7 +411,7 @@ func (ns *Namespace) TrimLeft(cutset, s interface{}) (string, error) { return "", err } - return _strings.TrimLeft(ss, sc), nil + return strings.TrimLeft(ss, sc), nil } // TrimPrefix returns s without the provided leading prefix string. If s doesn't @@ -421,7 +427,7 @@ func (ns *Namespace) TrimPrefix(prefix, s interface{}) (string, error) { return "", err } - return _strings.TrimPrefix(ss, sx), nil + return strings.TrimPrefix(ss, sx), nil } // TrimRight returns a slice of the string s with all trailing characters @@ -437,7 +443,7 @@ func (ns *Namespace) TrimRight(cutset, s interface{}) (string, error) { return "", err } - return _strings.TrimRight(ss, sc), nil + return strings.TrimRight(ss, sc), nil } // TrimSuffix returns s without the provided trailing suffix string. If s @@ -453,7 +459,7 @@ func (ns *Namespace) TrimSuffix(suffix, s interface{}) (string, error) { return "", err } - return _strings.TrimSuffix(ss, sx), nil + return strings.TrimSuffix(ss, sx), nil } // Repeat returns a new string consisting of count copies of the string s. @@ -472,5 +478,5 @@ func (ns *Namespace) Repeat(n, s interface{}) (string, error) { return "", errors.New("strings: negative Repeat count") } - return _strings.Repeat(ss, sn), nil + return strings.Repeat(ss, sn), nil } diff --git a/tpl/strings/strings_test.go b/tpl/strings/strings_test.go index 2fc3dc028..6a14acd78 100644 --- a/tpl/strings/strings_test.go +++ b/tpl/strings/strings_test.go @@ -15,11 +15,11 @@ package strings import ( "html/template" - "testing" - qt "github.com/frankban/quicktest" "github.com/gohugoio/hugo/deps" + + qt "github.com/frankban/quicktest" "github.com/spf13/cast" "github.com/spf13/viper" ) @@ -302,18 +302,30 @@ func TestReplace(t *testing.T) { s interface{} old interface{} new interface{} + limit interface{} expect interface{} }{ - {"aab", "a", "b", "bbb"}, - {"11a11", 1, 2, "22a22"}, - {12345, 1, 2, "22345"}, + {"aab", "a", "b", nil, "bbb"}, + {"11a11", 1, 2, nil, "22a22"}, + {12345, 1, 2, nil, "22345"}, + {"aab", "a", "b", 1, "bab"}, + {"11a11", 1, 2, 2, "22a11"}, // errors - {tstNoStringer{}, "a", "b", false}, - {"a", tstNoStringer{}, "b", false}, - {"a", "b", tstNoStringer{}, false}, + {tstNoStringer{}, "a", "b", nil, false}, + {"a", tstNoStringer{}, "b", nil, false}, + {"a", "b", tstNoStringer{}, nil, false}, } { - result, err := ns.Replace(test.s, test.old, test.new) + var ( + result string + err error + ) + + if test.limit != nil { + result, err = ns.Replace(test.s, test.old, test.new, test.limit) + } else { + result, err = ns.Replace(test.s, test.old, test.new) + } if b, ok := test.expect.(bool); ok && !b { c.Assert(err, qt.Not(qt.IsNil)) |