From e8c5fb4c758bd8d1fb566d748bab3eea745c59ce Mon Sep 17 00:00:00 2001 From: adnaan <758447+adnaan@users.noreply.github.com> Date: Fri, 10 Jul 2026 22:24:43 +0000 Subject: [PATCH] Sync from livetemplate@v0.17.0 --- content/contributing/livetemplate.md | 4 +- content/guides/ephemeral-components.md | 4 +- content/guides/observability.md | 4 +- content/guides/progressive-complexity.md | 4 +- content/guides/scaling.md | 4 +- content/guides/standard-html-reactivity.md | 4 +- content/reference/api.md | 5 +- content/reference/authentication.md | 4 +- content/reference/client-attributes.md | 4 +- content/reference/configuration.md | 4 +- content/reference/controller-pattern.md | 58 ++++++++++++++++++-- content/reference/error-handling.md | 4 +- content/reference/limitations.md | 4 +- content/reference/navigate.md | 4 +- content/reference/progressive-complexity.md | 4 +- content/reference/pubsub.md | 4 +- content/reference/server-actions.md | 4 +- content/reference/session.md | 4 +- content/reference/template-support-matrix.md | 4 +- content/reference/uploads.md | 4 +- 20 files changed, 93 insertions(+), 42 deletions(-) diff --git a/content/contributing/livetemplate.md b/content/contributing/livetemplate.md index 2510cf3..d119c89 100644 --- a/content/contributing/livetemplate.md +++ b/content/contributing/livetemplate.md @@ -2,8 +2,8 @@ title: "Contributing to LiveTemplate Core Library" source_repo: "https://github.com/livetemplate/livetemplate" source_path: "CONTRIBUTING.md" -source_ref: "v0.16.0" -source_commit: "f4f9147c7066382d821c022caa48683d0886ad9a" +source_ref: "v0.17.0" +source_commit: "20648eb134863ff13a45b258faa0eedd1626d63f" --- # Contributing to LiveTemplate Core Library diff --git a/content/guides/ephemeral-components.md b/content/guides/ephemeral-components.md index d582769..df62fd9 100644 --- a/content/guides/ephemeral-components.md +++ b/content/guides/ephemeral-components.md @@ -2,8 +2,8 @@ title: "Ephemeral Components Guide" source_repo: "https://github.com/livetemplate/livetemplate" source_path: "docs/guides/ephemeral-components.md" -source_ref: "v0.16.0" -source_commit: "f4f9147c7066382d821c022caa48683d0886ad9a" +source_ref: "v0.17.0" +source_commit: "20648eb134863ff13a45b258faa0eedd1626d63f" --- # Ephemeral Components Guide diff --git a/content/guides/observability.md b/content/guides/observability.md index 5e4bfd6..31dac70 100644 --- a/content/guides/observability.md +++ b/content/guides/observability.md @@ -2,8 +2,8 @@ title: "LiveTemplate Observability Guide" source_repo: "https://github.com/livetemplate/livetemplate" source_path: "docs/guides/OBSERVABILITY.md" -source_ref: "v0.16.0" -source_commit: "f4f9147c7066382d821c022caa48683d0886ad9a" +source_ref: "v0.17.0" +source_commit: "20648eb134863ff13a45b258faa0eedd1626d63f" --- # LiveTemplate Observability Guide diff --git a/content/guides/progressive-complexity.md b/content/guides/progressive-complexity.md index a5f3ffe..1ae813d 100644 --- a/content/guides/progressive-complexity.md +++ b/content/guides/progressive-complexity.md @@ -2,8 +2,8 @@ title: "Progressive Complexity Guide" source_repo: "https://github.com/livetemplate/livetemplate" source_path: "docs/guides/progressive-complexity.md" -source_ref: "v0.16.0" -source_commit: "f4f9147c7066382d821c022caa48683d0886ad9a" +source_ref: "v0.17.0" +source_commit: "20648eb134863ff13a45b258faa0eedd1626d63f" --- # Progressive Complexity Guide diff --git a/content/guides/scaling.md b/content/guides/scaling.md index 2055034..dd227b6 100644 --- a/content/guides/scaling.md +++ b/content/guides/scaling.md @@ -2,8 +2,8 @@ title: "LiveTemplate Scaling Guide" source_repo: "https://github.com/livetemplate/livetemplate" source_path: "docs/guides/SCALING.md" -source_ref: "v0.16.0" -source_commit: "f4f9147c7066382d821c022caa48683d0886ad9a" +source_ref: "v0.17.0" +source_commit: "20648eb134863ff13a45b258faa0eedd1626d63f" --- # LiveTemplate Scaling Guide diff --git a/content/guides/standard-html-reactivity.md b/content/guides/standard-html-reactivity.md index ff35f7d..0a32539 100644 --- a/content/guides/standard-html-reactivity.md +++ b/content/guides/standard-html-reactivity.md @@ -2,8 +2,8 @@ title: "Standard HTML Reactivity" source_repo: "https://github.com/livetemplate/livetemplate" source_path: "docs/guides/standard-html-reactivity.md" -source_ref: "v0.16.0" -source_commit: "f4f9147c7066382d821c022caa48683d0886ad9a" +source_ref: "v0.17.0" +source_commit: "20648eb134863ff13a45b258faa0eedd1626d63f" --- # Standard HTML Reactivity diff --git a/content/reference/api.md b/content/reference/api.md index 31a7bb7..28df717 100644 --- a/content/reference/api.md +++ b/content/reference/api.md @@ -2,8 +2,8 @@ title: "Go Library API Reference" source_repo: "https://github.com/livetemplate/livetemplate" source_path: "docs/references/api-reference.md" -source_ref: "v0.16.0" -source_commit: "f4f9147c7066382d821c022caa48683d0886ad9a" +source_ref: "v0.17.0" +source_commit: "20648eb134863ff13a45b258faa0eedd1626d63f" --- # Go Library API Reference @@ -437,6 +437,7 @@ Options passed to `New()`: | `WithCookieMaxAge` | `(maxAge time.Duration)` | Session cookie max age | | `WithUpgrader` | `(upgrader *websocket.Upgrader)` | Custom WebSocket upgrader | | `WithParseFiles` | `(files ...string)` | Explicit template files | +| `WithParseFS` | `(fsys fs.FS, patterns ...string)` | Templates from an `fs.FS` (e.g. `embed.FS`); precedence over `WithParseFiles` | | `WithTemplateBaseDir` | `(dir string)` | Template discovery base dir | | `WithIgnoreTemplateDirs` | `(dirs ...string)` | Skip directories during discovery | | `WithUpload` | `(name string, config UploadConfig)` | Configure upload field | diff --git a/content/reference/authentication.md b/content/reference/authentication.md index abb3cae..4a62ccc 100644 --- a/content/reference/authentication.md +++ b/content/reference/authentication.md @@ -2,8 +2,8 @@ title: "Authentication Reference" source_repo: "https://github.com/livetemplate/livetemplate" source_path: "docs/references/authentication.md" -source_ref: "v0.16.0" -source_commit: "f4f9147c7066382d821c022caa48683d0886ad9a" +source_ref: "v0.17.0" +source_commit: "20648eb134863ff13a45b258faa0eedd1626d63f" --- # Authentication Reference diff --git a/content/reference/client-attributes.md b/content/reference/client-attributes.md index 88c7a4f..8487257 100644 --- a/content/reference/client-attributes.md +++ b/content/reference/client-attributes.md @@ -2,8 +2,8 @@ title: "Client Attributes Reference" source_repo: "https://github.com/livetemplate/livetemplate" source_path: "docs/references/client-attributes.md" -source_ref: "v0.16.0" -source_commit: "f4f9147c7066382d821c022caa48683d0886ad9a" +source_ref: "v0.17.0" +source_commit: "20648eb134863ff13a45b258faa0eedd1626d63f" --- # Client Attributes Reference diff --git a/content/reference/configuration.md b/content/reference/configuration.md index a3fd3e5..1925f57 100644 --- a/content/reference/configuration.md +++ b/content/reference/configuration.md @@ -2,8 +2,8 @@ title: "LiveTemplate Configuration Guide" source_repo: "https://github.com/livetemplate/livetemplate" source_path: "docs/references/CONFIGURATION.md" -source_ref: "v0.16.0" -source_commit: "f4f9147c7066382d821c022caa48683d0886ad9a" +source_ref: "v0.17.0" +source_commit: "20648eb134863ff13a45b258faa0eedd1626d63f" --- # LiveTemplate Configuration Guide diff --git a/content/reference/controller-pattern.md b/content/reference/controller-pattern.md index 54ef9cd..c1b67f9 100644 --- a/content/reference/controller-pattern.md +++ b/content/reference/controller-pattern.md @@ -2,8 +2,8 @@ title: "Controller+State Pattern Reference" source_repo: "https://github.com/livetemplate/livetemplate" source_path: "docs/references/controller-pattern.md" -source_ref: "v0.16.0" -source_commit: "f4f9147c7066382d821c022caa48683d0886ad9a" +source_ref: "v0.17.0" +source_commit: "20648eb134863ff13a45b258faa0eedd1626d63f" --- # Controller+State Pattern Reference @@ -213,10 +213,59 @@ func (c *TodoController) OnDisconnect() { - Cancel background jobs - Unsubscribe from data feeds +## State methods in templates + +Exported zero-arg methods on your State type are callable from templates just like +fields — `{{.ActiveCount}}` resolves to `ActiveCount()`'s return value. Methods +returning `(T, error)` are omitted (with a warning) when the error is non-nil. + +Because LiveTemplate converts State to a map before rendering, these methods are +*precomputed* — but only for methods your templates actually reference. A method that +appears nowhere in any template is never called, so an expensive or side-effecting +helper you keep on State but don't render costs nothing. + +Two caveats: + +- **Conditional references still run.** The scoping is by name, not by reachability: + `{{if .Show}}{{.Expensive}}{{end}}` still calls `Expensive()` on every render even + when `.Show` is false, because the name appears in the template text. Keep genuinely + expensive work in an action method, not a render-time State method. +- **Prefer methods without side effects.** Precompute timing is an implementation + detail; a State method should compute a view of the state, not mutate anything or + perform I/O. + ## Context API For the complete Context API (data extraction, HTTP operations, struct binding), see [API Reference — Context](api-reference.md#context). +### Request context + +`*livetemplate.Context` **embeds `context.Context`** — it carries the request/connection +context (cancellation, deadline, request-scoped values). So `ctx` *is* a `context.Context`: +pass it directly to any context-aware call (database queries, outbound HTTP, tracing) instead +of `context.Background()`. + +```go +func (c *TodoController) Add(state TodoState, ctx *livetemplate.Context) (TodoState, error) { + // ✅ ctx is a context.Context — propagates cancellation when the request/connection ends + if err := c.DB.InsertTodo(ctx, todo); err != nil { + return state, err + } + return state, nil +} +``` + +Reaching for `context.Background()` inside an action instead silently discards that +cancellation and any deadline or trace attached to the request: + +```go +// ❌ throws away request-scoped cancellation, deadline, and tracing +if err := c.DB.InsertTodo(context.Background(), todo); err != nil { ... } +``` + +Use `context.Background()` only for work that must deliberately **outlive** the request (e.g. +a fire-and-forget goroutine you start from the action) — not for the action's own calls. + ## Error Handling For validation errors, field errors, and template error display, see [Error Handling Reference](error-handling.md). @@ -266,7 +315,8 @@ type TodoController struct { } func (c *TodoController) Mount(state TodoState, ctx *livetemplate.Context) (TodoState, error) { - items, err := c.DB.GetTodos() + // Pass ctx (a context.Context) so the query is cancelled if the request ends. + items, err := c.DB.GetTodos(ctx) if err != nil { return state, fmt.Errorf("failed to load todos: %w", err) } @@ -285,7 +335,7 @@ func (c *TodoController) Add(state TodoState, ctx *livetemplate.Context) (TodoSt Title: title, } - if err := c.DB.InsertTodo(todo); err != nil { + if err := c.DB.InsertTodo(ctx, todo); err != nil { return state, fmt.Errorf("database error") } diff --git a/content/reference/error-handling.md b/content/reference/error-handling.md index becc502..c174595 100644 --- a/content/reference/error-handling.md +++ b/content/reference/error-handling.md @@ -2,8 +2,8 @@ title: "Error Handling Reference" source_repo: "https://github.com/livetemplate/livetemplate" source_path: "docs/references/error-handling.md" -source_ref: "v0.16.0" -source_commit: "f4f9147c7066382d821c022caa48683d0886ad9a" +source_ref: "v0.17.0" +source_commit: "20648eb134863ff13a45b258faa0eedd1626d63f" --- # Error Handling Reference diff --git a/content/reference/limitations.md b/content/reference/limitations.md index 2e900ee..91c217f 100644 --- a/content/reference/limitations.md +++ b/content/reference/limitations.md @@ -2,8 +2,8 @@ title: "Current Limitations" source_repo: "https://github.com/livetemplate/livetemplate" source_path: "docs/references/current-limitations.md" -source_ref: "v0.16.0" -source_commit: "f4f9147c7066382d821c022caa48683d0886ad9a" +source_ref: "v0.17.0" +source_commit: "20648eb134863ff13a45b258faa0eedd1626d63f" --- # Current Limitations diff --git a/content/reference/navigate.md b/content/reference/navigate.md index b586386..0b9e323 100644 --- a/content/reference/navigate.md +++ b/content/reference/navigate.md @@ -2,8 +2,8 @@ title: "Navigate Action Reference" source_repo: "https://github.com/livetemplate/livetemplate" source_path: "docs/references/navigate.md" -source_ref: "v0.16.0" -source_commit: "f4f9147c7066382d821c022caa48683d0886ad9a" +source_ref: "v0.17.0" +source_commit: "20648eb134863ff13a45b258faa0eedd1626d63f" --- # Navigate Action Reference diff --git a/content/reference/progressive-complexity.md b/content/reference/progressive-complexity.md index f69c763..5d48118 100644 --- a/content/reference/progressive-complexity.md +++ b/content/reference/progressive-complexity.md @@ -2,8 +2,8 @@ title: "Progressive Complexity Reference" source_repo: "https://github.com/livetemplate/livetemplate" source_path: "docs/references/progressive-complexity-reference.md" -source_ref: "v0.16.0" -source_commit: "f4f9147c7066382d821c022caa48683d0886ad9a" +source_ref: "v0.17.0" +source_commit: "20648eb134863ff13a45b258faa0eedd1626d63f" --- # Progressive Complexity Reference diff --git a/content/reference/pubsub.md b/content/reference/pubsub.md index d811619..438f328 100644 --- a/content/reference/pubsub.md +++ b/content/reference/pubsub.md @@ -2,8 +2,8 @@ title: "PubSub Reference" source_repo: "https://github.com/livetemplate/livetemplate" source_path: "docs/references/pubsub.md" -source_ref: "v0.16.0" -source_commit: "f4f9147c7066382d821c022caa48683d0886ad9a" +source_ref: "v0.17.0" +source_commit: "20648eb134863ff13a45b258faa0eedd1626d63f" --- # PubSub Reference diff --git a/content/reference/server-actions.md b/content/reference/server-actions.md index f2253b8..75dc72d 100644 --- a/content/reference/server-actions.md +++ b/content/reference/server-actions.md @@ -2,8 +2,8 @@ title: "Server Actions Reference" source_repo: "https://github.com/livetemplate/livetemplate" source_path: "docs/references/server-actions.md" -source_ref: "v0.16.0" -source_commit: "f4f9147c7066382d821c022caa48683d0886ad9a" +source_ref: "v0.17.0" +source_commit: "20648eb134863ff13a45b258faa0eedd1626d63f" --- # Server Actions Reference diff --git a/content/reference/session.md b/content/reference/session.md index dbfe5c8..9f29176 100644 --- a/content/reference/session.md +++ b/content/reference/session.md @@ -2,8 +2,8 @@ title: "Session Reference" source_repo: "https://github.com/livetemplate/livetemplate" source_path: "docs/references/session.md" -source_ref: "v0.16.0" -source_commit: "f4f9147c7066382d821c022caa48683d0886ad9a" +source_ref: "v0.17.0" +source_commit: "20648eb134863ff13a45b258faa0eedd1626d63f" --- # Session Reference diff --git a/content/reference/template-support-matrix.md b/content/reference/template-support-matrix.md index 722a1cc..af44cdb 100644 --- a/content/reference/template-support-matrix.md +++ b/content/reference/template-support-matrix.md @@ -2,8 +2,8 @@ title: "LiveTemplate Go Template Support Matrix" source_repo: "https://github.com/livetemplate/livetemplate" source_path: "docs/references/template-support-matrix.md" -source_ref: "v0.16.0" -source_commit: "f4f9147c7066382d821c022caa48683d0886ad9a" +source_ref: "v0.17.0" +source_commit: "20648eb134863ff13a45b258faa0eedd1626d63f" --- # LiveTemplate Go Template Support Matrix diff --git a/content/reference/uploads.md b/content/reference/uploads.md index 21f2e10..b90eb0b 100644 --- a/content/reference/uploads.md +++ b/content/reference/uploads.md @@ -2,8 +2,8 @@ title: "Upload Reference" source_repo: "https://github.com/livetemplate/livetemplate" source_path: "docs/references/uploads.md" -source_ref: "v0.16.0" -source_commit: "f4f9147c7066382d821c022caa48683d0886ad9a" +source_ref: "v0.17.0" +source_commit: "20648eb134863ff13a45b258faa0eedd1626d63f" --- # Upload Reference