mirror of
https://github.com/gohugoio/hugo.git
synced 2024-11-21 20:46:30 -05:00
tpl: Allow 'Querify' to take lone slice/interface argument
Querify can now take a lone string/interface slice (with string keys) as a parameter, or multiple string parameters, to build URL queries. Querify earlier used 'Dictionary' to add key/value pairs to a map to build URL queries. Changed to dynamically generate ordered key/value pairs. Cannot take string slice as key (earlier possible due to Dictionary). Added tests and benchmarks for querify. Closes #6735
This commit is contained in:
parent
504c78da4b
commit
c46fc838a9
3 changed files with 68 additions and 5 deletions
|
@ -424,13 +424,39 @@ func (ns *Namespace) Last(limit interface{}, seq interface{}) (interface{}, erro
|
||||||
// Querify encodes the given parameters in URL-encoded form ("bar=baz&foo=quux") sorted by key.
|
// Querify encodes the given parameters in URL-encoded form ("bar=baz&foo=quux") sorted by key.
|
||||||
func (ns *Namespace) Querify(params ...interface{}) (string, error) {
|
func (ns *Namespace) Querify(params ...interface{}) (string, error) {
|
||||||
qs := url.Values{}
|
qs := url.Values{}
|
||||||
vals, err := ns.Dictionary(params...)
|
|
||||||
if err != nil {
|
if len(params) == 1 {
|
||||||
return "", errors.New("querify keys must be strings")
|
switch v := params[0].(type) {
|
||||||
|
case []string:
|
||||||
|
if len(v)%2 != 0 {
|
||||||
|
return "", errors.New("invalid query")
|
||||||
}
|
}
|
||||||
|
|
||||||
for name, value := range vals {
|
for i := 0; i < len(v); i += 2 {
|
||||||
qs.Add(name, fmt.Sprintf("%v", value))
|
qs.Add(v[i], v[i+1])
|
||||||
|
}
|
||||||
|
|
||||||
|
return qs.Encode(), nil
|
||||||
|
|
||||||
|
case []interface{}:
|
||||||
|
params = v
|
||||||
|
|
||||||
|
default:
|
||||||
|
return "", errors.New("query keys must be strings")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(params)%2 != 0 {
|
||||||
|
return "", errors.New("invalid query")
|
||||||
|
}
|
||||||
|
|
||||||
|
for i := 0; i < len(params); i += 2 {
|
||||||
|
switch v := params[i].(type) {
|
||||||
|
case string:
|
||||||
|
qs.Add(v, fmt.Sprintf("%v", params[i+1]))
|
||||||
|
default:
|
||||||
|
return "", errors.New("query keys must be strings")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return qs.Encode(), nil
|
return qs.Encode(), nil
|
||||||
|
|
|
@ -564,9 +564,16 @@ func TestQuerify(t *testing.T) {
|
||||||
}{
|
}{
|
||||||
{[]interface{}{"a", "b"}, "a=b"},
|
{[]interface{}{"a", "b"}, "a=b"},
|
||||||
{[]interface{}{"a", "b", "c", "d", "f", " &"}, `a=b&c=d&f=+%26`},
|
{[]interface{}{"a", "b", "c", "d", "f", " &"}, `a=b&c=d&f=+%26`},
|
||||||
|
{[]interface{}{[]string{"a", "b"}}, "a=b"},
|
||||||
|
{[]interface{}{[]string{"a", "b", "c", "d", "f", " &"}}, `a=b&c=d&f=+%26`},
|
||||||
|
{[]interface{}{[]interface{}{"x", "y"}}, `x=y`},
|
||||||
|
{[]interface{}{[]interface{}{"x", 5}}, `x=5`},
|
||||||
// errors
|
// errors
|
||||||
{[]interface{}{5, "b"}, false},
|
{[]interface{}{5, "b"}, false},
|
||||||
{[]interface{}{"a", "b", "c"}, false},
|
{[]interface{}{"a", "b", "c"}, false},
|
||||||
|
{[]interface{}{[]string{"a", "b", "c"}}, false},
|
||||||
|
{[]interface{}{[]string{"a", "b"}, "c"}, false},
|
||||||
|
{[]interface{}{[]interface{}{"c", "d", "e"}}, false},
|
||||||
} {
|
} {
|
||||||
errMsg := qt.Commentf("[%d] %v", i, test.params)
|
errMsg := qt.Commentf("[%d] %v", i, test.params)
|
||||||
|
|
||||||
|
@ -582,6 +589,32 @@ func TestQuerify(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func BenchmarkQuerify(b *testing.B) {
|
||||||
|
ns := New(&deps.Deps{})
|
||||||
|
params := []interface{}{"a", "b", "c", "d", "f", " &"}
|
||||||
|
|
||||||
|
b.ResetTimer()
|
||||||
|
for i := 0; i < b.N; i++ {
|
||||||
|
_, err := ns.Querify(params...)
|
||||||
|
if err != nil {
|
||||||
|
b.Fatal(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func BenchmarkQuerifySlice(b *testing.B) {
|
||||||
|
ns := New(&deps.Deps{})
|
||||||
|
params := []string{"a", "b", "c", "d", "f", " &"}
|
||||||
|
|
||||||
|
b.ResetTimer()
|
||||||
|
for i := 0; i < b.N; i++ {
|
||||||
|
_, err := ns.Querify(params)
|
||||||
|
if err != nil {
|
||||||
|
b.Fatal(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestSeq(t *testing.T) {
|
func TestSeq(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
c := qt.New(t)
|
c := qt.New(t)
|
||||||
|
|
|
@ -122,6 +122,10 @@ func init() {
|
||||||
`<a href="https://www.google.com?{{ (querify "q" "test" "page" 3) | safeURL }}">Search</a>`,
|
`<a href="https://www.google.com?{{ (querify "q" "test" "page" 3) | safeURL }}">Search</a>`,
|
||||||
`<a href="https://www.google.com?page=3&q=test">Search</a>`,
|
`<a href="https://www.google.com?page=3&q=test">Search</a>`,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
`{{ slice "foo" 1 "bar" 2 | querify | safeHTML }}`,
|
||||||
|
`bar=2&foo=1`,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue