Core Functions¶
Functions and types exported by the burrow package for use in handlers and apps.
Handlers¶
HandlerFunc¶
An HTTP handler that returns an error. Use Handle() to convert it to a standard http.HandlerFunc.
Handle¶
Converts a HandlerFunc into a standard http.HandlerFunc with centralized error handling:
*HTTPError— sends the error's status code and message- Any other error — sends 500 Internal Server Error (original error is logged)
- If the response has already started, the error is logged but no response is written
r.Get("/notes", burrow.Handle(func(w http.ResponseWriter, r *http.Request) error {
return burrow.Text(w, http.StatusOK, "Hello!")
}))
HTTPError¶
type HTTPError struct {
Message string
Code int
}
func NewHTTPError(code int, message string) *HTTPError
An error with an HTTP status code. When returned from a HandlerFunc, Handle() sends it as the response.
Response Helpers¶
JSON¶
Writes a JSON response. Sets Content-Type: application/json.
Text¶
Writes a plain text response. Sets Content-Type: text/plain; charset=utf-8.
HTML¶
Writes an HTML string response. Sets Content-Type: text/html; charset=utf-8.
Render¶
func Render(w http.ResponseWriter, r *http.Request, statusCode int, name string, data map[string]any) error
Executes a named template and writes the result. Applies automatic layout and HTMX logic:
- HTMX request (
HX-Requestheader) — renders the fragment only, no layout wrapping - Normal request with layout — renders the layout template from context, passing the fragment as
.Content - Normal request without layout — renders the fragment only
See Layouts & Rendering for details on templates and layout wrapping.
RenderContent¶
func RenderContent(w http.ResponseWriter, r *http.Request, statusCode int, content template.HTML, data map[string]any) error
Writes pre-rendered HTML content with layout wrapping. Unlike Render, which executes a named template, RenderContent takes already-rendered HTML and wraps it in the active layout.
RenderError¶
Writes an error response. Picks the format automatically:
- JSON API — if
Accept: application/json, returns{"error": "...", "code": 404} - HTML — renders the
error/{code}template (e.g.error/404) through the standardRenderpipeline with layout wrapping, HTMX support, and i18n-translated messages
The framework ships default error templates for 403, 404, 405, and 500. Override them by defining {{ define "error/404" }} in any app's template FS — the last definition wins.
Template data:
| Key | Type | Description |
|---|---|---|
Code |
int |
HTTP status code |
Title |
string |
HTTP status text (e.g. "Not Found") |
Message |
string |
i18n-translated error message |
// In a handler:
return burrow.NewHTTPError(http.StatusNotFound, "item not found")
// Handle() calls RenderError automatically.
// In middleware:
burrow.RenderError(w, r, http.StatusForbidden, "forbidden")
Request Binding¶
Bind¶
Parses the request body into a struct and validates it. Supports:
application/json— decoded viajson.Decodermultipart/form-data— parsed viar.ParseMultipartForm, decoded withformstruct tagsapplication/x-www-form-urlencoded— parsed viar.ParseForm, decoded withformstruct tags
Returns a *ValidationError when validation fails.
var req struct {
Title string `form:"title" validate:"required"`
Content string `form:"content"`
}
if err := burrow.Bind(r, &req); err != nil {
return err
}
See Validation for validation tags and error handling.
Validate¶
Validates a struct using validate struct tags. Returns nil if v is not a struct, has no validate tags, or passes all checks. Returns a *ValidationError on failure.
ValidationError¶
Returned by Bind() and Validate() when validation fails. Contains a slice of FieldError values describing each failure. Not automatically converted to an HTTP response by Handle() — your handler must check for it explicitly.
var ve *burrow.ValidationError
if errors.As(err, &ve) {
if ve.HasField("email") {
// highlight the email input
}
}
FieldError¶
type FieldError struct {
Field string // field name (from form/json tag or Go field name)
Tag string // validation tag that failed (e.g., "required")
Param string // tag parameter (e.g., "3" for min=3)
Value any // the value that failed
Message string // human-readable error message
}
Context Helpers¶
Layout¶
func WithLayout(ctx context.Context, name string) context.Context
func Layout(ctx context.Context) string
Gets or sets the layout template name in the request context. The framework sets this automatically via middleware. Used by Render to wrap content in the named layout template.
NavItems¶
func WithNavItems(ctx context.Context, items []NavItem) context.Context
func NavItems(ctx context.Context) []NavItem
Gets or sets navigation items in the request context. The framework collects items from all HasNavItems apps and injects them via middleware.
AuthChecker¶
type AuthChecker struct {
IsAuthenticated func() bool
IsAdmin func() bool
}
func WithAuthChecker(ctx context.Context, checker AuthChecker) context.Context
Stores authentication state in the context via closures, allowing the core navLinks template function to filter AuthOnly/AdminOnly items without importing contrib/auth. The auth contrib app injects this automatically. When no AuthChecker is set, AuthOnly and AdminOnly items are hidden.
TemplateExecutor¶
type TemplateExecutor func(ctx context.Context, name string, data map[string]any) (template.HTML, error)
func WithTemplateExecutor(ctx context.Context, exec TemplateExecutor) context.Context
func TemplateExec(ctx context.Context) TemplateExecutor
Gets or sets the template executor in a context. The framework injects this automatically for HTTP requests. For non-HTTP rendering, use Server.TemplateExecutor() to obtain an executor after boot, then pass it via WithTemplateExecutor. Used internally by Render and RenderFragment.
Generic Context Helpers¶
func WithContextValue(ctx context.Context, key, val any) context.Context
func ContextValue[T any](ctx context.Context, key any) (T, bool)
Generic context helpers for storing and retrieving typed values. Used by contrib apps for inter-app communication.
ctx = burrow.WithContextValue(ctx, myKey{}, myValue)
val, ok := burrow.ContextValue[MyType](ctx, myKey{})
See Inter-App Communication for usage patterns.
Pagination¶
ParsePageRequest¶
Extracts page and limit from query parameters. Defaults: limit=20, page=0. Limit is clamped to [1, 100].
OffsetResult¶
Computes PageResult metadata (total pages, has more, etc.) from a total count.
PageURL¶
Builds a pagination URL that preserves existing query parameters (search, filters, sort) and sets the page parameter. Pass r.URL.RawQuery as rawQuery to retain the current query state.
burrow.PageURL("/notes", "q=alpha&sort=-created_at", 3)
// => "/notes?page=3&q=alpha&sort=-created_at"
See Pagination Guide for full usage examples.
Database¶
OpenDB¶
Opens a Den database for the given DSN. The matching backend must be blank-imported by the calling binary so its init() registers the URL scheme with Den:
import (
_ "github.com/oliverandrich/den/backend/sqlite" // for sqlite:// DSNs
_ "github.com/oliverandrich/den/backend/postgres" // for postgres:// DSNs
)
If the DSN's scheme has no matching blank-import, OpenDB returns an error naming the missing import path. SQLite DSNs auto-create the parent directory and apply burrow's PRAGMA tuning (WAL, foreign keys, busy timeout). Pass den.WithStorage(...) via opts to attach a den.Storage so mediaURL becomes available in templates.
Server.boot calls OpenDB for you using --database-dsn plus the storage configured via --storage-dsn; you only call OpenDB directly in tests or one-off CLI tools that don't go through Server.Run. Test code should prefer burrowtest.DB, which wraps OpenDB against a file-backed SQLite DSN under t.TempDir().
Configuration Helpers¶
FlagSources¶
func FlagSources(configSource func(key string) cli.ValueSource, envVar, tomlKey string) cli.ValueSourceChain
Builds a cli.ValueSourceChain from an environment variable and an optional TOML key. Used by contrib apps to wire up flag sources consistently.
&cli.StringFlag{
Name: "my-flag",
Sources: burrow.FlagSources(configSource, "MY_FLAG", "myapp.flag"),
}
IsLocalhost¶
Returns true if the host is a localhost address ("", localhost, 127.0.0.1, ::1, or *.localhost). Used by the TLS auto-detection logic.
Layout¶
Layouts are template name strings. Use SetLayout("myapp/layout") to set the layout template name. Render renders the content template, then renders the layout template with .Content set to the rendered fragment.
See Layouts & Rendering for details on implementing layouts.
Navigation¶
NavItem¶
type NavItem struct {
Label string // displayed and also used as the i18n message ID
URL string
Icon string // template-define name (e.g. "auth/icon_people"), empty for no icon
Position int // sort order (lower = earlier)
AuthOnly bool // only shown to authenticated users
AdminOnly bool // only shown to admin users
}
Layouts render Icon via the {{ icon "..." }} template function — see Template Functions.
See Navigation for positioning and ordering.
NavLink¶
type NavLink struct {
Label string
URL string
Icon string // template-define name; render with {{ icon .Icon }}
IsActive bool
}
Template-ready navigation item returned by the navLinks template function. IsActive is true when the current request path matches the item's URL (prefix match, with exact match for /). See Navigation for usage.