summaryrefslogtreecommitdiffstats
path: root/tpl/internal
diff options
context:
space:
mode:
authorBjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com>2017-05-01 18:40:34 +0200
committerBjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com>2017-05-01 21:44:15 +0200
commit690b0f8ff5795318dfa3834a5a75d6623e7d934a (patch)
tree1112306f4c6fecc0966d880dec702c3804633deb /tpl/internal
parente2b067f0504ba41ef45786e2f83d7002bd13a7eb (diff)
tpl: Add docshelper for template funcs
And fix some other minor related issues. Updates #3418
Diffstat (limited to 'tpl/internal')
-rw-r--r--tpl/internal/templatefuncRegistry_test.go33
-rw-r--r--tpl/internal/templatefuncsRegistry.go83
2 files changed, 115 insertions, 1 deletions
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,
+ })
+}