From b843cd268aedaba339f383907df1902f8a6a6124 Mon Sep 17 00:00:00 2001 From: Virgil Date: Thu, 19 Feb 2026 16:21:21 +0000 Subject: [PATCH] Add "Template-Rendering" --- Template-Rendering.-.md | 161 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 161 insertions(+) create mode 100644 Template-Rendering.-.md diff --git a/Template-Rendering.-.md b/Template-Rendering.-.md new file mode 100644 index 0000000..dfe9dd0 --- /dev/null +++ b/Template-Rendering.-.md @@ -0,0 +1,161 @@ +# Template Rendering + +The `Render` method combines the store's key-value data with Go's `text/template` package, enabling dynamic configuration files, API payloads, and text generation from stored values. + +## How It Works + +1. All key-value pairs in the specified group are loaded into a `map[string]string` +2. The map is passed as the data context to `text/template` +3. The rendered output is returned as a string + +```go +func (s *Store) Render(tmplStr, group string) (string, error) +``` + +The template receives the full group as its root data object. Each store key becomes a field accessible with `{{ .keyname }}`. + +## Basic Usage + +```go +s, _ := store.New(":memory:") +s.Set("user", "pool", "pool.lthn.io:3333") +s.Set("user", "wallet", "iz...") + +tmpl := `{"pool":"{{ .pool }}","wallet":"{{ .wallet }}"}` +out, _ := s.Render(tmpl, "user") +// out = `{"pool":"pool.lthn.io:3333","wallet":"iz..."}` +``` + +## Go Template Syntax + +Templates use the standard Go `text/template` syntax. Here is a quick reference for the most useful features with go-store. + +### Variable Access + +Access store values using dot notation: + +``` +{{ .keyname }} +``` + +For keys containing special characters, use the `index` function: + +``` +{{ index . "my-key" }} +{{ index . "key.with.dots" }} +``` + +### Conditionals + +Check if a key has a value: + +``` +{{ if .theme }}Theme: {{ .theme }}{{ end }} +``` + +Default values using `or`: + +``` +{{ or .theme "dark" }} +``` + +### Ranges and Pipelines + +Since the data is a flat `map[string]string`, range iterates over all keys: + +``` +{{ range $key, $val := . }} +{{ $key }} = {{ $val }} +{{ end }} +``` + +### Built-in Functions + +Go templates include these functions out of the box: + +| Function | Example | Description | +|----------|---------|-------------| +| `index` | `{{ index . "key" }}` | Access map value by key string | +| `len` | `{{ len . }}` | Number of keys in the group | +| `eq` | `{{ if eq .theme "dark" }}` | String equality | +| `ne` | `{{ if ne .lang "" }}` | String inequality | +| `and` | `{{ if and .pool .wallet }}` | Logical AND | +| `or` | `{{ or .theme "default" }}` | Logical OR / default value | +| `print` | `{{ print .host ":" .port }}` | String concatenation | + +## Practical Examples + +### JSON Configuration + +```go +s.Set("mining", "pool", "pool.lthn.io:3333") +s.Set("mining", "wallet", "iz4xK...") +s.Set("mining", "threads", "4") + +tmpl := `{ + "pool": "{{ .pool }}", + "wallet": "{{ .wallet }}", + "threads": {{ .threads }} +}` +out, _ := s.Render(tmpl, "mining") +``` + +### INI-Style Configuration + +```go +s.Set("app", "name", "MyApp") +s.Set("app", "version", "1.0.0") +s.Set("app", "debug", "true") + +tmpl := `[application] +name={{ .name }} +version={{ .version }} +debug={{ .debug }}` +out, _ := s.Render(tmpl, "app") +``` + +### Environment Variables + +```go +s.Set("env", "DATABASE_URL", "sqlite:///data/app.db") +s.Set("env", "LOG_LEVEL", "info") +s.Set("env", "PORT", "8080") + +tmpl := `{{ range $key, $val := . }}{{ $key }}={{ $val }} +{{ end }}` +out, _ := s.Render(tmpl, "env") +``` + +### HTML Fragment + +```go +s.Set("site", "title", "My Site") +s.Set("site", "description", "A great site") + +tmpl := ` + {{ .title }} + +` +out, _ := s.Render(tmpl, "site") +``` + +## Error Handling + +`Render` can fail at three stages: + +1. **Database query** — the group cannot be read from SQLite +2. **Template parsing** — the template string has invalid syntax +3. **Template execution** — a referenced key does not exist in the map + +For missing keys, Go templates produce `` by default rather than failing. To fail explicitly on missing keys, use `template.Option("missingkey=error")` (not currently exposed — use `index` with a conditional instead). + +### Safe Access Pattern + +```go +tmpl := `{{ if .optional }}Value: {{ .optional }}{{ else }}(not set){{ end }}` +``` + +## Related + +- [[Home]] — Package overview and schema +- [[API-Reference]] — Full method signatures and error documentation