Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/gohugoio/hugo.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/tpl
diff options
context:
space:
mode:
authorBjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com>2017-05-01 19:40:34 +0300
committerBjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com>2017-05-01 22:44:15 +0300
commit690b0f8ff5795318dfa3834a5a75d6623e7d934a (patch)
tree1112306f4c6fecc0966d880dec702c3804633deb /tpl
parente2b067f0504ba41ef45786e2f83d7002bd13a7eb (diff)
tpl: Add docshelper for template funcs
And fix some other minor related issues. Updates #3418
Diffstat (limited to 'tpl')
-rw-r--r--tpl/cast/docshelper.go41
-rw-r--r--tpl/cast/init.go28
-rw-r--r--tpl/collections/init.go150
-rw-r--r--tpl/compare/init.go60
-rw-r--r--tpl/crypto/init.go39
-rw-r--r--tpl/data/init.go22
-rw-r--r--tpl/encoding/init.go39
-rw-r--r--tpl/fmt/fmt.go13
-rw-r--r--tpl/fmt/init.go35
-rw-r--r--tpl/images/init.go17
-rw-r--r--tpl/inflect/init.go43
-rw-r--r--tpl/internal/templatefuncRegistry_test.go33
-rw-r--r--tpl/internal/templatefuncsRegistry.go83
-rw-r--r--tpl/lang/init.go18
-rw-r--r--tpl/math/init.go64
-rw-r--r--tpl/os/init.go34
-rw-r--r--tpl/partials/init.go25
-rw-r--r--tpl/safe/init.go67
-rw-r--r--tpl/strings/init.go152
-rw-r--r--tpl/time/init.go34
-rw-r--r--tpl/tplimpl/template_funcs.go10
-rw-r--r--tpl/tplimpl/template_funcs_test.go28
-rw-r--r--tpl/transform/init.go99
-rw-r--r--tpl/urls/init.go56
24 files changed, 842 insertions, 348 deletions
diff --git a/tpl/cast/docshelper.go b/tpl/cast/docshelper.go
new file mode 100644
index 000000000..5220ca570
--- /dev/null
+++ b/tpl/cast/docshelper.go
@@ -0,0 +1,41 @@
+// Copyright 2017 The Hugo Authors. All rights reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package cast
+
+import (
+ "github.com/spf13/hugo/deps"
+ "github.com/spf13/hugo/docshelper"
+ "github.com/spf13/hugo/tpl/internal"
+)
+
+// This file provides documentation support and is randomly put into this package.
+func init() {
+ docsProvider := func() map[string]interface{} {
+ docs := make(map[string]interface{})
+ d := &deps.Deps{}
+
+ var namespaces []*internal.TemplateFuncsNamespace
+
+ for _, nsf := range internal.TemplateFuncsNamespaceRegistry {
+ nf := nsf(d)
+ namespaces = append(namespaces, nf)
+
+ }
+
+ docs["funcs"] = namespaces
+ return docs
+ }
+
+ docshelper.AddDocProvider("tpl", docsProvider)
+}
diff --git a/tpl/cast/init.go b/tpl/cast/init.go
index acddaa91a..1c737ee58 100644
--- a/tpl/cast/init.go
+++ b/tpl/cast/init.go
@@ -24,21 +24,27 @@ func init() {
f := func(d *deps.Deps) *internal.TemplateFuncsNamespace {
ctx := New()
- examples := [][2]string{
- {`{{ "1234" | int | printf "%T" }}`, `int`},
- {`{{ 1234 | string | printf "%T" }}`, `string`},
- }
-
- return &internal.TemplateFuncsNamespace{
+ ns := &internal.TemplateFuncsNamespace{
Name: name,
Context: func() interface{} { return ctx },
- Aliases: map[string]interface{}{
- "int": ctx.ToInt,
- "string": ctx.ToString,
- },
- Examples: examples,
}
+ ns.AddMethodMapping(ctx.ToInt,
+ []string{"int"},
+ [][2]string{
+ {`{{ "1234" | int | printf "%T" }}`, `int`},
+ },
+ )
+
+ ns.AddMethodMapping(ctx.ToString,
+ []string{"string"},
+ [][2]string{
+ {`{{ 1234 | string | printf "%T" }}`, `string`},
+ },
+ )
+
+ return ns
+
}
internal.AddTemplateFuncsNamespace(f)
diff --git a/tpl/collections/init.go b/tpl/collections/init.go
index 29f6809c3..289228901 100644
--- a/tpl/collections/init.go
+++ b/tpl/collections/init.go
@@ -24,48 +24,122 @@ func init() {
f := func(d *deps.Deps) *internal.TemplateFuncsNamespace {
ctx := New(d)
- examples := [][2]string{
- {`{{ delimit (slice "A" "B" "C") ", " " and " }}`, `A, B and C`},
- {`{{ echoParam .Params "langCode" }}`, `en`},
- {`{{ if in "this string contains a substring" "substring" }}Substring found!{{ end }}`, `Substring found!`},
- {
- `{{ (querify "foo" 1 "bar" 2 "baz" "with spaces" "qux" "this&that=those") | safeHTML }}`,
- `bar=2&baz=with+spaces&foo=1&qux=this%26that%3Dthose`},
- {
- `<a href="https://www.google.com?{{ (querify "q" "test" "page" 3) | safeURL }}">Search</a>`,
- `<a href="https://www.google.com?page=3&amp;q=test">Search</a>`},
- {`{{ slice "B" "C" "A" | sort }}`, `[A B C]`},
- {`{{ seq 3 }}`, `[1 2 3]`},
- {`{{ union (slice 1 2 3) (slice 3 4 5) }}`, `[1 2 3 4 5]`},
- }
-
- return &internal.TemplateFuncsNamespace{
+ ns := &internal.TemplateFuncsNamespace{
Name: name,
Context: func() interface{} { return ctx },
- Aliases: map[string]interface{}{
- "after": ctx.After,
- "apply": ctx.Apply,
- "delimit": ctx.Delimit,
- "dict": ctx.Dictionary,
- "echoParam": ctx.EchoParam,
- "first": ctx.First,
- "in": ctx.In,
- "index": ctx.Index,
- "intersect": ctx.Intersect,
- "isSet": ctx.IsSet,
- "isset": ctx.IsSet,
- "last": ctx.Last,
- "querify": ctx.Querify,
- "shuffle": ctx.Shuffle,
- "slice": ctx.Slice,
- "sort": ctx.Sort,
- "union": ctx.Union,
- "where": ctx.Where,
- "seq": ctx.Seq,
- },
- Examples: examples,
}
+ ns.AddMethodMapping(ctx.After,
+ []string{"after"},
+ [][2]string{},
+ )
+
+ ns.AddMethodMapping(ctx.Apply,
+ []string{"apply"},
+ [][2]string{},
+ )
+
+ ns.AddMethodMapping(ctx.Delimit,
+ []string{"delimit"},
+ [][2]string{
+ {`{{ delimit (slice "A" "B" "C") ", " " and " }}`, `A, B and C`},
+ },
+ )
+
+ ns.AddMethodMapping(ctx.Dictionary,
+ []string{"dict"},
+ [][2]string{},
+ )
+
+ ns.AddMethodMapping(ctx.EchoParam,
+ []string{"echoParam"},
+ [][2]string{
+ {`{{ echoParam .Params "langCode" }}`, `en`},
+ },
+ )
+
+ ns.AddMethodMapping(ctx.First,
+ []string{"first"},
+ [][2]string{},
+ )
+
+ ns.AddMethodMapping(ctx.In,
+ []string{"in"},
+ [][2]string{
+ {`{{ if in "this string contains a substring" "substring" }}Substring found!{{ end }}`, `Substring found!`},
+ },
+ )
+
+ ns.AddMethodMapping(ctx.Index,
+ []string{"index"},
+ [][2]string{},
+ )
+
+ ns.AddMethodMapping(ctx.Intersect,
+ []string{"intersect"},
+ [][2]string{},
+ )
+
+ ns.AddMethodMapping(ctx.IsSet,
+ []string{"isSet", "isset"},
+ [][2]string{},
+ )
+
+ ns.AddMethodMapping(ctx.Last,
+ []string{"last"},
+ [][2]string{},
+ )
+
+ ns.AddMethodMapping(ctx.Querify,
+ []string{"querify"},
+ [][2]string{
+ {
+ `{{ (querify "foo" 1 "bar" 2 "baz" "with spaces" "qux" "this&that=those") | safeHTML }}`,
+ `bar=2&baz=with+spaces&foo=1&qux=this%26that%3Dthose`},
+ {
+ `<a href="https://www.google.com?{{ (querify "q" "test" "page" 3) | safeURL }}">Search</a>`,
+ `<a href="https://www.google.com?page=3&amp;q=test">Search</a>`},
+ },
+ )
+
+ ns.AddMethodMapping(ctx.Shuffle,
+ []string{"shuffle"},
+ [][2]string{},
+ )
+
+ ns.AddMethodMapping(ctx.Slice,
+ []string{"slice"},
+ [][2]string{
+ {`{{ slice "B" "C" "A" | sort }}`, `[A B C]`},
+ },
+ )
+
+ ns.AddMethodMapping(ctx.Sort,
+ []string{"sort"},
+ [][2]string{},
+ )
+
+ ns.AddMethodMapping(ctx.Union,
+ []string{"union"},
+ [][2]string{
+ {`{{ union (slice 1 2 3) (slice 3 4 5) }}`, `[1 2 3 4 5]`},
+ },
+ )
+
+ ns.AddMethodMapping(ctx.Where,
+ []string{"where"},
+ [][2]string{},
+ )
+
+ ns.AddMethodMapping(ctx.Seq,
+ []string{"seq"},
+ [][2]string{
+ {`{{ seq 3 }}`, `[1 2 3]`},
+ },
+ )
+
+ return ns
+
}
internal.AddTemplateFuncsNamespace(f)
diff --git a/tpl/compare/init.go b/tpl/compare/init.go
index bf8227353..0285abff5 100644
--- a/tpl/compare/init.go
+++ b/tpl/compare/init.go
@@ -24,27 +24,53 @@ func init() {
f := func(d *deps.Deps) *internal.TemplateFuncsNamespace {
ctx := New()
- examples := [][2]string{
- {`{{ if eq .Section "blog" }}current{{ end }}`, `current`},
- {`{{ "Hugo Rocks!" | default "Hugo Rules!" }}`, `Hugo Rocks!`},
- {`{{ "" | default "Hugo Rules!" }}`, `Hugo Rules!`},
- }
-
- return &internal.TemplateFuncsNamespace{
+ ns := &internal.TemplateFuncsNamespace{
Name: name,
Context: func() interface{} { return ctx },
- Aliases: map[string]interface{}{
- "default": ctx.Default,
- "eq": ctx.Eq,
- "ge": ctx.Ge,
- "gt": ctx.Gt,
- "le": ctx.Le,
- "lt": ctx.Lt,
- "ne": ctx.Ne,
- },
- Examples: examples,
}
+ ns.AddMethodMapping(ctx.Default,
+ []string{"default"},
+ [][2]string{
+ {`{{ "Hugo Rocks!" | default "Hugo Rules!" }}`, `Hugo Rocks!`},
+ {`{{ "" | default "Hugo Rules!" }}`, `Hugo Rules!`},
+ },
+ )
+
+ ns.AddMethodMapping(ctx.Eq,
+ []string{"eq"},
+ [][2]string{
+ {`{{ if eq .Section "blog" }}current{{ end }}`, `current`},
+ },
+ )
+
+ ns.AddMethodMapping(ctx.Ge,
+ []string{"ge"},
+ [][2]string{},
+ )
+
+ ns.AddMethodMapping(ctx.Gt,
+ []string{"gt"},
+ [][2]string{},
+ )
+
+ ns.AddMethodMapping(ctx.Le,
+ []string{"le"},
+ [][2]string{},
+ )
+
+ ns.AddMethodMapping(ctx.Lt,
+ []string{"lt"},
+ [][2]string{},
+ )
+
+ ns.AddMethodMapping(ctx.Ne,
+ []string{"ne"},
+ [][2]string{},
+ )
+
+ return ns
+
}
internal.AddTemplateFuncsNamespace(f)
diff --git a/tpl/crypto/init.go b/tpl/crypto/init.go
index 7c1899f88..a47c3369f 100644
--- a/tpl/crypto/init.go
+++ b/tpl/crypto/init.go
@@ -24,24 +24,35 @@ func init() {
f := func(d *deps.Deps) *internal.TemplateFuncsNamespace {
ctx := New()
- examples := [][2]string{
- {`{{ md5 "Hello world, gophers!" }}`, `b3029f756f98f79e7f1b7f1d1f0dd53b`},
- {`{{ crypto.MD5 "Hello world, gophers!" }}`, `b3029f756f98f79e7f1b7f1d1f0dd53b`},
- {`{{ sha1 "Hello world, gophers!" }}`, `c8b5b0e33d408246e30f53e32b8f7627a7a649d4`},
- {`{{ sha256 "Hello world, gophers!" }}`, `6ec43b78da9669f50e4e422575c54bf87536954ccd58280219c393f2ce352b46`},
- }
-
- return &internal.TemplateFuncsNamespace{
+ ns := &internal.TemplateFuncsNamespace{
Name: name,
Context: func() interface{} { return ctx },
- Aliases: map[string]interface{}{
- "md5": ctx.MD5,
- "sha1": ctx.SHA1,
- "sha256": ctx.SHA256,
- },
- Examples: examples,
}
+ ns.AddMethodMapping(ctx.MD5,
+ []string{"md5"},
+ [][2]string{
+ {`{{ md5 "Hello world, gophers!" }}`, `b3029f756f98f79e7f1b7f1d1f0dd53b`},
+ {`{{ crypto.MD5 "Hello world, gophers!" }}`, `b3029f756f98f79e7f1b7f1d1f0dd53b`},
+ },
+ )
+
+ ns.AddMethodMapping(ctx.SHA1,
+ []string{"sha1"},
+ [][2]string{
+ {`{{ sha1 "Hello world, gophers!" }}`, `c8b5b0e33d408246e30f53e32b8f7627a7a649d4`},
+ },
+ )
+
+ ns.AddMethodMapping(ctx.SHA256,
+ []string{"sha256"},
+ [][2]string{
+ {`{{ sha256 "Hello world, gophers!" }}`, `6ec43b78da9669f50e4e422575c54bf87536954ccd58280219c393f2ce352b46`},
+ },
+ )
+
+ return ns
+
}
internal.AddTemplateFuncsNamespace(f)
diff --git a/tpl/data/init.go b/tpl/data/init.go
index 476e9ab75..e9e4ca2f9 100644
--- a/tpl/data/init.go
+++ b/tpl/data/init.go
@@ -24,19 +24,21 @@ func init() {
f := func(d *deps.Deps) *internal.TemplateFuncsNamespace {
ctx := New(d)
- examples := [][2]string{
- {},
- }
-
- return &internal.TemplateFuncsNamespace{
+ ns := &internal.TemplateFuncsNamespace{
Name: name,
Context: func() interface{} { return ctx },
- Aliases: map[string]interface{}{
- "getCSV": ctx.GetCSV,
- "getJSON": ctx.GetJSON,
- },
- Examples: examples,
}
+
+ ns.AddMethodMapping(ctx.GetCSV,
+ []string{"getCSV"},
+ [][2]string{},
+ )
+
+ ns.AddMethodMapping(ctx.GetJSON,
+ []string{"getJSON"},
+ [][2]string{},
+ )
+ return ns
}
internal.AddTemplateFuncsNamespace(f)
diff --git a/tpl/encoding/init.go b/tpl/encoding/init.go
index 5bc0eb145..b46394203 100644
--- a/tpl/encoding/init.go
+++ b/tpl/encoding/init.go
@@ -24,24 +24,35 @@ func init() {
f := func(d *deps.Deps) *internal.TemplateFuncsNamespace {
ctx := New()
- examples := [][2]string{
- {`{{ (slice "A" "B" "C") | jsonify }}`, `["A","B","C"]`},
- {`{{ "SGVsbG8gd29ybGQ=" | base64Decode }}`, `Hello world`},
- {`{{ 42 | base64Encode | base64Decode }}`, `42`},
- {`{{ "Hello world" | base64Encode }}`, `SGVsbG8gd29ybGQ=`},
- }
-
- return &internal.TemplateFuncsNamespace{
+ ns := &internal.TemplateFuncsNamespace{
Name: name,
Context: func() interface{} { return ctx },
- Aliases: map[string]interface{}{
- "base64Decode": ctx.Base64Decode,
- "base64Encode": ctx.Base64Encode,
- "jsonify": ctx.Jsonify,
- },
- Examples: examples,
}
+ ns.AddMethodMapping(ctx.Base64Decode,
+ []string{"base64Decode"},
+ [][2]string{
+ {`{{ "SGVsbG8gd29ybGQ=" | base64Decode }}`, `Hello world`},
+ {`{{ 42 | base64Encode | base64Decode }}`, `42`},
+ },
+ )
+
+ ns.AddMethodMapping(ctx.Base64Encode,
+ []string{"base64Encode"},
+ [][2]string{
+ {`{{ "Hello world" | base64Encode }}`, `SGVsbG8gd29ybGQ=`},
+ },
+ )
+
+ ns.AddMethodMapping(ctx.Jsonify,
+ []string{"jsonify"},
+ [][2]string{
+ {`{{ (slice "A" "B" "C") | jsonify }}`, `["A","B","C"]`},
+ },
+ )
+
+ return ns
+
}
internal.AddTemplateFuncsNamespace(f)
diff --git a/tpl/fmt/fmt.go b/tpl/fmt/fmt.go
index 5e320fede..ca31ec522 100644
--- a/tpl/fmt/fmt.go
+++ b/tpl/fmt/fmt.go
@@ -26,14 +26,15 @@ func New() *Namespace {
type Namespace struct {
}
-func (ns *Namespace) Print(a ...interface{}) (n int, err error) {
- return _fmt.Print(a...)
+func (ns *Namespace) Print(a ...interface{}) string {
+ return _fmt.Sprint(a...)
}
-func (ns *Namespace) Printf(format string, a ...interface{}) (n int, err error) {
- return _fmt.Printf(format, a...)
+func (ns *Namespace) Printf(format string, a ...interface{}) string {
+ return _fmt.Sprintf(format, a...)
+
}
-func (ns *Namespace) Println(a ...interface{}) (n int, err error) {
- return _fmt.Println(a...)
+func (ns *Namespace) Println(a ...interface{}) string {
+ return _fmt.Sprintln(a...)
}
diff --git a/tpl/fmt/init.go b/tpl/fmt/init.go
index 0f4296263..98070b777 100644
--- a/tpl/fmt/init.go
+++ b/tpl/fmt/init.go
@@ -24,18 +24,33 @@ func init() {
f := func(d *deps.Deps) *internal.TemplateFuncsNamespace {
ctx := New()
- examples := [][2]string{
- {`{{ print "works!" }}`, `works!`},
- {`{{ printf "%s!" "works" }}`, `works!`},
- {`{{ println "works!" }}`, "works!\n"},
+ ns := &internal.TemplateFuncsNamespace{
+ Name: name,
+ Context: func() interface{} { return ctx },
}
- return &internal.TemplateFuncsNamespace{
- Name: name,
- Context: func() interface{} { return ctx },
- Aliases: map[string]interface{}{},
- Examples: examples,
- }
+ ns.AddMethodMapping(ctx.Print,
+ []string{"print"},
+ [][2]string{
+ {`{{ print "works!" }}`, `works!`},
+ },
+ )
+
+ ns.AddMethodMapping(ctx.Println,
+ []string{"println"},
+ [][2]string{
+ {`{{ println "works!" }}`, "works!\n"},
+ },
+ )
+
+ ns.AddMethodMapping(ctx.Printf,
+ []string{"printf"},
+ [][2]string{
+ {`{{ printf "%s!" "works" }}`, `works!`},
+ },
+ )
+
+ return ns
}
diff --git a/tpl/images/init.go b/tpl/images/init.go
index 0c2cb57c4..8e829f300 100644
--- a/tpl/images/init.go
+++ b/tpl/images/init.go
@@ -24,19 +24,18 @@ func init() {
f := func(d *deps.Deps) *internal.TemplateFuncsNamespace {
ctx := New(d)
- examples := [][2]string{
- {},
- }
-
- return &internal.TemplateFuncsNamespace{
+ ns := &internal.TemplateFuncsNamespace{
Name: name,
Context: func() interface{} { return ctx },
- Aliases: map[string]interface{}{
- "imageConfig": ctx.Config,
- },
- Examples: examples,
}
+ ns.AddMethodMapping(ctx.Config,
+ []string{"imageConfig"},
+ [][2]string{},
+ )
+
+ return ns
+
}
internal.AddTemplateFuncsNamespace(f)
diff --git a/tpl/inflect/init.go b/tpl/inflect/init.go
index b42ae5af3..50d012d35 100644
--- a/tpl/inflect/init.go
+++ b/tpl/inflect/init.go
@@ -24,26 +24,37 @@ func init() {
f := func(d *deps.Deps) *internal.TemplateFuncsNamespace {
ctx := New()
- examples := [][2]string{
- {`{{ humanize "my-first-post" }}`, `My first post`},
- {`{{ humanize "myCamelPost" }}`, `My camel post`},
- {`{{ humanize "52" }}`, `52nd`},
- {`{{ humanize 103 }}`, `103rd`},
- {`{{ "cat" | pluralize }}`, `cats`},
- {`{{ "cats" | singularize }}`, `cat`},
- }
-
- return &internal.TemplateFuncsNamespace{
+ ns := &internal.TemplateFuncsNamespace{
Name: name,
Context: func() interface{} { return ctx },
- Aliases: map[string]interface{}{
- "humanize": ctx.Humanize,
- "pluralize": ctx.Pluralize,
- "singularize": ctx.Singularize,
- },
- Examples: examples,
}
+ ns.AddMethodMapping(ctx.Humanize,
+ []string{"humanize"},
+ [][2]string{
+ {`{{ humanize "my-first-post" }}`, `My first post`},
+ {`{{ humanize "myCamelPost" }}`, `My camel post`},
+ {`{{ humanize "52" }}`, `52nd`},
+ {`{{ humanize 103 }}`, `103rd`},
+ },
+ )
+
+ ns.AddMethodMapping(ctx.Pluralize,
+ []string{"pluralize"},
+ [][2]string{
+ {`{{ "cat" | pluralize }}`, `cats`},
+ },
+ )
+
+ ns.AddMethodMapping(ctx.Singularize,
+ []string{"singularize"},
+ [][2]string{
+ {`{{ "cats" | singularize }}`, `cat`},
+ },
+ )
+
+ return ns
+
}
internal.AddTemplateFuncsNamespace(f)
diff --git a/tpl/internal/templatefuncRegistry_test.go b/tpl/internal/templatefuncRegistry_test.go
new file mode 100644
index 000000000..dfc4ba09b
--- /dev/null
+++ b/tpl/internal/templatefuncRegistry_test.go
@@ -0,0 +1,33 @@
+// Copyright 2017 The Hugo Authors. All rights reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package internal
+
+import (
+ "testing"
+
+ "github.com/stretchr/testify/require"
+)
+
+type Test struct {
+}
+
+func (t *Test) MyTestMethod() string {
+ return "abcde"
+}
+
+func TestMethodToName(t *testing.T) {
+ test := &Test{}
+
+ require.Equal(t, "MyTestMethod", methodToName(test.MyTestMethod))
+}
diff --git a/tpl/internal/templatefuncsRegistry.go b/tpl/internal/templatefuncsRegistry.go
index aa3196ca3..c9c931579 100644
--- a/tpl/internal/templatefuncsRegistry.go
+++ b/tpl/internal/templatefuncsRegistry.go
@@ -16,6 +16,12 @@
package internal
import (
+ "encoding/json"
+ "path/filepath"
+ "reflect"
+ "runtime"
+ "strings"
+
"github.com/spf13/hugo/deps"
)
@@ -32,12 +38,46 @@ type TemplateFuncsNamespace struct {
// This is the method receiver.
Context interface{}
+ // Additional info, aliases and examples, per method name.
+ MethodMappings map[string]TemplateFuncMethodMapping
+}
+
+func (t *TemplateFuncsNamespace) AddMethodMapping(m interface{}, aliases []string, examples [][2]string) {
+ if t.MethodMappings == nil {
+ t.MethodMappings = make(map[string]TemplateFuncMethodMapping)
+ }
+
+ name := methodToName(m)
+
+ // sanity check
+ for _, e := range examples {
+ if e[0] == "" {
+ panic(t.Name + ": Empty example for " + name)
+ }
+ }
+ for _, a := range aliases {
+ if a == "" {
+ panic(t.Name + ": Empty alias for " + name)
+ }
+ }
+
+ t.MethodMappings[name] = TemplateFuncMethodMapping{
+ Method: m,
+ Aliases: aliases,
+ Examples: examples,
+ }
+
+}
+
+type TemplateFuncMethodMapping struct {
+ Method interface{}
+
// Any template funcs aliases. This is mainly motivated by keeping
// backwards compability, but some new template funcs may also make
// sense to give short and snappy aliases.
// Note that these aliases are global and will be merged, so the last
// key will win.
- Aliases map[string]interface{}
+ Aliases []string
// A slice of input/expected examples.
// We keep it a the namespace level for now, but may find a way to keep track
@@ -45,3 +85,44 @@ type TemplateFuncsNamespace struct {
// Some of these, hopefully just a few, may depend on some test data to run.
Examples [][2]string
}
+
+func methodToName(m interface{}) string {
+ name := runtime.FuncForPC(reflect.ValueOf(m).Pointer()).Name()
+ name = filepath.Ext(name)
+ name = strings.TrimPrefix(name, ".")
+ name = strings.TrimSuffix(name, "-fm")
+ return name
+}
+
+func (t *TemplateFuncsNamespace) MarshalJSON() ([]byte, error) {
+ type Func struct {
+ Name string
+ Description string // TODO(bep)
+ Aliases []string
+ Examples [][2]string
+ }
+ // TODO(bep) map/lookup from docs template Namespace + Func name.
+ var funcs []Func
+
+ ctx := t.Context.(func() interface{})()
+ ctxType := reflect.TypeOf(ctx)
+ for i := 0; i < ctxType.NumMethod(); i++ {
+ method := ctxType.Method(i)
+ f := Func{
+ Name: method.Name,
+ }
+ if mapping, ok := t.MethodMappings[method.Name]; ok {
+ f.Aliases = mapping.Aliases
+ f.Examples = mapping.Examples
+ }
+ funcs = append(funcs, f)
+ }
+
+ return json.Marshal(&struct {
+ Name string
+ Funcs []Func
+ }{
+ Name: t.Name,
+ Funcs: funcs,
+ })
+}
diff --git a/tpl/lang/init.go b/tpl/lang/init.go
index a902c7a66..6cf8e790d 100644
--- a/tpl/lang/init.go
+++ b/tpl/lang/init.go
@@ -24,20 +24,18 @@ func init() {
f := func(d *deps.Deps) *internal.TemplateFuncsNamespace {
ctx := New(d)
- examples := [][2]string{
- {},
- }
-
- return &internal.TemplateFuncsNamespace{
+ ns := &internal.TemplateFuncsNamespace{
Name: name,
Context: func() interface{} { return ctx },
- Aliases: map[string]interface{}{
- "i18n": ctx.Translate,
- "T": ctx.Translate,
- },
- Examples: examples,
}
+ ns.AddMethodMapping(ctx.Translate,
+ []string{"i18n", "T"},
+ [][2]string{},
+ )
+
+ return ns
+
}
internal.AddTemplateFuncsNamespace(f)
diff --git a/tpl/math/init.go b/tpl/math/init.go
index 69ba2cc17..65b22c516 100644
--- a/tpl/math/init.go
+++ b/tpl/math/init.go
@@ -24,29 +24,55 @@ func init() {
f := func(d *deps.Deps) *internal.TemplateFuncsNamespace {
ctx := New()
- examples := [][2]string{
- {"{{add 1 2}}", "3"},
- {"{{div 6 3}}", "2"},
- {"{{mod 15 3}}", "0"},
- {"{{modBool 15 3}}", "true"},
- {"{{mul 2 3}}", "6"},
- {"{{sub 3 2}}", "1"},
- }
-
- return &internal.TemplateFuncsNamespace{
+ ns := &internal.TemplateFuncsNamespace{
Name: name,
Context: func() interface{} { return ctx },
- Aliases: map[string]interface{}{
- "add": ctx.Add,
- "div": ctx.Div,
- "mod": ctx.Mod,
- "modBool": ctx.ModBool,
- "mul": ctx.Mul,
- "sub": ctx.Sub,
- },
- Examples: examples,
}
+ ns.AddMethodMapping(ctx.Add,
+ []string{"add"},
+ [][2]string{
+ {"{{add 1 2}}", "3"},
+ },
+ )
+
+ ns.AddMethodMapping(ctx.Div,
+ []string{"div"},
+ [][2]string{
+ {"{{div 6 3}}", "2"},
+ },
+ )
+
+ ns.AddMethodMapping(ctx.Mod,
+ []string{"mod"},
+ [][2]string{
+ {"{{mod 15 3}}", "0"},
+ },
+ )
+
+ ns.AddMethodMapping(ctx.ModBool,
+ []string{"modBool"},
+ [][2]string{
+ {"{{modBool 15 3}}", "true"},
+ },
+ )
+
+ ns.AddMethodMapping(ctx.Mul,
+ []string{"mul"},
+ [][2]string{
+ {"{{mul 2 3}}", "6"},
+ },
+ )
+
+ ns.AddMethodMapping(ctx.Sub,
+ []string{"sub"},
+ [][2]string{
+ {"{{sub 3 2}}", "1"},
+ },
+ )
+
+ return ns
+
}
internal.AddTemplateFuncsNamespace(f)
diff --git a/tpl/os/init.go b/tpl/os/init.go
index d03ad5f03..264afd43a 100644
--- a/tpl/os/init.go
+++ b/tpl/os/init.go
@@ -24,22 +24,32 @@ func init() {
f := func(d *deps.Deps) *internal.TemplateFuncsNamespace {
ctx := New(d)
- examples := [][2]string{
- {`{{ range (readDir ".") }}{{ .Name }}{{ end }}`, "README.txt"},
- {`{{ readFile "README.txt" }}`, `Hugo Rocks!`},
- }
-
- return &internal.TemplateFuncsNamespace{
+ ns := &internal.TemplateFuncsNamespace{
Name: name,
Context: func() interface{} { return ctx },
- Aliases: map[string]interface{}{
- "getenv": ctx.Getenv,
- "readDir": ctx.ReadDir,
- "readFile": ctx.ReadFile,
- },
- Examples: examples,
}
+ ns.AddMethodMapping(ctx.Getenv,
+ []string{"getenv"},
+ [][2]string{},
+ )
+
+ ns.AddMethodMapping(ctx.ReadDir,
+ []string{"readDir"},
+ [][2]string{
+ {`{{ range (readDir ".") }}{{ .Name }}{{ end }}`, "README.txt"},
+ },
+ )
+
+ ns.AddMethodMapping(ctx.ReadFile,
+ []string{"readFile"},
+ [][2]string{
+ {`{{ readFile "README.txt" }}`, `Hugo Rocks!`},
+ },
+ )
+
+ return ns
+
}
internal.AddTemplateFuncsNamespace(f)
diff --git a/tpl/partials/init.go b/tpl/partials/init.go
index a9d1f82fe..4ee3faf19 100644
--- a/tpl/partials/init.go
+++ b/tpl/partials/init.go
@@ -24,20 +24,25 @@ func init() {
f := func(d *deps.Deps) *internal.TemplateFuncsNamespace {
ctx := New(d)
- examples := [][2]string{
- {`{{ partial "header.html" . }}`, `<title>Hugo Rocks!</title>`},
- }
-
- return &internal.TemplateFuncsNamespace{
+ ns := &internal.TemplateFuncsNamespace{
Name: name,
Context: func() interface{} { return ctx },
- Aliases: map[string]interface{}{
- "partial": ctx.Include,
- "partialCached": ctx.getCached,
- },
- Examples: examples,
}
+ ns.AddMethodMapping(ctx.Include,
+ []string{"partial"},
+ [][2]string{
+ {`{{ partial "header.html" . }}`, `<title>Hugo Rocks!</title>`},
+ },
+ )
+
+ ns.AddMethodMapping(ctx.getCached,
+ []string{"partialCached"},
+ [][2]string{},
+ )
+
+ return ns
+
}
internal.AddTemplateFuncsNamespace(f)
diff --git a/tpl/safe/init.go b/tpl/safe/init.go
index fc47c66a7..94012a6ca 100644
--- a/tpl/safe/init.go
+++ b/tpl/safe/init.go
@@ -24,30 +24,57 @@ func init() {
f := func(d *deps.Deps) *internal.TemplateFuncsNamespace {
ctx := New()
- examples := [][2]string{
- {`{{ "Bat&Man" | safeCSS | safeCSS }}`, `Bat&amp;Man`},
- {`{{ "Bat&Man" | safeHTML | safeHTML }}`, `Bat&Man`},
- {`{{ "Bat&Man" | safeHTML }}`, `Bat&Man`},
- {`{{ "(1*2)" | safeJS | safeJS }}`, `(1*2)`},
- {`{{ "http://gohugo.io" | safeURL | safeURL }}`, `http://gohugo.io`},
- }
-
- return &internal.TemplateFuncsNamespace{
+ ns := &internal.TemplateFuncsNamespace{
Name: name,
Context: func() interface{} { return ctx },
- Aliases: map[string]interface{}{
- "safeCSS": ctx.CSS,
- "safeHTML": ctx.HTML,
- "safeHTMLAttr": ctx.HTMLAttr,
- "safeJS": ctx.JS,
- "safeJSStr": ctx.JSStr,
- "safeURL": ctx.URL,
- "sanitizeURL": ctx.SanitizeURL,
- "sanitizeurl": ctx.SanitizeURL,
- },
- Examples: examples,
}
+ ns.AddMethodMapping(ctx.CSS,
+ []string{"safeCSS"},
+ [][2]string{
+ {`{{ "Bat&Man" | safeCSS | safeCSS }}`, `Bat&amp;Man`},
+ },
+ )
+
+ ns.AddMethodMapping(ctx.HTML,
+ []string{"safeHTML"},
+ [][2]string{
+ {`{{ "Bat&Man" | safeHTML | safeHTML }}`, `Bat&Man`},
+ {`{{ "Bat&Man" | safeHTML }}`, `Bat&Man`},
+ },
+ )
+
+ ns.AddMethodMapping(ctx.HTMLAttr,
+ []string{"safeHTMLAttr"},
+ [][2]string{},
+ )
+
+ ns.AddMethodMapping(ctx.JS,
+ []string{"safeJS"},
+ [][2]string{
+ {`{{ "(1*2)" | safeJS | safeJS }}`, `(1*2)`},
+ },
+ )
+
+ ns.AddMethodMapping(ctx.JSStr,
+ []string{"safeJSStr"},
+ [][2]string{},
+ )
+
+ ns.AddMethodMapping(ctx.URL,
+ []string{"safeURL"},
+ [][2]string{
+ {`{{ "http://gohugo.io" | safeURL | safeURL }}`, `http://gohugo.io`},
+ },
+ )
+
+ ns.AddMethodMapping(ctx.SanitizeURL,
+ []string{"sanitizeURL", "sanitizeurl"},
+ [][2]string{},
+ )
+
+ return ns
+
}
internal.AddTemplateFuncsNamespace(f)
diff --git a/tpl/strings/init.go b/tpl/strings/init.go
index 8e3dfdef2..9f33bd176 100644
--- a/tpl/strings/init.go
+++ b/tpl/strings/init.go
@@ -24,54 +24,118 @@ func init() {
f := func(d *deps.Deps) *internal.TemplateFuncsNamespace {
ctx := New(d)
- examples := [][2]string{
- {`{{chomp "<p>Blockhead</p>\n" }}`, `<p>Blockhead</p>`},
- {
- `{{ findRE "[G|g]o" "Hugo is a static side generator written in Go." "1" }}`,
- `[go]`},
- {`{{ hasPrefix "Hugo" "Hu" }}`, `true`},
- {`{{ hasPrefix "Hugo" "Fu" }}`, `false`},
- {`{{lower "BatMan"}}`, `batman`},
- {
- `{{ replace "Batman and Robin" "Robin" "Catwoman" }}`,
- `Batman and Catwoman`},
- {
- `{{ "http://gohugo.io/docs" | replaceRE "^https?://([^/]+).*" "$1" }}`,
- `gohugo.io`},
- {`{{slicestr "BatMan" 0 3}}`, `Bat`},
- {`{{slicestr "BatMan" 3}}`, `Man`},
- {`{{substr "BatMan" 0 -3}}`, `Bat`},
- {`{{substr "BatMan" 3 3}}`, `Man`},
- {`{{title "Bat man"}}`, `Bat Man`},
- {`{{ trim "++Batman--" "+-" }}`, `Batman`},
- {`{{ "this is a very long text" | truncate 10 " ..." }}`, `this is a ...`},
- {`{{ "With [Markdown](/markdown) inside." | markdownify | truncate 14 }}`, `With <a href="/markdown">Markdown …</a>`},
- {`{{upper "BatMan"}}`, `BATMAN`},
- }
-
- return &internal.TemplateFuncsNamespace{
+ ns := &internal.TemplateFuncsNamespace{
Name: name,
Context: func() interface{} { return ctx },
- Aliases: map[string]interface{}{
- "chomp": ctx.Chomp,
- "countrunes": ctx.CountRunes,
- "countwords": ctx.CountWords,
- "findRE": ctx.FindRE,
- "hasPrefix": ctx.HasPrefix,
- "lower": ctx.ToLower,
- "replace": ctx.Replace,
- "replaceRE": ctx.ReplaceRE,
- "slicestr": ctx.SliceString,
- "split": ctx.Split,
- "substr": ctx.Substr,
- "title": ctx.Title,
- "trim": ctx.Trim,
- "truncate": ctx.Truncate,
- "upper": ctx.ToUpper,
- },
- Examples: examples,
}
+ ns.AddMethodMapping(ctx.Chomp,
+ []string{"chomp"},
+ [][2]string{
+ {`{{chomp "<p>Blockhead</p>\n" }}`, `<p>Blockhead</p>`},
+ },
+ )
+
+ ns.AddMethodMapping(ctx.CountRunes,
+ []string{"countrunes"},
+ [][2]string{},
+ )
+
+ ns.AddMethodMapping(ctx.CountWords,
+ []string{"countwords"},
+ [][2]string{},
+ )
+
+ ns.AddMethodMapping(ctx.FindRE,
+ []string{"findRE"},
+ [][2]string{
+ {
+ `{{ findRE "[G|g]o" "Hugo is a static side generator written in Go." "1" }}`,
+ `[go]`},
+ },
+ )
+
+ ns.AddMethodMapping(ctx.HasPrefix,
+ []string{"hasPrefix"},
+ [][2]string{
+ {`{{ hasPrefix "Hugo" "Hu" }}`, `true`},
+ {`{{ hasPrefix "Hugo" "Fu" }}`, `false`},
+ },
+ )
+
+ ns.AddMethodMapping(ctx.ToLower,
+ []string{"lower"},
+ [][2]string{
+ {`{{lower "BatMan"}}`, `batman`},
+ },
+ )
+
+ ns.AddMethodMapping(ctx.Replace,
+ []string{"replace"},
+ [][2]string{
+ {
+ `{{ replace "Batman and Robin" "Robin" "Catwoman" }}`,
+ `Batman and Catwoman`},
+ },
+ )
+
+ ns.AddMethodMapping(ctx.ReplaceRE,
+ []string{"replaceRE"},
+ [][2]string{},
+ )
+
+ ns.AddMethodMapping(ctx.SliceString,
+ []string{"slicestr"},
+ [][2]string{
+ {`{{slicestr "BatMan" 0 3}}`, `Bat`},
+ {`{{slicestr "BatMan" 3}}`, `Man`},
+ },
+ )
+
+ ns.AddMethodMapping(ctx.Split,
+ []string{"split"},
+ [][2]string{},
+ )
+
+ ns.AddMethodMapping(ctx.Substr,
+ []string{"substr"},
+ [][2]string{
+ {`{{substr "BatMan" 0 -3}}`, `Bat`},
+ {`{{substr "BatMan" 3 3}}`, `Man`},
+ },
+ )
+
+ ns.AddMethodMapping(ctx.Trim,
+ []string{"trim"},
+ [][2]string{
+ {`{{ trim "++Batman--" "+-" }}`, `Batman`},
+ },
+ )
+
+ ns.AddMethodMapping(ctx.Title,
+ []string{"title"},
+ [][2]string{
+ {`{{title "Bat man"}}`, `Bat Man`},
+ },
+ )
+
+ ns.AddMethodMapping(ctx.Truncate,
+ []string{"truncate"},
+ [][2]string{
+ {`{{ "this is a very long text" | truncate 10 " ..." }}`, `this is a ...`},
+ {`{{ "With [Markdown](/markdown) inside." | markdownify | truncate 14 }}`, `With <a href="/markdown">Markdown …</a>`},
+ },
+ )
+
+ ns.AddMethodMapping(ctx.ToUpper,
+ []string{"upper"},
+ [][2]string{
+ {`{{upper "BatMan"}}`, `BATMAN`},
+ },
+ )
+
+ return ns
+
}
internal.AddTemplateFuncsNamespace(f)
diff --git a/tpl/time/init.go b/tpl/time/init.go
index d91c1376f..33f8a7dbb 100644
--- a/tpl/time/init.go
+++ b/tpl/time/init.go
@@ -24,22 +24,32 @@ func init() {
f := func(d *deps.Deps) *internal.TemplateFuncsNamespace {
ctx := New()
- examples := [][2]string{
- {`{{ (time "2015-01-21").Year }}`, `2015`},
- {`dateFormat: {{ dateFormat "Monday, Jan 2, 2006" "2015-01-21" }}`, `dateFormat: Wednesday, Jan 21, 2015`},
- }
-
- return &internal.TemplateFuncsNamespace{
+ ns := &internal.TemplateFuncsNamespace{
Name: name,
Context: func() interface{} { return ctx },
- Aliases: map[string]interface{}{
- "dateFormat": ctx.Format,
- "now": ctx.Now,
- "time": ctx.AsTime,
- },
- Examples: examples,
}
+ ns.AddMethodMapping(ctx.Format,
+ []string{"dateFormat"},
+ [][2]string{
+ {`dateFormat: {{ dateFormat "Monday, Jan 2, 2006" "2015-01-21" }}`, `dateFormat: Wednesday, Jan 21, 2015`},
+ },
+ )
+
+ ns.AddMethodMapping(ctx.Now,
+ []string{"now"},
+ [][2]string{},
+ )
+
+ ns.AddMethodMapping(ctx.AsTime,
+ []string{"asTime"}, // TODO(bep) handle duplicate
+ [][2]string{
+ {`{{ (asTime "2015-01-21").Year }}`, `2015`},
+ },
+ )
+
+ return ns
+
}
internal.AddTemplateFuncsNamespace(f)
diff --git a/tpl/tplimpl/template_funcs.go b/tpl/tplimpl/template_funcs.go
index 089463a1e..938f4531c 100644
--- a/tpl/tplimpl/template_funcs.go
+++ b/tpl/tplimpl/template_funcs.go
@@ -51,8 +51,14 @@ func (t *templateFuncster) initFuncMap() {
panic(ns.Name + " is a duplicate template func")
}
funcMap[ns.Name] = ns.Context
- for k, v := range ns.Aliases {
- funcMap[k] = v
+ for _, mm := range ns.MethodMappings {
+ for _, alias := range mm.Aliases {
+ if _, exists := funcMap[alias]; exists {
+ panic(alias + " is a duplicate template func")
+ }
+ funcMap[alias] = mm.Method
+ }
+
}
}
diff --git a/tpl/tplimpl/template_funcs_test.go b/tpl/tplimpl/template_funcs_test.go
index b0a6e87b7..97685f96e 100644
--- a/tpl/tplimpl/template_funcs_test.go
+++ b/tpl/tplimpl/template_funcs_test.go
@@ -87,19 +87,21 @@ func TestTemplateFuncsExamples(t *testing.T) {
for _, nsf := range internal.TemplateFuncsNamespaceRegistry {
ns := nsf(d)
- for i, example := range ns.Examples {
- in, expected := example[0], example[1]
- d.WithTemplate = func(templ tpl.TemplateHandler) error {
- require.NoError(t, templ.AddTemplate("test", in))
- require.NoError(t, templ.AddTemplate("partials/header.html", "<title>Hugo Rocks!</title>"))
- return nil
- }
- require.NoError(t, d.LoadResources())
-
- var b bytes.Buffer
- require.NoError(t, d.Tmpl.Lookup("test").Execute(&b, &data))
- if b.String() != expected {
- t.Fatalf("%s[%d]: got %q expected %q", ns.Name, i, b.String(), expected)
+ for _, mm := range ns.MethodMappings {
+ for i, example := range mm.Examples {
+ in, expected := example[0], example[1]
+ d.WithTemplate = func(templ tpl.TemplateHandler) error {
+ require.NoError(t, templ.AddTemplate("test", in))
+ require.NoError(t, templ.AddTemplate("partials/header.html", "<title>Hugo Rocks!</title>"))
+ return nil
+ }
+ require.NoError(t, d.LoadResources())
+
+ var b bytes.Buffer
+ require.NoError(t, d.Tmpl.Lookup("test").Execute(&b, &data))
+ if b.String() != expected {
+ t.Fatalf("%s[%d]: got %q expected %q", ns.Name, i, b.String(), expected)
+ }
}
}
}
diff --git a/tpl/transform/init.go b/tpl/transform/init.go
index 98994c0e6..3483d1306 100644
--- a/tpl/transform/init.go
+++ b/tpl/transform/init.go
@@ -24,47 +24,72 @@ func init() {
f := func(d *deps.Deps) *internal.TemplateFuncsNamespace {
ctx := New(d)
- examples := [][2]string{
- {`{{ "I :heart: Hugo" | emojify }}`, `I ❤️ Hugo`},
- {`{{ .Title | markdownify}}`, `<strong>BatMan</strong>`},
- {`{{ plainify "Hello <strong>world</strong>, gophers!" }}`, `Hello world, gophers!`},
- {
- `htmlEscape 1: {{ htmlEscape "Cathal Garvey & The Sunshine Band <cathal@foo.bar>" | safeHTML}}`,
- `htmlEscape 1: Cathal Garvey &amp; The Sunshine Band &lt;cathal@foo.bar&gt;`},
- {
- `htmlEscape 2: {{ htmlEscape "Cathal Garvey & The Sunshine Band <cathal@foo.bar>"}}`,
- `htmlEscape 2: Cathal Garvey &amp;amp; The Sunshine Band &amp;lt;cathal@foo.bar&amp;gt;`},
- {
- `htmlUnescape 1: {{htmlUnescape "Cathal Garvey &amp; The Sunshine Band &lt;cathal@foo.bar&gt;" | safeHTML}}`,
- `htmlUnescape 1: Cathal Garvey & The Sunshine Band <cathal@foo.bar>`},
- {
- `htmlUnescape 2: {{"Cathal Garvey &amp;amp; The Sunshine Band &amp;lt;cathal@foo.bar&amp;gt;" | htmlUnescape | htmlUnescape | safeHTML}}`,
- `htmlUnescape 2: Cathal Garvey & The Sunshine Band <cathal@foo.bar>`},
- {
- `htmlUnescape 3: {{"Cathal Garvey &amp;amp; The Sunshine Band &amp;lt;cathal@foo.bar&amp;gt;" | htmlUnescape | htmlUnescape }}`,
- `htmlUnescape 3: Cathal Garvey &amp; The Sunshine Band &lt;cathal@foo.bar&gt;`},
- {
- `htmlUnescape 4: {{ htmlEscape "Cathal Garvey & The Sunshine Band <cathal@foo.bar>" | htmlUnescape | safeHTML }}`,
- `htmlUnescape 4: Cathal Garvey & The Sunshine Band <cathal@foo.bar>`},
- {
- `htmlUnescape 5: {{ htmlUnescape "Cathal Garvey &amp; The Sunshine Band &lt;cathal@foo.bar&gt;" | htmlEscape | safeHTML }}`,
- `htmlUnescape 5: Cathal Garvey &amp; The Sunshine Band &lt;cathal@foo.bar&gt;`},
- }
-
- return &internal.TemplateFuncsNamespace{
+ ns := &internal.TemplateFuncsNamespace{
Name: name,
Context: func() interface{} { return ctx },
- Aliases: map[string]interface{}{
- "emojify": ctx.Emojify,
- "highlight": ctx.Highlight,
- "htmlEscape": ctx.HTMLEscape,
- "htmlUnescape": ctx.HTMLUnescape,
- "markdownify": ctx.Markdownify,
- "plainify": ctx.Plainify,
- },
- Examples: examples,
}
+ ns.AddMethodMapping(ctx.Emojify,
+ []string{"emojify"},
+ [][2]string{
+ {`{{ "I :heart: Hugo" | emojify }}`, `I ❤️ Hugo`},
+ },
+ )
+
+ ns.AddMethodMapping(ctx.Highlight,
+ []string{"highlight"},
+ [][2]string{},
+ )
+
+ ns.AddMethodMapping(ctx.HTMLEscape,
+ []string{"htmlEscape"},
+ [][2]string{
+ {
+ `{{ htmlEscape "Cathal Garvey & The Sunshine Band <cathal@foo.bar>" | safeHTML}}`,
+ `Cathal Garvey &amp; The Sunshine Band &lt;cathal@foo.bar&gt;`},
+ {
+ `{{ htmlEscape "Cathal Garvey & The Sunshine Band <cathal@foo.bar>"}}`,
+ `Cathal Garvey &amp;amp; The Sunshine Band &amp;lt;cathal@foo.bar&amp;gt;`},
+ {
+ `{{ htmlEscape "Cathal Garvey & The Sunshine Band <cathal@foo.bar>" | htmlUnescape | safeHTML }}`,
+ `Cathal Garvey & The Sunshine Band <cathal@foo.bar>`},
+ },
+ )
+
+ ns.AddMethodMapping(ctx.HTMLUnescape,
+ []string{"htmlUnescape"},
+ [][2]string{
+ {
+ `{{ htmlUnescape "Cathal Garvey &amp; The Sunshine Band &lt;cathal@foo.bar&gt;" | safeHTML}}`,
+ `Cathal Garvey & The Sunshine Band <cathal@foo.bar>`},
+ {
+ `{{"Cathal Garvey &amp;amp; The Sunshine Band &amp;lt;cathal@foo.bar&amp;gt;" | htmlUnescape | htmlUnescape | safeHTML}}`,
+ `Cathal Garvey & The Sunshine Band <cathal@foo.bar>`},
+ {
+ `{{"Cathal Garvey &amp;amp; The Sunshine Band &amp;lt;cathal@foo.bar&amp;gt;" | htmlUnescape | htmlUnescape }}`,
+ `Cathal Garvey &amp; The Sunshine Band &lt;cathal@foo.bar&gt;`},
+ {
+ `{{ htmlUnescape "Cathal Garvey &amp; The Sunshine Band &lt;cathal@foo.bar&gt;" | htmlEscape | safeHTML }}`,
+ `Cathal Garvey &amp; The Sunshine Band &lt;cathal@foo.bar&gt;`},
+ },
+ )
+
+ ns.AddMethodMapping(ctx.Markdownify,
+ []string{"markdownify"},
+ [][2]string{
+ {`{{ .Title | markdownify}}`, `<strong>BatMan</strong>`},
+ },
+ )
+
+ ns.AddMethodMapping(ctx.Plainify,
+ []string{"plainify"},
+ [][2]string{
+ {`{{ plainify "Hello <strong>world</strong>, gophers!" }}`, `Hello world, gophers!`},
+ },
+ )
+
+ return ns
+
}
internal.AddTemplateFuncsNamespace(f)
diff --git a/tpl/urls/init.go b/tpl/urls/init.go
index fb9b00a27..e32807f32 100644
--- a/tpl/urls/init.go
+++ b/tpl/urls/init.go
@@ -24,33 +24,43 @@ func init() {
f := func(d *deps.Deps) *internal.TemplateFuncsNamespace {
ctx := New(d)
- examples := [][2]string{
- {`{{ "index.html" | absLangURL }}`, `http://mysite.com/hugo/en/index.html`},
- {`{{ "http://gohugo.io/" | absURL }}`, `http://gohugo.io/`},
- {`{{ "mystyle.css" | absURL }}`, `http://mysite.com/hugo/mystyle.css`},
- {`{{ 42 | absURL }}`, `http://mysite.com/hugo/42`},
- {`{{ "index.html" | relLangURL }}`, `/hugo/en/index.html`},
- {`{{ "http://gohugo.io/" | relURL }}`, `http://gohugo.io/`},
- {`{{ "mystyle.css" | relURL }}`, `/hugo/mystyle.css`},
- {`{{ mul 2 21 | relURL }}`, `/hugo/42`},
- {`{{ "Bat Man" | urlize }}`, `bat-man`},
- }
-
- return &internal.TemplateFuncsNamespace{
+ ns := &internal.TemplateFuncsNamespace{
Name: name,
Context: func() interface{} { return ctx },
- Aliases: map[string]interface{}{
- "absURL": ctx.AbsURL,
- "absLangURL": ctx.AbsLangURL,
- "ref": ctx.Ref,
- "relURL": ctx.RelURL,
- "relLangURL": ctx.RelLangURL,
- "relref": ctx.RelRef,
- "urlize": ctx.URLize,
- },
- Examples: examples,
}
+ ns.AddMethodMapping(ctx.AbsURL,
+ []string{"absURL"},
+ [][2]string{},
+ )
+
+ ns.AddMethodMapping(ctx.AbsLangURL,
+ []string{"absLangURL"},
+ [][2]string{},
+ )
+ ns.AddMethodMapping(ctx.Ref,
+ []string{"ref"},
+ [][2]string{},
+ )
+ ns.AddMethodMapping(ctx.RelURL,
+ []string{"relURL"},
+ [][2]string{},
+ )
+ ns.AddMethodMapping(ctx.RelLangURL,
+ []string{"relLangURL"},
+ [][2]string{},
+ )
+ ns.AddMethodMapping(ctx.RelRef,
+ []string{"relref"},
+ [][2]string{},
+ )
+ ns.AddMethodMapping(ctx.URLize,
+ []string{"urlize"},
+ [][2]string{},
+ )
+
+ return ns
+
}
internal.AddTemplateFuncsNamespace(f)