mirror of
https://github.com/gohugoio/hugo.git
synced 2024-07-05 08:42:12 +00:00
tpl: Add replaceRE function
This commit addes a `replaceRE` template function. Regexp patterns are compiled once and cached.
This commit is contained in:
parent
e9008b91fa
commit
b8d3651242
|
@ -451,6 +451,13 @@ Replaces all occurrences of the search string with the replacement string.
|
||||||
e.g. `{{ replace "Batman and Robin" "Robin" "Catwoman" }}` → "Batman and Catwoman"
|
e.g. `{{ replace "Batman and Robin" "Robin" "Catwoman" }}` → "Batman and Catwoman"
|
||||||
|
|
||||||
|
|
||||||
|
### replaceRE
|
||||||
|
Replaces all occurrences of a regular expression with the replacement pattern.
|
||||||
|
|
||||||
|
e.g. `{{ replaceRE "^https?://([^/]+).*" "$1" "http://gohugo.io/docs" }}` → "gohugo.io"
|
||||||
|
e.g. `{{ "http://gohugo.io/docs" | replaceRE "^https?://([^/]+).*" "$1" }}` → "gohugo.io"
|
||||||
|
|
||||||
|
|
||||||
### safeHTML
|
### safeHTML
|
||||||
Declares the provided string as a "safe" HTML document fragment
|
Declares the provided string as a "safe" HTML document fragment
|
||||||
so Go html/template will not filter it. It should not be used
|
so Go html/template will not filter it. It should not be used
|
||||||
|
|
|
@ -29,6 +29,7 @@ import (
|
||||||
"math/rand"
|
"math/rand"
|
||||||
"os"
|
"os"
|
||||||
"reflect"
|
"reflect"
|
||||||
|
"regexp"
|
||||||
"sort"
|
"sort"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
@ -1230,6 +1231,37 @@ func replace(a, b, c interface{}) (string, error) {
|
||||||
return strings.Replace(aStr, bStr, cStr, -1), nil
|
return strings.Replace(aStr, bStr, cStr, -1), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var regexpCache = make(map[string]*regexp.Regexp)
|
||||||
|
|
||||||
|
// replaceRE exposes a regular expression replacement function to the templates.
|
||||||
|
func replaceRE(pattern, repl, src interface{}) (_ string, err error) {
|
||||||
|
patternStr, err := cast.ToStringE(pattern)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
replStr, err := cast.ToStringE(repl)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
srcStr, err := cast.ToStringE(src)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, ok := regexpCache[patternStr]; !ok {
|
||||||
|
re, err2 := regexp.Compile(patternStr)
|
||||||
|
if err2 != nil {
|
||||||
|
return "", err2
|
||||||
|
}
|
||||||
|
|
||||||
|
regexpCache[patternStr] = re
|
||||||
|
}
|
||||||
|
|
||||||
|
return regexpCache[patternStr].ReplaceAllString(srcStr, replStr), err
|
||||||
|
}
|
||||||
|
|
||||||
// dateFormat converts the textual representation of the datetime string into
|
// dateFormat converts the textual representation of the datetime string into
|
||||||
// the other form or returns it of the time.Time value. These are formatted
|
// the other form or returns it of the time.Time value. These are formatted
|
||||||
// with the layout string
|
// with the layout string
|
||||||
|
@ -1717,6 +1749,7 @@ func init() {
|
||||||
"relURL": func(a string) template.HTML { return template.HTML(helpers.RelURL(a)) },
|
"relURL": func(a string) template.HTML { return template.HTML(helpers.RelURL(a)) },
|
||||||
"relref": relRef,
|
"relref": relRef,
|
||||||
"replace": replace,
|
"replace": replace,
|
||||||
|
"replaceRE": replaceRE,
|
||||||
"safeCSS": safeCSS,
|
"safeCSS": safeCSS,
|
||||||
"safeHTML": safeHTML,
|
"safeHTML": safeHTML,
|
||||||
"safeJS": safeJS,
|
"safeJS": safeJS,
|
||||||
|
|
|
@ -1781,6 +1781,27 @@ func TestReplace(t *testing.T) {
|
||||||
assert.NotNil(t, e, "tstNoStringer cannot be converted to string")
|
assert.NotNil(t, e, "tstNoStringer cannot be converted to string")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestReplaceRE(t *testing.T) {
|
||||||
|
for i, val := range []struct {
|
||||||
|
pattern string
|
||||||
|
repl string
|
||||||
|
src string
|
||||||
|
expect string
|
||||||
|
ok bool
|
||||||
|
}{
|
||||||
|
{"^https?://([^/]+).*", "$1", "http://gohugo.io/docs", "gohugo.io", true},
|
||||||
|
{"^https?://([^/]+).*", "$2", "http://gohugo.io/docs", "", true},
|
||||||
|
{"(ab)", "AB", "aabbaab", "aABbaAB", true},
|
||||||
|
{"(ab", "AB", "aabb", "", false}, // invalid re
|
||||||
|
} {
|
||||||
|
v, err := replaceRE(val.pattern, val.repl, val.src)
|
||||||
|
if (err == nil) != val.ok {
|
||||||
|
t.Errorf("[%d] %s", i, err)
|
||||||
|
}
|
||||||
|
assert.Equal(t, val.expect, v)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestTrim(t *testing.T) {
|
func TestTrim(t *testing.T) {
|
||||||
|
|
||||||
for i, this := range []struct {
|
for i, this := range []struct {
|
||||||
|
|
Loading…
Reference in a new issue