GoHT Templates

To declare a GoHT template, you use the @goht directive followed by any valid Go function declaration. The GoHT template is then written in GoHT.

@goht Hello(name string) {
	%p Hello, #{name}!
}

This will generate a Go function named Hello that takes a single string argument name. The function returns a goht.Template which is a function that takes a context.Context and an io.Writer and returns an error.

func Hello(name string) goht.Template {
	return goht.TemplateFunc(func(ctx context.Context, __w io.Writer) (__err error) { 
		// ... 
	})
}

Templates can also be declared with a Go receiver. This allows you to create methods on a type that can be used as a template.

@goht (u *User) Greeting(name string) {
	%p #{u.Name} says "Hello, #{name}!"
}

The Go function will be generated with the receiver and the function name.

func (u *User) Greeting(name string) goht.Template {
    return goht.TemplateFunc(func(ctx context.Context, __w io.Writer) (__err error) { 
        // ... 
    })
}

You would use these templates just as you would receiver-less GoHT templates.

Rendering a template

To render a template, you call the generated Go function with the context.Context and io.Writer that you want to use.

func main() {
    var buf bytes.Buffer
    Hello("World").Render(context.Background(), &buf)
    fmt.Println(buf.String())
}

Here, we call the Hello function with a context.Background() and a bytes.Buffer. The Render method will write the output of the template to the io.Writer.

The http.ResponseWriter can be used as the io.Writer to write the output of the template to the HTTP response.

func handler(w http.ResponseWriter, r *http.Request) {
    Hello("World").Render(r.Context(), w)
}

Inside a template, you should not try to interact with the io.Writer directly but the context is available to you and can be accessed as ctx. You can use the context to get values, set values, and pass values to child templates.