Skip to content

shayanderson/htx

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

HTX 🧩

HTX is a simple, composable, and testable Go HTML template extension for the Go html/template package.

Features

  • base layouts
  • partial includes
  • inline string rendering
  • template caching
  • custom template functions
  • glob pattern loading
  • easy to use and test

Installation

go get github.com/shayanderson/htx

Basic Usage

func main() {
	e := htx.New(htx.Config{
		Base:      "layout/base",
		Extension: ".html",
		Load:      []string{"partials/*.html"},
		Root:      "app/view",
	})

	var buf bytes.Buffer
	err := e.Render(&buf, "index", map[string]any{
		"name": "World",
	})
	if err != nil {
		panic(err)
	}

	fmt.Println(buf.String())
}

Engine Configuration

All engine configuration:

  • Base - base layout template name (without extension), e.g. layout/base
  • DisableCache - disable template caching (default: false)
  • Extension - template file extension, will be applied to all templates without file extensions (default: .html)
  • Funcs - custom template functions (see Template Functions)
  • Load - additional partial templates to load (supports glob patterns), e.g. partials/*.html
  • Root - root directory for templates (default: current working directory)

Example Templates

app/view/layout/base.html - base layout with header include and content block

<!DOCTYPE html>
<html>
	<head>
		<title>{{ .title }}</title>
	</head>
	<body>
		{{ include "layout/header" . }}
		<!-- content defined in other templates -->
		{{ block "content" . }}{{ end }}
	</body>
</html>

app/view/layout/header.html - header partial

<header>header</header>

app/view/partials/banner.html - banner partial, loaded via config Load option

<div class="banner">Welcome, {{ .name }}!</div>

app/view/index.html - main index template

<!-- content block will be injected into base layout -->
{{ define "content" }}
<h1>Hello, {{ .name }}!</h1>
{{ include "banner" . }} {{ end }}

Rendering a Template String

You can render a template from a string instead of a file with the RenderString method.

tpl := `
{{ define "content" }}
<h1>Hello, {{ .name }}!</h1>
{{ include "banner" . }}
{{ end }}
`
var buf bytes.Buffer
err := e.RenderString(&buf, tpl, map[string]any{
    "name": "World",
})
if err != nil {
    panic(err)
}
fmt.Println(buf.String())

Render Options

You can override the engine config options per render call via the Options struct.

err := e.Render(&buf, "index", data, htx.Options{
    // disable base layout for this render
    DisableBase: true,
    // add custom template functions for this render
    Funcs: template.FuncMap{
        "myFunc": func() string { return "myFuncVal" },
    },
    // load additional partials for this render
    Load: []string{"other_partials/*.html"},
})

All render options:

  • DisableBase - disable base layout for this render (default: false)
  • DisableCache - disable template caching for this render (default: false)
  • Funcs - additional custom template functions for this render (see Template Functions)
  • Load - additional partial templates to load for this render (supports glob patterns)

Template Functions

You can add custom template functions via the Funcs field in the Config struct or via the Options struct when rendering.

Default functions:

  • get - get a value from the engine store by key, e.g. {{ get "year" }}
    • example set store value: e.Store("year", 2025)
  • include - include another template partial, e.g. {{ include "header" . }}
  • list - creates a list
    • for iteration: {{ range list 1 2 3 }}{{ . }}{{ end }}
    • as a template variable: {{ template "myTemplate" (list 1 2 3) }}
  • map - creates a map
    • for use in templates: {{ $m := map "key1" "val1" "key2" "val2" }}{{ $m.key1 }}
    • as a template variable: {{ template "myTemplate" (map "key1" "val1" "key2" "val2") }}
    • can use with list as value: {{ template "myTemplate" (map "key1" (list 1 2 3) "key2" "val2") }}

Default Engine

You can set up a default engine to use throughout your app.

e := htx.New(htx.Config{
    // ...
})
htx.SetDefault(e)
// later in your code
err := htx.Render(&buf, "index", data)
// or access engine directly
htx.Default()

Testing

Test templates exist in testdata/ and can be tested with:

make test

About

Go html/template extension

Resources

License

Stars

Watchers

Forks

Packages

No packages published