mirror of
https://github.com/gohugoio/hugo.git
synced 2024-11-07 20:30:36 -05: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
3 changed files with 61 additions and 0 deletions
|
@ -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"
|
||||
|
||||
|
||||
### 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
|
||||
Declares the provided string as a "safe" HTML document fragment
|
||||
so Go html/template will not filter it. It should not be used
|
||||
|
|
|
@ -29,6 +29,7 @@ import (
|
|||
"math/rand"
|
||||
"os"
|
||||
"reflect"
|
||||
"regexp"
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
@ -1230,6 +1231,37 @@ func replace(a, b, c interface{}) (string, error) {
|
|||
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
|
||||
// the other form or returns it of the time.Time value. These are formatted
|
||||
// with the layout string
|
||||
|
@ -1717,6 +1749,7 @@ func init() {
|
|||
"relURL": func(a string) template.HTML { return template.HTML(helpers.RelURL(a)) },
|
||||
"relref": relRef,
|
||||
"replace": replace,
|
||||
"replaceRE": replaceRE,
|
||||
"safeCSS": safeCSS,
|
||||
"safeHTML": safeHTML,
|
||||
"safeJS": safeJS,
|
||||
|
|
|
@ -1781,6 +1781,27 @@ func TestReplace(t *testing.T) {
|
|||
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) {
|
||||
|
||||
for i, this := range []struct {
|
||||
|
|
Loading…
Reference in a new issue