ref: 690b0f8ff5795318dfa3834a5a75d6623e7d934a
parent: e2b067f0504ba41ef45786e2f83d7002bd13a7eb
author: Bjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com>
date: Mon May 1 14:40:34 EDT 2017
tpl: Add docshelper for template funcs And fix some other minor related issues. Updates #3418
--- a/docs/data/docs.json
+++ b/docs/data/docs.json
@@ -258,5 +258,1228 @@
]
}
]
+ },
+ "tpl": {+ "funcs": [
+ {+ "Name": "cast",
+ "Funcs": [
+ {+ "Name": "ToInt",
+ "Description": "",
+ "Aliases": [
+ "int"
+ ],
+ "Examples": [
+ [
+ "{{ \"1234\" | int | printf \"%T\" }}",+ "int"
+ ]
+ ]
+ },
+ {+ "Name": "ToString",
+ "Description": "",
+ "Aliases": [
+ "string"
+ ],
+ "Examples": [
+ [
+ "{{ 1234 | string | printf \"%T\" }}",+ "string"
+ ]
+ ]
+ }
+ ]
+ },
+ {+ "Name": "compare",
+ "Funcs": [
+ {+ "Name": "Default",
+ "Description": "",
+ "Aliases": [
+ "default"
+ ],
+ "Examples": [
+ [
+ "{{ \"Hugo Rocks!\" | default \"Hugo Rules!\" }}",+ "Hugo Rocks!"
+ ],
+ [
+ "{{ \"\" | default \"Hugo Rules!\" }}",+ "Hugo Rules!"
+ ]
+ ]
+ },
+ {+ "Name": "Eq",
+ "Description": "",
+ "Aliases": [
+ "eq"
+ ],
+ "Examples": [
+ [
+ "{{ if eq .Section \"blog\" }}current{{ end }}",+ "current"
+ ]
+ ]
+ },
+ {+ "Name": "Ge",
+ "Description": "",
+ "Aliases": [
+ "ge"
+ ],
+ "Examples": []
+ },
+ {+ "Name": "Gt",
+ "Description": "",
+ "Aliases": [
+ "gt"
+ ],
+ "Examples": []
+ },
+ {+ "Name": "Le",
+ "Description": "",
+ "Aliases": [
+ "le"
+ ],
+ "Examples": []
+ },
+ {+ "Name": "Lt",
+ "Description": "",
+ "Aliases": [
+ "lt"
+ ],
+ "Examples": []
+ },
+ {+ "Name": "Ne",
+ "Description": "",
+ "Aliases": [
+ "ne"
+ ],
+ "Examples": []
+ }
+ ]
+ },
+ {+ "Name": "collections",
+ "Funcs": [
+ {+ "Name": "After",
+ "Description": "",
+ "Aliases": [
+ "after"
+ ],
+ "Examples": []
+ },
+ {+ "Name": "Apply",
+ "Description": "",
+ "Aliases": [
+ "apply"
+ ],
+ "Examples": []
+ },
+ {+ "Name": "Delimit",
+ "Description": "",
+ "Aliases": [
+ "delimit"
+ ],
+ "Examples": [
+ [
+ "{{ delimit (slice \"A\" \"B\" \"C\") \", \" \" and \" }}",+ "A, B and C"
+ ]
+ ]
+ },
+ {+ "Name": "Dictionary",
+ "Description": "",
+ "Aliases": [
+ "dict"
+ ],
+ "Examples": []
+ },
+ {+ "Name": "EchoParam",
+ "Description": "",
+ "Aliases": [
+ "echoParam"
+ ],
+ "Examples": [
+ [
+ "{{ echoParam .Params \"langCode\" }}",+ "en"
+ ]
+ ]
+ },
+ {+ "Name": "First",
+ "Description": "",
+ "Aliases": [
+ "first"
+ ],
+ "Examples": []
+ },
+ {+ "Name": "In",
+ "Description": "",
+ "Aliases": [
+ "in"
+ ],
+ "Examples": [
+ [
+ "{{ if in \"this string contains a substring\" \"substring\" }}Substring found!{{ end }}",+ "Substring found!"
+ ]
+ ]
+ },
+ {+ "Name": "Index",
+ "Description": "",
+ "Aliases": [
+ "index"
+ ],
+ "Examples": []
+ },
+ {+ "Name": "Intersect",
+ "Description": "",
+ "Aliases": [
+ "intersect"
+ ],
+ "Examples": []
+ },
+ {+ "Name": "IsSet",
+ "Description": "",
+ "Aliases": [
+ "isSet",
+ "isset"
+ ],
+ "Examples": []
+ },
+ {+ "Name": "Last",
+ "Description": "",
+ "Aliases": [
+ "last"
+ ],
+ "Examples": []
+ },
+ {+ "Name": "Querify",
+ "Description": "",
+ "Aliases": [
+ "querify"
+ ],
+ "Examples": [
+ [
+ "{{ (querify \"foo\" 1 \"bar\" 2 \"baz\" \"with spaces\" \"qux\" \"this\u0026that=those\") | safeHTML }}",+ "bar=2\u0026baz=with+spaces\u0026foo=1\u0026qux=this%26that%3Dthose"
+ ],
+ [
+ "\u003ca href=\"https://www.google.com?{{ (querify \"q\" \"test\" \"page\" 3) | safeURL }}\"\u003eSearch\u003c/a\u003e",+ "\u003ca href=\"https://www.google.com?page=3\u0026amp;q=test\"\u003eSearch\u003c/a\u003e"
+ ]
+ ]
+ },
+ {+ "Name": "Seq",
+ "Description": "",
+ "Aliases": [
+ "seq"
+ ],
+ "Examples": [
+ [
+ "{{ seq 3 }}",+ "[1 2 3]"
+ ]
+ ]
+ },
+ {+ "Name": "Shuffle",
+ "Description": "",
+ "Aliases": [
+ "shuffle"
+ ],
+ "Examples": []
+ },
+ {+ "Name": "Slice",
+ "Description": "",
+ "Aliases": [
+ "slice"
+ ],
+ "Examples": [
+ [
+ "{{ slice \"B\" \"C\" \"A\" | sort }}",+ "[A B C]"
+ ]
+ ]
+ },
+ {+ "Name": "Sort",
+ "Description": "",
+ "Aliases": [
+ "sort"
+ ],
+ "Examples": []
+ },
+ {+ "Name": "Union",
+ "Description": "",
+ "Aliases": [
+ "union"
+ ],
+ "Examples": [
+ [
+ "{{ union (slice 1 2 3) (slice 3 4 5) }}",+ "[1 2 3 4 5]"
+ ]
+ ]
+ },
+ {+ "Name": "Where",
+ "Description": "",
+ "Aliases": [
+ "where"
+ ],
+ "Examples": []
+ }
+ ]
+ },
+ {+ "Name": "crypto",
+ "Funcs": [
+ {+ "Name": "MD5",
+ "Description": "",
+ "Aliases": [
+ "md5"
+ ],
+ "Examples": [
+ [
+ "{{ md5 \"Hello world, gophers!\" }}",+ "b3029f756f98f79e7f1b7f1d1f0dd53b"
+ ],
+ [
+ "{{ crypto.MD5 \"Hello world, gophers!\" }}",+ "b3029f756f98f79e7f1b7f1d1f0dd53b"
+ ]
+ ]
+ },
+ {+ "Name": "SHA1",
+ "Description": "",
+ "Aliases": [
+ "sha1"
+ ],
+ "Examples": [
+ [
+ "{{ sha1 \"Hello world, gophers!\" }}",+ "c8b5b0e33d408246e30f53e32b8f7627a7a649d4"
+ ]
+ ]
+ },
+ {+ "Name": "SHA256",
+ "Description": "",
+ "Aliases": [
+ "sha256"
+ ],
+ "Examples": [
+ [
+ "{{ sha256 \"Hello world, gophers!\" }}",+ "6ec43b78da9669f50e4e422575c54bf87536954ccd58280219c393f2ce352b46"
+ ]
+ ]
+ }
+ ]
+ },
+ {+ "Name": "data",
+ "Funcs": [
+ {+ "Name": "GetCSV",
+ "Description": "",
+ "Aliases": [
+ "getCSV"
+ ],
+ "Examples": []
+ },
+ {+ "Name": "GetJSON",
+ "Description": "",
+ "Aliases": [
+ "getJSON"
+ ],
+ "Examples": []
+ }
+ ]
+ },
+ {+ "Name": "encoding",
+ "Funcs": [
+ {+ "Name": "Base64Decode",
+ "Description": "",
+ "Aliases": [
+ "base64Decode"
+ ],
+ "Examples": [
+ [
+ "{{ \"SGVsbG8gd29ybGQ=\" | base64Decode }}",+ "Hello world"
+ ],
+ [
+ "{{ 42 | base64Encode | base64Decode }}",+ "42"
+ ]
+ ]
+ },
+ {+ "Name": "Base64Encode",
+ "Description": "",
+ "Aliases": [
+ "base64Encode"
+ ],
+ "Examples": [
+ [
+ "{{ \"Hello world\" | base64Encode }}",+ "SGVsbG8gd29ybGQ="
+ ]
+ ]
+ },
+ {+ "Name": "Jsonify",
+ "Description": "",
+ "Aliases": [
+ "jsonify"
+ ],
+ "Examples": [
+ [
+ "{{ (slice \"A\" \"B\" \"C\") | jsonify }}",+ "[\"A\",\"B\",\"C\"]"
+ ]
+ ]
+ }
+ ]
+ },
+ {+ "Name": "fmt",
+ "Funcs": [
+ {+ "Name": "Print",
+ "Description": "",
+ "Aliases": [
+ "print"
+ ],
+ "Examples": [
+ [
+ "{{ print \"works!\" }}",+ "works!"
+ ]
+ ]
+ },
+ {+ "Name": "Printf",
+ "Description": "",
+ "Aliases": [
+ "printf"
+ ],
+ "Examples": [
+ [
+ "{{ printf \"%s!\" \"works\" }}",+ "works!"
+ ]
+ ]
+ },
+ {+ "Name": "Println",
+ "Description": "",
+ "Aliases": [
+ "println"
+ ],
+ "Examples": [
+ [
+ "{{ println \"works!\" }}",+ "works!\n"
+ ]
+ ]
+ }
+ ]
+ },
+ {+ "Name": "images",
+ "Funcs": [
+ {+ "Name": "Config",
+ "Description": "",
+ "Aliases": [
+ "imageConfig"
+ ],
+ "Examples": []
+ },
+ {+ "Name": "Lock",
+ "Description": "",
+ "Aliases": null,
+ "Examples": null
+ },
+ {+ "Name": "RLock",
+ "Description": "",
+ "Aliases": null,
+ "Examples": null
+ },
+ {+ "Name": "RLocker",
+ "Description": "",
+ "Aliases": null,
+ "Examples": null
+ },
+ {+ "Name": "RUnlock",
+ "Description": "",
+ "Aliases": null,
+ "Examples": null
+ },
+ {+ "Name": "Unlock",
+ "Description": "",
+ "Aliases": null,
+ "Examples": null
+ }
+ ]
+ },
+ {+ "Name": "inflect",
+ "Funcs": [
+ {+ "Name": "Humanize",
+ "Description": "",
+ "Aliases": [
+ "humanize"
+ ],
+ "Examples": [
+ [
+ "{{ humanize \"my-first-post\" }}",+ "My first post"
+ ],
+ [
+ "{{ humanize \"myCamelPost\" }}",+ "My camel post"
+ ],
+ [
+ "{{ humanize \"52\" }}",+ "52nd"
+ ],
+ [
+ "{{ humanize 103 }}",+ "103rd"
+ ]
+ ]
+ },
+ {+ "Name": "Pluralize",
+ "Description": "",
+ "Aliases": [
+ "pluralize"
+ ],
+ "Examples": [
+ [
+ "{{ \"cat\" | pluralize }}",+ "cats"
+ ]
+ ]
+ },
+ {+ "Name": "Singularize",
+ "Description": "",
+ "Aliases": [
+ "singularize"
+ ],
+ "Examples": [
+ [
+ "{{ \"cats\" | singularize }}",+ "cat"
+ ]
+ ]
+ }
+ ]
+ },
+ {+ "Name": "lang",
+ "Funcs": [
+ {+ "Name": "Translate",
+ "Description": "",
+ "Aliases": [
+ "i18n",
+ "T"
+ ],
+ "Examples": []
+ }
+ ]
+ },
+ {+ "Name": "math",
+ "Funcs": [
+ {+ "Name": "Add",
+ "Description": "",
+ "Aliases": [
+ "add"
+ ],
+ "Examples": [
+ [
+ "{{add 1 2}}",+ "3"
+ ]
+ ]
+ },
+ {+ "Name": "Div",
+ "Description": "",
+ "Aliases": [
+ "div"
+ ],
+ "Examples": [
+ [
+ "{{div 6 3}}",+ "2"
+ ]
+ ]
+ },
+ {+ "Name": "Mod",
+ "Description": "",
+ "Aliases": [
+ "mod"
+ ],
+ "Examples": [
+ [
+ "{{mod 15 3}}",+ "0"
+ ]
+ ]
+ },
+ {+ "Name": "ModBool",
+ "Description": "",
+ "Aliases": [
+ "modBool"
+ ],
+ "Examples": [
+ [
+ "{{modBool 15 3}}",+ "true"
+ ]
+ ]
+ },
+ {+ "Name": "Mul",
+ "Description": "",
+ "Aliases": [
+ "mul"
+ ],
+ "Examples": [
+ [
+ "{{mul 2 3}}",+ "6"
+ ]
+ ]
+ },
+ {+ "Name": "Sub",
+ "Description": "",
+ "Aliases": [
+ "sub"
+ ],
+ "Examples": [
+ [
+ "{{sub 3 2}}",+ "1"
+ ]
+ ]
+ }
+ ]
+ },
+ {+ "Name": "os",
+ "Funcs": [
+ {+ "Name": "Getenv",
+ "Description": "",
+ "Aliases": [
+ "getenv"
+ ],
+ "Examples": []
+ },
+ {+ "Name": "ReadDir",
+ "Description": "",
+ "Aliases": [
+ "readDir"
+ ],
+ "Examples": [
+ [
+ "{{ range (readDir \".\") }}{{ .Name }}{{ end }}",+ "README.txt"
+ ]
+ ]
+ },
+ {+ "Name": "ReadFile",
+ "Description": "",
+ "Aliases": [
+ "readFile"
+ ],
+ "Examples": [
+ [
+ "{{ readFile \"README.txt\" }}",+ "Hugo Rocks!"
+ ]
+ ]
+ }
+ ]
+ },
+ {+ "Name": "partials",
+ "Funcs": [
+ {+ "Name": "Include",
+ "Description": "",
+ "Aliases": [
+ "partial"
+ ],
+ "Examples": [
+ [
+ "{{ partial \"header.html\" . }}",+ "\u003ctitle\u003eHugo Rocks!\u003c/title\u003e"
+ ]
+ ]
+ }
+ ]
+ },
+ {+ "Name": "safe",
+ "Funcs": [
+ {+ "Name": "CSS",
+ "Description": "",
+ "Aliases": [
+ "safeCSS"
+ ],
+ "Examples": [
+ [
+ "{{ \"Bat\u0026Man\" | safeCSS | safeCSS }}",+ "Bat\u0026amp;Man"
+ ]
+ ]
+ },
+ {+ "Name": "HTML",
+ "Description": "",
+ "Aliases": [
+ "safeHTML"
+ ],
+ "Examples": [
+ [
+ "{{ \"Bat\u0026Man\" | safeHTML | safeHTML }}",+ "Bat\u0026Man"
+ ],
+ [
+ "{{ \"Bat\u0026Man\" | safeHTML }}",+ "Bat\u0026Man"
+ ]
+ ]
+ },
+ {+ "Name": "HTMLAttr",
+ "Description": "",
+ "Aliases": [
+ "safeHTMLAttr"
+ ],
+ "Examples": []
+ },
+ {+ "Name": "JS",
+ "Description": "",
+ "Aliases": [
+ "safeJS"
+ ],
+ "Examples": [
+ [
+ "{{ \"(1*2)\" | safeJS | safeJS }}",+ "(1*2)"
+ ]
+ ]
+ },
+ {+ "Name": "JSStr",
+ "Description": "",
+ "Aliases": [
+ "safeJSStr"
+ ],
+ "Examples": []
+ },
+ {+ "Name": "SanitizeURL",
+ "Description": "",
+ "Aliases": [
+ "sanitizeURL",
+ "sanitizeurl"
+ ],
+ "Examples": []
+ },
+ {+ "Name": "URL",
+ "Description": "",
+ "Aliases": [
+ "safeURL"
+ ],
+ "Examples": [
+ [
+ "{{ \"http://gohugo.io\" | safeURL | safeURL }}",+ "http://gohugo.io"
+ ]
+ ]
+ }
+ ]
+ },
+ {+ "Name": "strings",
+ "Funcs": [
+ {+ "Name": "Chomp",
+ "Description": "",
+ "Aliases": [
+ "chomp"
+ ],
+ "Examples": [
+ [
+ "{{chomp \"\u003cp\u003eBlockhead\u003c/p\u003e\\n\" }}",+ "\u003cp\u003eBlockhead\u003c/p\u003e"
+ ]
+ ]
+ },
+ {+ "Name": "Contains",
+ "Description": "",
+ "Aliases": null,
+ "Examples": null
+ },
+ {+ "Name": "ContainsAny",
+ "Description": "",
+ "Aliases": null,
+ "Examples": null
+ },
+ {+ "Name": "CountRunes",
+ "Description": "",
+ "Aliases": [
+ "countrunes"
+ ],
+ "Examples": []
+ },
+ {+ "Name": "CountWords",
+ "Description": "",
+ "Aliases": [
+ "countwords"
+ ],
+ "Examples": []
+ },
+ {+ "Name": "FindRE",
+ "Description": "",
+ "Aliases": [
+ "findRE"
+ ],
+ "Examples": [
+ [
+ "{{ findRE \"[G|g]o\" \"Hugo is a static side generator written in Go.\" \"1\" }}",+ "[go]"
+ ]
+ ]
+ },
+ {+ "Name": "HasPrefix",
+ "Description": "",
+ "Aliases": [
+ "hasPrefix"
+ ],
+ "Examples": [
+ [
+ "{{ hasPrefix \"Hugo\" \"Hu\" }}",+ "true"
+ ],
+ [
+ "{{ hasPrefix \"Hugo\" \"Fu\" }}",+ "false"
+ ]
+ ]
+ },
+ {+ "Name": "HasSuffix",
+ "Description": "",
+ "Aliases": null,
+ "Examples": null
+ },
+ {+ "Name": "Replace",
+ "Description": "",
+ "Aliases": [
+ "replace"
+ ],
+ "Examples": [
+ [
+ "{{ replace \"Batman and Robin\" \"Robin\" \"Catwoman\" }}",+ "Batman and Catwoman"
+ ]
+ ]
+ },
+ {+ "Name": "ReplaceRE",
+ "Description": "",
+ "Aliases": [
+ "replaceRE"
+ ],
+ "Examples": []
+ },
+ {+ "Name": "SliceString",
+ "Description": "",
+ "Aliases": [
+ "slicestr"
+ ],
+ "Examples": [
+ [
+ "{{slicestr \"BatMan\" 0 3}}",+ "Bat"
+ ],
+ [
+ "{{slicestr \"BatMan\" 3}}",+ "Man"
+ ]
+ ]
+ },
+ {+ "Name": "Split",
+ "Description": "",
+ "Aliases": [
+ "split"
+ ],
+ "Examples": []
+ },
+ {+ "Name": "Substr",
+ "Description": "",
+ "Aliases": [
+ "substr"
+ ],
+ "Examples": [
+ [
+ "{{substr \"BatMan\" 0 -3}}",+ "Bat"
+ ],
+ [
+ "{{substr \"BatMan\" 3 3}}",+ "Man"
+ ]
+ ]
+ },
+ {+ "Name": "Title",
+ "Description": "",
+ "Aliases": [
+ "title"
+ ],
+ "Examples": [
+ [
+ "{{title \"Bat man\"}}",+ "Bat Man"
+ ]
+ ]
+ },
+ {+ "Name": "ToLower",
+ "Description": "",
+ "Aliases": [
+ "lower"
+ ],
+ "Examples": [
+ [
+ "{{lower \"BatMan\"}}",+ "batman"
+ ]
+ ]
+ },
+ {+ "Name": "ToUpper",
+ "Description": "",
+ "Aliases": [
+ "upper"
+ ],
+ "Examples": [
+ [
+ "{{upper \"BatMan\"}}",+ "BATMAN"
+ ]
+ ]
+ },
+ {+ "Name": "Trim",
+ "Description": "",
+ "Aliases": [
+ "trim"
+ ],
+ "Examples": [
+ [
+ "{{ trim \"++Batman--\" \"+-\" }}",+ "Batman"
+ ]
+ ]
+ },
+ {+ "Name": "TrimPrefix",
+ "Description": "",
+ "Aliases": null,
+ "Examples": null
+ },
+ {+ "Name": "TrimSuffix",
+ "Description": "",
+ "Aliases": null,
+ "Examples": null
+ },
+ {+ "Name": "Truncate",
+ "Description": "",
+ "Aliases": [
+ "truncate"
+ ],
+ "Examples": [
+ [
+ "{{ \"this is a very long text\" | truncate 10 \" ...\" }}",+ "this is a ..."
+ ],
+ [
+ "{{ \"With [Markdown](/markdown) inside.\" | markdownify | truncate 14 }}",+ "With \u003ca href=\"/markdown\"\u003eMarkdown …\u003c/a\u003e"
+ ]
+ ]
+ }
+ ]
+ },
+ {+ "Name": "time",
+ "Funcs": [
+ {+ "Name": "AsTime",
+ "Description": "",
+ "Aliases": [
+ "asTime"
+ ],
+ "Examples": [
+ [
+ "{{ (asTime \"2015-01-21\").Year }}",+ "2015"
+ ]
+ ]
+ },
+ {+ "Name": "Format",
+ "Description": "",
+ "Aliases": [
+ "dateFormat"
+ ],
+ "Examples": [
+ [
+ "dateFormat: {{ dateFormat \"Monday, Jan 2, 2006\" \"2015-01-21\" }}",+ "dateFormat: Wednesday, Jan 21, 2015"
+ ]
+ ]
+ },
+ {+ "Name": "Now",
+ "Description": "",
+ "Aliases": [
+ "now"
+ ],
+ "Examples": []
+ }
+ ]
+ },
+ {+ "Name": "transform",
+ "Funcs": [
+ {+ "Name": "Emojify",
+ "Description": "",
+ "Aliases": [
+ "emojify"
+ ],
+ "Examples": [
+ [
+ "{{ \"I :heart: Hugo\" | emojify }}",+ "I ❤️ Hugo"
+ ]
+ ]
+ },
+ {+ "Name": "HTMLEscape",
+ "Description": "",
+ "Aliases": [
+ "htmlEscape"
+ ],
+ "Examples": [
+ [
+ "{{ htmlEscape \"Cathal Garvey \u0026 The Sunshine Band \u003ccathal@foo.bar\u003e\" | safeHTML}}",+ "Cathal Garvey \u0026amp; The Sunshine Band \u0026lt;cathal@foo.bar\u0026gt;"
+ ],
+ [
+ "{{ htmlEscape \"Cathal Garvey \u0026 The Sunshine Band \u003ccathal@foo.bar\u003e\"}}",+ "Cathal Garvey \u0026amp;amp; The Sunshine Band \u0026amp;lt;cathal@foo.bar\u0026amp;gt;"
+ ],
+ [
+ "{{ htmlEscape \"Cathal Garvey \u0026 The Sunshine Band \u003ccathal@foo.bar\u003e\" | htmlUnescape | safeHTML }}",+ "Cathal Garvey \u0026 The Sunshine Band \u003ccathal@foo.bar\u003e"
+ ]
+ ]
+ },
+ {+ "Name": "HTMLUnescape",
+ "Description": "",
+ "Aliases": [
+ "htmlUnescape"
+ ],
+ "Examples": [
+ [
+ "{{ htmlUnescape \"Cathal Garvey \u0026amp; The Sunshine Band \u0026lt;cathal@foo.bar\u0026gt;\" | safeHTML}}",+ "Cathal Garvey \u0026 The Sunshine Band \u003ccathal@foo.bar\u003e"
+ ],
+ [
+ "{{\"Cathal Garvey \u0026amp;amp; The Sunshine Band \u0026amp;lt;cathal@foo.bar\u0026amp;gt;\" | htmlUnescape | htmlUnescape | safeHTML}}",+ "Cathal Garvey \u0026 The Sunshine Band \u003ccathal@foo.bar\u003e"
+ ],
+ [
+ "{{\"Cathal Garvey \u0026amp;amp; The Sunshine Band \u0026amp;lt;cathal@foo.bar\u0026amp;gt;\" | htmlUnescape | htmlUnescape }}",+ "Cathal Garvey \u0026amp; The Sunshine Band \u0026lt;cathal@foo.bar\u0026gt;"
+ ],
+ [
+ "{{ htmlUnescape \"Cathal Garvey \u0026amp; The Sunshine Band \u0026lt;cathal@foo.bar\u0026gt;\" | htmlEscape | safeHTML }}",+ "Cathal Garvey \u0026amp; The Sunshine Band \u0026lt;cathal@foo.bar\u0026gt;"
+ ]
+ ]
+ },
+ {+ "Name": "Highlight",
+ "Description": "",
+ "Aliases": [
+ "highlight"
+ ],
+ "Examples": []
+ },
+ {+ "Name": "Markdownify",
+ "Description": "",
+ "Aliases": [
+ "markdownify"
+ ],
+ "Examples": [
+ [
+ "{{ .Title | markdownify}}",+ "\u003cstrong\u003eBatMan\u003c/strong\u003e"
+ ]
+ ]
+ },
+ {+ "Name": "Plainify",
+ "Description": "",
+ "Aliases": [
+ "plainify"
+ ],
+ "Examples": [
+ [
+ "{{ plainify \"Hello \u003cstrong\u003eworld\u003c/strong\u003e, gophers!\" }}",+ "Hello world, gophers!"
+ ]
+ ]
+ }
+ ]
+ },
+ {+ "Name": "urls",
+ "Funcs": [
+ {+ "Name": "AbsLangURL",
+ "Description": "",
+ "Aliases": [
+ "absLangURL"
+ ],
+ "Examples": []
+ },
+ {+ "Name": "AbsURL",
+ "Description": "",
+ "Aliases": [
+ "absURL"
+ ],
+ "Examples": []
+ },
+ {+ "Name": "Ref",
+ "Description": "",
+ "Aliases": [
+ "ref"
+ ],
+ "Examples": []
+ },
+ {+ "Name": "RelLangURL",
+ "Description": "",
+ "Aliases": [
+ "relLangURL"
+ ],
+ "Examples": []
+ },
+ {+ "Name": "RelRef",
+ "Description": "",
+ "Aliases": [
+ "relref"
+ ],
+ "Examples": []
+ },
+ {+ "Name": "RelURL",
+ "Description": "",
+ "Aliases": [
+ "relURL"
+ ],
+ "Examples": []
+ },
+ {+ "Name": "URLize",
+ "Description": "",
+ "Aliases": [
+ "urlize"
+ ],
+ "Examples": []
+ }
+ ]
+ }
+ ]
}
}
--- /dev/null
+++ b/tpl/cast/docshelper.go
@@ -1,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)+}
--- a/tpl/cast/init.go
+++ b/tpl/cast/init.go
@@ -24,20 +24,26 @@
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
}
--- a/tpl/collections/init.go
+++ b/tpl/collections/init.go
@@ -24,47 +24,121 @@
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&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&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
}
--- a/tpl/compare/init.go
+++ b/tpl/compare/init.go
@@ -24,26 +24,52 @@
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
}
--- a/tpl/crypto/init.go
+++ b/tpl/crypto/init.go
@@ -24,23 +24,34 @@
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
}
--- a/tpl/data/init.go
+++ b/tpl/data/init.go
@@ -24,19 +24,21 @@
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)
--- a/tpl/encoding/init.go
+++ b/tpl/encoding/init.go
@@ -24,23 +24,34 @@
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
}
--- a/tpl/fmt/fmt.go
+++ b/tpl/fmt/fmt.go
@@ -26,14 +26,15 @@
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...)
}
--- a/tpl/fmt/init.go
+++ b/tpl/fmt/init.go
@@ -24,18 +24,33 @@
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
}
--- a/tpl/images/init.go
+++ b/tpl/images/init.go
@@ -24,18 +24,17 @@
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
}
--- a/tpl/inflect/init.go
+++ b/tpl/inflect/init.go
@@ -24,25 +24,36 @@
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
}
--- /dev/null
+++ b/tpl/internal/templatefuncRegistry_test.go
@@ -1,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))
+}
--- 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 @@
// 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
@@ -44,4 +84,45 @@
// of the single template func, for documentation purposes.
// 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,
+ })
}
--- a/tpl/lang/init.go
+++ b/tpl/lang/init.go
@@ -24,19 +24,17 @@
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
}
--- a/tpl/math/init.go
+++ b/tpl/math/init.go
@@ -24,28 +24,54 @@
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
}
--- a/tpl/os/init.go
+++ b/tpl/os/init.go
@@ -24,21 +24,31 @@
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
}
--- a/tpl/partials/init.go
+++ b/tpl/partials/init.go
@@ -24,19 +24,24 @@
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
}
--- a/tpl/safe/init.go
+++ b/tpl/safe/init.go
@@ -24,29 +24,56 @@
f := func(d *deps.Deps) *internal.TemplateFuncsNamespace {ctx := New()
- examples := [][2]string{- {`{{ "Bat&Man" | safeCSS | safeCSS }}`, `Bat&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&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
}
--- a/tpl/strings/init.go
+++ b/tpl/strings/init.go
@@ -24,53 +24,117 @@
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
}
--- a/tpl/time/init.go
+++ b/tpl/time/init.go
@@ -24,21 +24,31 @@
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
}
--- a/tpl/tplimpl/template_funcs.go
+++ b/tpl/tplimpl/template_funcs.go
@@ -51,8 +51,14 @@
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
+ }
+
}
}
--- a/tpl/tplimpl/template_funcs_test.go
+++ b/tpl/tplimpl/template_funcs_test.go
@@ -87,19 +87,21 @@
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())
+ 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)+ 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)+ }
}
}
}
--- a/tpl/transform/init.go
+++ b/tpl/transform/init.go
@@ -24,46 +24,71 @@
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 & The Sunshine Band <cathal@foo.bar>`},
- {- `htmlEscape 2: {{ htmlEscape "Cathal Garvey & The Sunshine Band <cathal@foo.bar>"}}`,- `htmlEscape 2: Cathal Garvey &amp; The Sunshine Band &lt;cathal@foo.bar&gt;`},
- {- `htmlUnescape 1: {{htmlUnescape "Cathal Garvey & The Sunshine Band <cathal@foo.bar>" | safeHTML}}`,- `htmlUnescape 1: Cathal Garvey & The Sunshine Band <cathal@foo.bar>`},
- {- `htmlUnescape 2: {{"Cathal Garvey &amp; The Sunshine Band &lt;cathal@foo.bar&gt;" | htmlUnescape | htmlUnescape | safeHTML}}`,- `htmlUnescape 2: Cathal Garvey & The Sunshine Band <cathal@foo.bar>`},
- {- `htmlUnescape 3: {{"Cathal Garvey &amp; The Sunshine Band &lt;cathal@foo.bar&gt;" | htmlUnescape | htmlUnescape }}`,- `htmlUnescape 3: Cathal Garvey & The Sunshine Band <cathal@foo.bar>`},
- {- `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 & The Sunshine Band <cathal@foo.bar>" | htmlEscape | safeHTML }}`,- `htmlUnescape 5: Cathal Garvey & The Sunshine Band <cathal@foo.bar>`},
- }
-
- 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 & The Sunshine Band <cathal@foo.bar>`},
+ {+ `{{ htmlEscape "Cathal Garvey & The Sunshine Band <cathal@foo.bar>"}}`,+ `Cathal Garvey &amp; The Sunshine Band &lt;cathal@foo.bar&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 & The Sunshine Band <cathal@foo.bar>" | safeHTML}}`,+ `Cathal Garvey & The Sunshine Band <cathal@foo.bar>`},
+ {+ `{{"Cathal Garvey &amp; The Sunshine Band &lt;cathal@foo.bar&gt;" | htmlUnescape | htmlUnescape | safeHTML}}`,+ `Cathal Garvey & The Sunshine Band <cathal@foo.bar>`},
+ {+ `{{"Cathal Garvey &amp; The Sunshine Band &lt;cathal@foo.bar&gt;" | htmlUnescape | htmlUnescape }}`,+ `Cathal Garvey & The Sunshine Band <cathal@foo.bar>`},
+ {+ `{{ htmlUnescape "Cathal Garvey & The Sunshine Band <cathal@foo.bar>" | htmlEscape | safeHTML }}`,+ `Cathal Garvey & The Sunshine Band <cathal@foo.bar>`},
+ },
+ )
+
+ 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
}
--- a/tpl/urls/init.go
+++ b/tpl/urls/init.go
@@ -24,32 +24,42 @@
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
}
--
⑨