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
diff options
context:
space:
mode:
-rw-r--r--docs/data/docs.json1223
-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
25 files changed, 2065 insertions, 348 deletions
diff --git a/docs/data/docs.json b/docs/data/docs.json
index 12bda6e3c..9aaf52302 100644
--- 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": []
+ }
+ ]
+ }
+ ]
}
}
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)