Skip to main content
Lightning uses Go’s standard text/template package for server-side rendering. Load templates once at startup with app.LoadHTMLGlob(), then render them from any handler with ctx.HTML().

Loading Templates

Call app.LoadHTMLGlob(pattern) before starting the server. The pattern follows the same glob syntax as filepath.Glob.
app.LoadHTMLGlob("templates/*.html")
LoadHTMLGlob panics if the pattern matches no files or if any template fails to parse. Always verify your template paths before deploying.

Custom Template Functions

Register custom functions with app.SetFuncMap() before calling app.LoadHTMLGlob(). The function map is applied when templates are parsed.
import (
    "fmt"
    "text/template"
    "time"

    "github.com/go-labx/lightning"
)

func formatDate(t time.Time) string {
    year, month, day := t.Date()
    return fmt.Sprintf("%d-%02d-%02d", year, month, day)
}

func main() {
    app := lightning.DefaultApp()

    // Register custom functions first
    app.SetFuncMap(template.FuncMap{
        "formatDate": formatDate,
    })

    // Then load templates (so they can use the functions)
    app.LoadHTMLGlob("templates/*.tmpl")
}

Rendering a Template

Call ctx.HTML(code, name, data) from a handler. name is the template file name as registered by the glob, and data is any value passed as the template’s dot (.).
app.Get("/", func(ctx *lightning.Context) {
    ctx.HTML(lightning.StatusOK, "index.tmpl", lightning.Map{
        "title":       "My App",
        "description": "Built with Lightning",
        "now":         time.Now(),
    })
})
If template execution fails, Lightning responds with 500 and the error message as plain text.

Complete Example

1

Create the template file

templates/index.tmpl:
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>{{.title}}</title>
    <link rel="stylesheet" href="/static/css/style.css" />
</head>
<body>
    <h1>{{.title}}</h1>
    <p>{{.description}}</p>
    <p>Today is {{.now | formatDate}}</p>
</body>
</html>
2

Write the server code

main.go:
package main

import (
    "fmt"
    "text/template"
    "time"

    "github.com/go-labx/lightning"
)

func formatDate(t time.Time) string {
    year, month, day := t.Date()
    return fmt.Sprintf("%d-%02d-%02d", year, month, day)
}

func main() {
    app := lightning.DefaultApp()

    // Serve CSS/JS from ./public at /static
    app.Static("./public", "/static")

    // Register custom template functions before loading
    app.SetFuncMap(template.FuncMap{
        "formatDate": formatDate,
    })

    // Load all templates from the templates directory
    app.LoadHTMLGlob("templates/*.tmpl")

    app.Get("/", func(ctx *lightning.Context) {
        ctx.HTML(lightning.StatusOK, "index.tmpl", lightning.Map{
            "title":       "Lightning",
            "description": "A fast web framework for Go.",
            "now":         time.Now(),
        })
    })

    app.Run(":8080")
}
3

Run and visit the page

go run main.go
# open http://localhost:8080
Use lightning.Map (a map[string]any alias) to pass ad-hoc template data without defining a dedicated struct.