Aiming for Jarvis, Creating D.A.N.I.

Tutorial 25: Web templates and static files

This tutorial expands on the web server by adding HTML templates and static file serving. Because nobody wants to look at raw JSON unless they absolutely have to.

HTML templates

std/web/tmpl provides a small, reliable template engine. It's not trying to reinvent the wheel, but it keeps your business logic and your markup separated—which, believe me, your future self will thank you for.

module main

import "std/web/tmpl"
import "std/web/types"

fn home(req: types.Request, w: *types.ResponseWriter) {
    t, err1 := tmpl.Parse("<h1>Hello, {{.name}}!</h1>")
    if err1.message != "" {
        w.WriteHeader(500)
        w.Write("bad template")
        return
    }
    
    data := {
        "name": "Skink",
    }
    
    rendered, err2 := tmpl.Execute(t, data)
    if err2.message != "" {
        w.WriteHeader(500)
        w.Write("render error")
        return
    }
    
    w.HTML(200, rendered)
}

Templates use {{.Key}} for variable substitution and are automatically HTML-escaped to prevent the kind of security issues that keep us up at night.

Static files

You don't need a heavy Nginx config just to serve a CSS file. std/web/static does the job perfectly:

import "std/web/router"
import "std/web/server"
import "std/web/static"

fn main() -> int {
    r := router.NewRouter()
    r.Get("/", home)
    r.Get("/assets/*", static.FileServer("./public"))

    s := server.NewServer(8080, &r)
    serr := s.ListenAndServe()
    if serr.message != "" {
        return 1
    }
    return 0
}

static.FileServer maps paths to files under your root directory. It’s smart enough to reject paths with .., so you don't accidentally expose your config.json to the world.

Putting it together

Create a public/ directory.

Add a style.css file inside.

Reference it in your HTML: <link rel="stylesheet" href="/assets/style.css">.

Exercises

  1. Render a list of items using {{range .items}} in your template.
  2. Add a conditional {{if .admin}} block to show different content based on user status.
  3. Serve a custom favicon.ico from your public/ folder.

Next

Cryptography basics