Documentation / Template filters
Template filters
Format text, prices, dates, and collections directly in your Go templates. Learn the calling conventions first, then use the reference below to find every registered filter.
Available in every Go template
HyperChi copies filters.FuncMap() when you create an application. Templates loaded with app.LoadTemplates can call these functions immediately. They are Go template functions, not a separate expression language. The external templ and Jet integrations do not inherit this function map.
app := hyperchi.New()
helpers.Must(app.LoadTemplates("templates/*.tmpl"))
app.Get("/product", func(c *hyperchi.Context) error {
return c.View("product.tmpl", hyperchi.H{
"name": " field notebook ",
"price": 24.5,
"published": "2026-10-05T12:00:00Z",
})
})
<h1>{{ .name | trim | title }}</h1>
<p>{{ currency .price "$" }}</p>
<time>{{ .published | dateFormat "Jan 2, 2006" }}</time>
The page displays “Field Notebook”, “$24.50”, and “Oct 5, 2026”. The handler uses only the core hyperchi package. c.View hands the values to the template unchanged, so a time.Time works as well as an RFC 3339 string.
Argument order matters
A Go pipeline places its result in the last argument. Unary functions work naturally in a chain. Most multi-argument HyperChi filters take the value first, so use a direct call or parentheses.
{{ .name | trim | upper }} <!-- unary chain -->
{{ truncate .name 20 }} <!-- value first -->
{{ currency .price "€" }}
{{ default .nickname "Anonymous" }}
{{ join (sort .tags) ", " }}
{{ .published | dateFormat "2006-01-02" }} <!-- format first -->
{{ .name | truncate 20 }}is not equivalent to{{ truncate .name 20 }}. It sends20as the first argument. Likewise,defaulttakes the value before the fallback.dateFormatintentionally takes the format first and supports the pipeline shown above.
Recipes with live output
These outputs are rendered by this page using the installed filters. Change the literals in your own templates to adapt them.
Clean a label
{{ " field notebook " | trim | title }}Shorten text
{{ truncate "A notebook for every journey" 18 }}Format a price
{{ currency 1234.5 "$" }}Display a proportion
{{ percent 0.125 1 }}Human-readable storage
{{ bytes 1536 }}Format an ISO date
{{ "2026-10-05T12:00:00Z" | dateFormat "Jan 2, 2006" }}Use a fallback
{{ default "" "Anonymous" }}Sort a collection
{{ range sort (list "htmx" "go" "html") }}{{ . }} {{ end }}Read nested JSON
{{ jsonGet (fromJSON `{"user":{"name":"Morgan"}}`) "user.name" }}Count items
{{ len (list "Go" "HTML" "HTMX") }}Work with collections
sortBy, filter, and pluck accept a collection followed by a field name. Use map keys for maps such as hyperchi.H. For structs, use the exported Go field name. Sorting uses string representations, including in sortBy; sort numeric values in Go when numeric order matters. Keep database queries and business decisions in the handler.
{{ $active := filter .products "active" true }}
{{ range take (sortBy $active "name") 3 }}
<article>
<h3>{{ .name }}</h3>
<p>{{ currency .price }}</p>
</article>
{{ else }}
<p>No matching products.</p>
{{ end }}
contains is a substring test for strings and a membership test for slices and arrays (by the rules of eq, so 2 matches 2.0). join expects []string, while many collection transforms return []any. Render those results with range instead of passing them to join.
HTML, JSON, and htmx
Go’s html/template escapes ordinary values for their HTML context. Render visitor text directly; adding escape can double-escape it. nl2br escapes its text before inserting line breaks.
<p>{{ .message }}</p>
<div>{{ nl2br .message }}</div>
<div data-settings="{{ toJSON .settings }}">Settings</div>
<button {{ hxGet "/demo/echo" }} {{ hxTarget "#result" }} {{ hxSwap "innerHTML" }}>
Load a fragment
</button>
<div id="result" aria-live="polite"></div>
Load htmx separately to activate these attributes. Attribute helpers generate individual attributes: place them side by side, not in a pipeline. Keep attribute names, event expressions, and destinations application-controlled.
safe, unescape, css, and js mark content as trusted; they do not sanitize it. stripTags is a regular-expression transform that also returns trusted HTML, not a security boundary. Only use trusted-content helpers after an appropriate sanitization or application-owned-content boundary.
htmxButton and htmxForm return complete elements, not attributes. They take typed filters.HTMXButtonOptions and filters.HTMXFormOptions, not a dict. Pass the typed options in the handler data, or use literal elements with individual helpers, as above.
Register a custom filter
Register filters during startup, before loading templates and before serving traffic. Use a distinctive name so you do not accidentally replace a built-in function.
app.RegisterFilter("excerpt", func(limit int, text string) string {
if limit < 0 {
limit = 0
}
runes := []rune(text)
if len(runes) > limit {
return string(runes[:limit]) + "…"
}
return text
})
helpers.Must(app.LoadTemplates("templates/*.tmpl"))
{{ .description | excerpt 80 }}
This custom function deliberately puts text last for pipeline use. Register several functions with app.RegisterFilters(template.FuncMap{...}). To use the built-ins outside HyperChi, call template.New("page").Funcs(filters.FuncMap()).Parse(source). Package-level filters.Register affects future snapshots; it does not update applications that already copied their function maps.
Types and failure behavior
Functions returning (value, error), such as fromJSON and dateAdd, stop template execution on a non-nil error. Other helpers return fallback values: an unparseable date produces an empty string, while an unconvertible currency value is printed unchanged. Validate input in the handler rather than treating formatting as validation.
default treats false, numeric zero, and empty collections as empty, as well as empty strings and nil. Use coalesce when only nil should trigger a fallback. Validate sizes and indexes before passing visitor-controlled numbers to collection or truncation helpers.
Complete registered reference
Signatures below come from the running filter registry. Arguments appear in call order; ... means variadic arguments and interface {} means any. Expand a category to inspect every function. Functions requiring typed options or callbacks are generally easier to use from Go with direct template execution.
Strings 31 functions
br2nlfunc(string) stringcamelCasefunc(string) stringcapitalizefunc(string) stringdedentfunc(string) stringhasPrefixfunc(string, string) boolhasSuffixfunc(string, string) boolindentfunc(string, int, ...string) stringjoinfunc([]string, string) stringkebabCasefunc(string) stringlowerfunc(string) stringnl2brfunc(string) template.HTMLpascalCasefunc(string) stringpluralizefunc(string, ...int) stringquotefunc(string) stringrepeatfunc(string, int) stringreplacefunc(string, string, string, int) stringreplaceAllfunc(string, string, string) stringsingularizefunc(string) stringslugfunc(string) stringsnakeCasefunc(string) stringsplitfunc(string, string) []stringstripTagsfunc(string) template.HTMLtitlefunc(string) stringtrimfunc(string) stringtrimPrefixfunc(string, string) stringtrimSuffixfunc(string, string) stringtruncatefunc(string, int, ...string) stringtruncateWordsfunc(string, int, ...string) stringunquotefunc(string) stringupperfunc(string) stringwordWrapfunc(string, int) string
HTML 27 functions
addClassfunc(string, string) stringariaAttrsfunc(map[string]interface {}) (template.HTMLAttr, error)attrfunc(string, string) (template.HTMLAttr, error)checkboxfunc(string, interface {}, bool, ...template.HTMLAttr) template.HTMLclassNamesfunc(...interface {}) stringcssfunc(string) template.CSSdataAttrsfunc(map[string]interface {}) (template.HTMLAttr, error)escapefunc(string) stringformFieldfunc(string, string, interface {}, ...template.HTMLAttr) template.HTMLimgfunc(string, string, ...template.HTMLAttr) template.HTMLinputAttrsfunc(filters.InputOptions) (template.HTMLAttr, error)jsfunc(string) template.JSlinkfunc(string, string, ...template.HTMLAttr) template.HTMLmailtofunc(string, ...string) template.HTMLmetafunc(string, string) template.HTMLradiofunc(string, interface {}, bool, ...template.HTMLAttr) template.HTMLremoveClassfunc(string, string) stringsafefunc(string) template.HTMLscriptfunc(string, ...template.HTMLAttr) template.HTMLselectfunc(string, []filters.SelectOption, ...template.HTMLAttr) template.HTMLstylefunc(string, ...template.HTMLAttr) template.HTMLtelfunc(string, ...string) template.HTMLtextareafunc(string, interface {}, int, int, ...template.HTMLAttr) template.HTMLtoggleClassfunc(string, string) stringunescapefunc(string) template.HTMLurlfunc(string) stringurlqueryfunc(string) string
JSON 12 functions
compactJSONfunc(string) (string, error)fromJSONfunc(string) (interface {}, error)jsonArrayfunc(...interface {}) []interface {}jsonAttrfunc(string, interface {}) (template.HTMLAttr, error)jsonEscapefunc(string) stringjsonGetfunc(interface {}, string) interface {}jsonLDfunc(interface {}) template.HTMLjsonMergefunc(interface {}, interface {}) interface {}jsonObjectfunc(...interface {}) map[string]interface {}jsonSetfunc(interface {}, string, interface {}) interface {}prettyJSONfunc(interface {}) (string, error)toJSONfunc(interface {}) (string, error)
Dates and times 26 functions
datefunc(interface {}, ...string) stringdateAddfunc(interface {}, int, string) (time.Time, error)dateComparefunc(interface {}, interface {}) (int, error)dateDifffunc(interface {}, interface {}, string) (int64, error)dateFormatfunc(string, interface {}) stringdateSubfunc(interface {}, int, string) (time.Time, error)dayfunc(interface {}) intdurationSecondsfunc(time.Duration) float64fromUnixfunc(int64) time.Timehourfunc(interface {}) inthumanDurationfunc(interface {}) stringiso8601func(interface {}) stringminutefunc(interface {}) intmonthfunc(interface {}) stringnowfunc() time.Timerfc3339func(interface {}) stringsecondfunc(interface {}) inttimeAgofunc(interface {}) stringtimeFromfunc(interface {}) stringtimezonefunc(interface {}, string) (time.Time, error)todayfunc() time.Timetomorrowfunc() time.Timeunixfunc(interface {}) int64weekdayfunc(interface {}) stringyearfunc(interface {}) intyesterdayfunc() time.Time
Numbers 25 functions
absfunc(interface {}) float64addfunc(interface {}, interface {}) float64avgfunc(...interface {}) float64bytesfunc(interface {}) stringceilfunc(interface {}) float64commasfunc(string) stringcurrencyfunc(interface {}, ...string) stringdecimalfunc(interface {}, int) stringdivfunc(interface {}, interface {}) float64floorfunc(interface {}) float64humanizefunc(interface {}) stringmaxfunc(...interface {}) float64minfunc(...interface {}) float64modfunc(interface {}, interface {}) float64mulfunc(interface {}, interface {}) float64numberfunc(interface {}, ...int) stringordinalfunc(interface {}) stringpadNumberfunc(interface {}, int, ...string) stringpercentfunc(interface {}, ...int) stringpowfunc(interface {}, interface {}) float64romanfunc(interface {}) stringroundfunc(interface {}, ...int) float64sqrtfunc(interface {}) float64subfunc(interface {}, interface {}) float64sumfunc(...interface {}) float64
Collections 28 functions
chunkfunc(interface {}, int) [][]interface {}containsfunc(interface {}, interface {}) boolfilterfunc(interface {}, string, interface {}) []interface {}findfunc(interface {}, string, interface {}) interface {}findIndexfunc(interface {}, string, interface {}) intfirstfunc(interface {}) interface {}flattenfunc(interface {}) []interface {}groupfunc(interface {}, string) map[string][]interface {}indexfunc(interface {}, int) interface {}keysfunc(interface {}) []stringlastfunc(interface {}) interface {}lenfunc(interface {}) intmapfunc(interface {}, string) []interface {}mergefunc(...interface {}) map[string]interface {}pairsfunc(interface {}) [][]interface {}pluckfunc(interface {}, string) []interface {}randomfunc(interface {}) interface {}reducefunc(interface {}, func(interface {}, interface {}) interface {}, interface {}) interface {}reversefunc(interface {}) []interface {}shufflefunc(interface {}) []interface {}skipfunc(interface {}, int) []interface {}slicefunc(interface {}, int, ...int) []interface {}sortfunc(interface {}) []interface {}sortByfunc(interface {}, string) []interface {}takefunc(interface {}, int) []interface {}uniquefunc(interface {}) []interface {}valuesfunc(interface {}) []interface {}zipfunc(...interface {}) [][]interface {}
HTMX 39 functions
htmxAttrsfunc(filters.HTMXAttrs) (template.HTMLAttr, error)htmxButtonfunc(filters.HTMXButtonOptions) (template.HTML, error)htmxFormfunc(filters.HTMXFormOptions) (template.HTML, error)htmxLinkfunc(string, string, ...map[string]string) (template.HTML, error)htmxModalfunc(string, template.HTML) template.HTMLhtmxSpinnerfunc(string) template.HTMLhtmxToastfunc(string, string) template.HTMLhxActionfunc(string) template.HTMLAttrhxBoostfunc(bool) template.HTMLAttrhxConfigfunc(map[string]interface {}) template.HTMLAttrhxConfirmfunc(string) template.HTMLAttrhxDeletefunc(string) template.HTMLAttrhxDisabledEltfunc(string) template.HTMLAttrhxEncodingfunc(string) template.HTMLAttrhxGetfunc(string) template.HTMLAttrhxHeadersfunc(map[string]string) template.HTMLAttrhxIgnorefunc() template.HTMLAttrhxIncludefunc(string) template.HTMLAttrhxIndicatorfunc(string) template.HTMLAttrhxMethodfunc(string) template.HTMLAttrhxOnfunc(string, string) (template.HTMLAttr, error)hxOptimisticfunc(string) template.HTMLAttrhxPatchfunc(string) template.HTMLAttrhxPostfunc(string) template.HTMLAttrhxPreloadfunc(string) template.HTMLAttrhxPreservefunc(interface {}) template.HTMLAttrhxPushURLfunc(string) template.HTMLAttrhxPutfunc(string) template.HTMLAttrhxReplaceURLfunc(interface {}) template.HTMLAttrhxSelectfunc(string) template.HTMLAttrhxSelectOOBfunc(string) template.HTMLAttrhxStatusfunc(string, string) (template.HTMLAttr, error)hxSwapfunc(string) template.HTMLAttrhxSwapOOBfunc(string) template.HTMLAttrhxSyncfunc(string) template.HTMLAttrhxTargetfunc(string) template.HTMLAttrhxTriggerfunc(string) template.HTMLAttrhxValidatefunc(bool) template.HTMLAttrhxValsfunc(map[string]interface {}) template.HTMLAttr
Utilities 37 functions
andfunc(...interface {}) boolbase64Decodefunc(string) (string, error)base64Encodefunc(string) stringcoalescefunc(...interface {}) interface {}defaultfunc(interface {}, interface {}) interface {}dictfunc(...interface {}) map[string]interface {}emptyfunc(interface {}) boolenvfunc(string, ...string) stringeqfunc(interface {}, ...interface {}) boolfallbackfunc(...interface {}) interface {}gefunc(interface {}, interface {}) boolgtfunc(interface {}, interface {}) boolisNilfunc(interface {}) boolkindOffunc(interface {}) stringlefunc(interface {}, interface {}) boollistfunc(...interface {}) []interface {}ltfunc(interface {}, interface {}) boolnefunc(interface {}, interface {}) boolnotfunc(interface {}) boolnotEmptyfunc(interface {}) boolnotNilfunc(interface {}) boolorfunc(...interface {}) boolpathBasefunc(string) stringpathDirfunc(string) stringpathExtfunc(string) stringpathJoinfunc(...string) stringprintfunc(...interface {}) stringprintffunc(string, ...interface {}) stringprintlnfunc(...interface {}) stringregexMatchfunc(string, string) (bool, error)regexReplacefunc(string, string, string) (string, error)regexSplitfunc(string, string) ([]string, error)ternaryfunc(bool, interface {}, interface {}) interface {}typeOffunc(interface {}) stringurlDecodefunc(string) (string, error)urlEncodefunc(string) stringuuidfunc() (string, error)
Keep exploring
Read Templates for composition, Passing data for view models, or the filter implementations and tests for detailed edge behavior. Formatting helpers do not automatically transfer to templ or Jet; those renderers own their data and helper APIs.