Examples — Structure and Standards
How examples are organised, documented, and built. This document serves both as user-facing documentation and as a reference for generating or refreshing example pages.
Interactivity spectrum
Examples map to the interactivity spectrum from the philosophy document. Each example lives at a specific level:
| Level | Approach | Examples |
|---|---|---|
| 1 | Static | (docs site itself) |
| 2 | Scrolling / printing output | 02 (Output Showcase) |
| 3 | Polling (whole page refresh) | 01 (Hello World), 07 (Water Tank), 08 (Multi-Page) |
| 4 | Static + forms (CRUD) | 06 (Notes CRUD) |
| 5 | HTMX partial updates | 09 (Water Tank HTMX), 10 (Maintenance), 12 (Batch Yield) |
| 6 | WASM (browser-only) | 03 (WASM Hello World), 04 (TinyGo WASM) |
| 7 | WASM + API server | 11 (Water Tank Storage) |
The progression is deliberate — each level adds one concept. Users stop at the level of complexity their project needs.
File structure per example
Each example has two locations: source code in examples/ and rendered documentation in docs/.
examples/NN_name/
go/ # Go source code
main.go # Server entry point
model.go # Business logic (shared with WASM)
main_wasm.go # WASM entry point (if applicable)
go.mod
python/ # Python source (where applicable)
templates/
index.html # WASM demo page (standalone, clean)
app.js # WASM JavaScript glue
hello.html # Server-side template (if applicable)
index.md # Documentation source (markdown)
README.md # Brief description for browsing on Codeberg
docs/NN_name/
index.html # Rendered from index.md — NEVER overwritten by build
demo.html # Copied from templates/index.html (WASM demo)
app.js # Copied from templates/app.js
main.wasm # Compiled WASM binary
wasm_exec.js # Go WASM runtime
*.svg # Screenshots captured via url2svg
Key rule: docs:build-wasm copies WASM assets and demo.html but never overwrites index.html. The documentation page and the demo page are separate concerns.
Documentation page standard (index.md)
Each example's index.md is the single source of truth for its documentation. It is rendered to docs/NN_name/index.html by task-plus md2html. The rendered page uses shared CSS for consistent styling.
Required sections
Every example page follows this structure:
# NN — Example Name
One-paragraph introduction. What does this example demonstrate?
Why would you start from this example?
[Screenshots: polling state + complete state]
[Buttons: Launch Demo | Source on Codeberg]
---
## The model — your application logic
Annotated walkthrough of model.go. Explain what each Print/Sleep/EndAction
does and why. Include the code inline with annotations below it.
---
## The server — wiring it up
Annotated walkthrough of main.go. Show how the model is connected to HTTP.
---
## How it works
Brief explanation of the request flow. Link to technical.html for internals
if the example has one.
---
## WASM: running in the browser (if applicable)
How the same model runs in WebAssembly. Show main_wasm.go.
Build command: GOOS=js GOARCH=wasm go build -o main.wasm .
---
[Footer: Back to docs | Source on Codeberg | pkg.go.dev]
Styling conventions
The documentation page uses these custom elements (defined in shared CSS):
Annotations — blue left-border callout boxes for explanations:
<div class="annotation">
<strong>Key concept</strong> — explanation of what's happening and why.
</div>
Code blocks — standard markdown fenced blocks for source code.
Screenshots — captured via url2svg during docs:capture:NN task:
<div class="columns">
<div class="column is-5">
<figure class="image screenshot">
<img src="../NN_polling.svg" alt="During polling">
<figcaption>During polling — partial output</figcaption>
</figure>
</div>
</div>
CSS classes
These classes should be available in the rendered HTML (via md2html template or inline <style>):
.annotation {
border-left: 3px solid #3273dc;
background: #f0f4ff;
padding: 0.75em 1em;
margin: 0.75em 0;
border-radius: 0 4px 4px 0;
font-size: 0.9em;
}
.annotation strong { color: #3273dc; }
.screenshot {
border: 1px solid #dbdbdb;
border-radius: 4px;
box-shadow: 0 2px 6px rgba(0,0,0,0.1);
overflow: hidden;
}
.screenshot img { display: block; }
WASM demo page standard (templates/index.html)
The demo page is a clean standalone page for the WASM build. It is not documentation — it is a runnable demo.
Required elements
- Bulma 1.0.4 CSS from CDN
- Navbar with example title + status tag (Ready/Running) + Cancel button
- Output
<div>with loading indicator - Start button
- Loads
wasm_exec.js+app.js
app.js pattern
All examples should use the same JavaScript pattern:
const outputDiv = document.getElementById('output');
const statusTag = document.getElementById('status-tag');
const startBtn = document.getElementById('startBtn');
const cancelBtn = document.getElementById('cancel-btn');
let renderInterval = null;
function render() {
if (typeof goRender === 'function') {
outputDiv.innerHTML = goRender();
updateStatus();
}
}
function updateStatus() {
const running = typeof goIsRunning === 'function' && goIsRunning();
statusTag.textContent = running ? 'Running' : 'Ready';
statusTag.className = running ? 'tag is-warning' : 'tag is-success';
startBtn.disabled = running;
cancelBtn.style.display = running ? 'inline-flex' : 'none';
if (!running && renderInterval) {
clearInterval(renderInterval);
renderInterval = null;
}
}
function start() {
goStart();
renderInterval = setInterval(render, 500);
render();
}
window.wasmReady = function() {
startBtn.disabled = false;
outputDiv.innerHTML = '<p>Click Start to run.</p>';
};
async function loadWASM() {
const go = new Go();
const result = await WebAssembly.instantiateStreaming(
fetch('main.wasm'), go.importObject
);
go.run(result.instance);
}
startBtn.addEventListener('click', start);
cancelBtn.addEventListener('click', function() {
if (typeof goCancel === 'function') { goCancel(); render(); }
});
loadWASM();
Examples with extra controls (07–12) extend this base pattern with additional event listeners.
Build process
docs:build (markdown → HTML)
Renders all index.md files to docs/NN_name/index.html:
docs:build:
cmds:
# ... existing md2html commands ...
# Example documentation pages:
- task-plus md2html --file examples/01_hello_world/index.md --dst docs/01_hello_world
- task-plus md2html --file examples/02_svg_graph/index.md --dst docs/02_svg_graph
# etc.
docs:build-wasm (compile + copy assets)
Builds WASM binaries and copies demo assets. Must not copy index.html:
# Per example:
- mkdir -p docs/NN_name
- cd examples/NN_name/go && GOOS=js GOARCH=wasm go build -o main.wasm .
- cp wasm_exec.js docs/NN_name/
- cp examples/NN_name/go/main.wasm docs/NN_name/
- cp examples/NN_name/templates/index.html docs/NN_name/demo.html # NOT index.html
- cp examples/NN_name/templates/app.js docs/NN_name/
docs:capture:NN (screenshots)
Captures screenshots using url2svg with LOFIGUI_HOLD=1:
docs:capture:NN:
cmds:
- |
LOFIGUI_HOLD=1 go run . &
# wait for server, capture polling state, wait, capture complete state
url2svg --url http://localhost:1340 -o docs/NN_polling.svg
sleep 5
url2svg --url http://localhost:1340 -o docs/NN_complete.svg
Example list
| # | Name | Level | Pattern | Key concepts |
|---|---|---|---|---|
| 01 | Hello World | 3 — Polling | Async + refresh | App.Handle, Print, Sleep, auto-refresh, cancel |
| 02 | Output Showcase | 2 — Scrolling | Async + refresh | All output types: Print, Markdown, HTML, Table, SVG charts |
| 03 | WASM Hello World | 6 — WASM | Browser-only | RunWASM, Go→WASM compilation |
| 04 | TinyGo WASM | 6 — WASM | Browser-only | TinyGo for smaller binaries (~500KB vs ~2MB) |
| 06 | Notes CRUD | 4 — Forms | CRUD + redirect | Form POST, StateDict, RenderTemplate, redirect-after-POST |
| 07 | Water Tank | 3 — Polling | Dashboard | Generated SVG, simulation goroutine, clickable <a> links |
| 08 | Water Tank Multi | 3 — Polling | Multi-page | Multiple routes, LayoutNavbar, HTTP Refresh per-page |
| 09 | Water Tank HTMX | 5 — HTMX | Partial updates | hx-get/hx-trigger, fragment endpoints, renderAndCapture mutex |
| 10 | Water Tank Maintenance | 5 — HTMX | Background ops | context.Context cancellation, progress, equipment lockout |
| 11 | Water Tank Storage | 7 — WASM+API | Persistent state | WASM frontend + Go API server, SeaweedFS storage |
| 12 | Batch Yield | 5 — HTMX | Cooperative scheduling | lofigui.Yield() for long computations |
Choosing a starting point
- Status page / report → 01 (polling) or 02 (scrolling output)
- CRUD / forms → 06
- Real-time dashboard → 08 (HTTP Refresh) or 09 (HTMX)
- Background tasks with progress → 10
- Browser-only (no server) → 03 (WASM)
- All output types demo → 02
Refreshing example documentation
When regenerating or updating an example's index.md, follow these steps:
- Read the example's Go source code (main.go, model.go)
- Read this document for the standard format
- Read the existing
index.mdif one exists — preserve any hand-written exposition - Ensure screenshots exist (run
task docs:capture:NNif needed) - Write index.md following the required sections above
- Run
task docs:buildto render - Verify with
tp pages
The documentation should explain why, not just what. Each annotation should help a reader understand the design decision, not merely restate the code.