Usage with Templates
Simple Usage
Import github.com/textwire/textwire/v3 and call textwire.NewTemplate(nil) to create a template instance. Pass nil for defaults, or a *config.Config to customize. See configuration options.
Choose one of these initialization patterns:
- Global —
tplis a package variable accessible from any handler - Local —
tplis created inmain()and injected into handlers
import (
"net/http"
"github.com/textwire/textwire/v3"
)
var tpl *textwire.Template
func main() {
tpl, _ = textwire.NewTemplate(nil)
http.HandleFunc("/", homeHandler)
http.ListenAndServe(":8080", nil)
}
func homeHandler(w http.ResponseWriter, r *http.Request) {
tpl.Response(w, "views/home", nil)
}import (
"net/http"
"github.com/textwire/textwire/v3"
)
func main() {
tpl, _ := textwire.NewTemplate(nil)
http.HandleFunc("/", homeHandler(tpl))
http.ListenAndServe(":8080", nil)
}
func homeHandler(tpl *textwire.Template) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
tpl.Response(w, "views/home", nil)
}
}Both patterns work—use global for simplicity, local for testability. Call NewTemplate only once at startup; it parses all templates into memory.
Writing Responses to the Client
Choose how to output your rendered template:
func homeHandler(w http.ResponseWriter, r *http.Request) {
err := tpl.Response(w, "views/home", map[string]any{
"title": "Home page",
})
if err != nil {
log.Printf("Template error: %v", err)
}
}func generateEmail() (string, error) {
out, failure := tpl.String("emails/welcome", map[string]any{
"name": user.Name,
})
if failure != nil {
return "", failure.Error()
}
return out, nil
}Response()— Writes directly to HTTP response. Returns standarderror.String()— Returns rendered string and*fail.Errorwith detailed info (line, filepath, message). Callfailure.Error()to convert to standarderror.
Live Reload
If your template files are not showing up after you've created them and you are using live-reloading libraries like Fresh or Air, restart them. Also, don't forget to add .tw files to trigger live-reloading.
Layouts
Layouts are reusable templates that define the overall structure of a page. They allow you to maintain a consistent look and feel across your website while enabling you to insert dynamic content into specific reserved places. You can define a base layout which will be used by multiple pages.
To define a layout in Textwire you need to create a file anywhere within your templates directory. We recommend to store it in templates/layouts directory. This way, all of your layouts could go in there.
Reserving Space in Layouts
The @reserve directive reserves placeholders for dynamic content that can be inserted later. For example, you can reserve a space for the page title and description, and then populate it from other templates such as about-me.tw or contact-us.tw. Example layout file:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>@reserve('title')</title>
<meta name="description" content="@reserve('description')">
</head>
<body>
<main id="main-app">
@reserve('content')
</main>
</body>
</html>This layout reserves spaces for the title, description and content. These placeholders can be populated with data from templates that use this layout. The next section explains how to insert content into reserved spaces.
Learn about @reserve directive.
Inserting Content into Reserved Spaces
The @insert directive inserts content into reserved placeholders. It can be used in two ways: with or without a block. In the following example, we insert "title" and "description" without a block, and "content" with a block.
Example templates/views/home.tw template:
@use("layouts/main")
@insert("title", "Home page")
@insert("description", "Go community loves Textwire")
@insert("content")
<h1>Hello, World!</h1>
<p>This is a home page.</p>
@endExplanation:
- Specify which layout to use by providing the layout path.
- Insert the title into the layout.
- Insert the description into the layout.
- Insert the main content into the layout with the HTML block.
Learn about @insert directive.
Configuration
The NewTemplate function accepts a *config.Config parameter with several properties to customize template behavior. Common use cases include overriding the default file format or specifying the template directory. Example:
import (
"fmt"
"net/http"
"github.com/textwire/textwire/v3"
"github.com/textwire/textwire/v3/config"
)
var tpl *textwire.Template
func main() {
var err error
tpl, err = textwire.NewTemplate(&config.Config{
TemplateDir: "src/templates",
})
if err != nil {
fmt.Println(err)
}
http.HandleFunc("/", homeHandler)
http.ListenAndServe(":8080", nil)
}For detailed information about available configuration options, visit the configurations page.
