diff --git a/flash-messages/flash.tmpl b/flash-messages/flash.tmpl
index 956b796..779241c 100644
--- a/flash-messages/flash.tmpl
+++ b/flash-messages/flash.tmpl
@@ -11,33 +11,19 @@
{{.Title}}
- {{if .lvt.HasAnyFlash}}
-
- {{if .lvt.HasFlash "success"}}
- {{.lvt.Flash "success"}}
- {{end}}
- {{if .lvt.HasFlash "error"}}
- {{.lvt.Flash "error"}}
- {{end}}
- {{if .lvt.HasFlash "warning"}}
- {{.lvt.Flash "warning"}}
- {{end}}
- {{if .lvt.HasFlash "info"}}
- {{.lvt.Flash "info"}}
- {{end}}
-
- {{end}}
+ {{.lvt.FlashTag "success"}}
+ {{.lvt.FlashTag "error"}}
+ {{.lvt.FlashTag "warning"}}
+ {{.lvt.FlashTag "info"}}
@@ -78,7 +64,8 @@
They don't affect ResponseMetadata.Success
Types: success, error, warning, info
Set via: ctx.SetFlash("success", "message")
- Read via: .lvt.Flash "success", .lvt.HasFlash "success"
+ Render via: .lvt.FlashTag "success" (recommended)
+ Or manually: .lvt.HasFlash "key", .lvt.Flash "key"
diff --git a/login/main.go b/login/main.go
index b288941..1b878e4 100644
--- a/login/main.go
+++ b/login/main.go
@@ -25,7 +25,6 @@ type AuthController struct {
type AuthState struct {
Username string `lvt:"persist"`
IsLoggedIn bool `lvt:"persist"`
- Error string
ServerMessage string
LoginTime time.Time `lvt:"persist"`
}
@@ -35,20 +34,19 @@ func (c *AuthController) Login(state AuthState, ctx *livetemplate.Context) (Auth
username := ctx.GetString("username")
password := ctx.GetString("password")
- // Simple validation
- if username == "" || password == "" {
- state.Error = "Username and password are required"
- return state, nil
+ // Field-level validation
+ if username == "" {
+ return state, livetemplate.NewFieldError("username", fmt.Errorf("username is required"))
+ }
+ if password == "" {
+ return state, livetemplate.NewFieldError("password", fmt.Errorf("password is required"))
}
// Demo: accept any username with password "secret"
if password != "secret" {
- state.Error = "Invalid credentials"
+ ctx.SetFlash("error", "Invalid credentials")
return state, nil
}
-
- // Clear error and set logged in state
- state.Error = ""
state.Username = username
state.IsLoggedIn = true
state.LoginTime = time.Now()
@@ -76,7 +74,6 @@ func (c *AuthController) Login(state AuthState, ctx *livetemplate.Context) (Auth
func (c *AuthController) Logout(state AuthState, ctx *livetemplate.Context) (AuthState, error) {
state.Username = ""
state.IsLoggedIn = false
- state.Error = ""
state.ServerMessage = ""
// Delete session cookie
diff --git a/login/templates/auth.html b/login/templates/auth.html
index e166d0c..5c4f457 100644
--- a/login/templates/auth.html
+++ b/login/templates/auth.html
@@ -31,18 +31,18 @@ Dashboard
Login
- {{if .Error}}
- {{.Error}}
- {{end}}
+ {{.lvt.FlashTag "error"}}
Demo: Use any username with password secret
diff --git a/progressive-enhancement/progressive-enhancement.tmpl b/progressive-enhancement/progressive-enhancement.tmpl
index 79921e1..af43bcd 100644
--- a/progressive-enhancement/progressive-enhancement.tmpl
+++ b/progressive-enhancement/progressive-enhancement.tmpl
@@ -39,12 +39,8 @@
- {{if .lvt.Flash "success"}}
- {{.lvt.Flash "success"}}
- {{end}}
- {{if .lvt.Flash "error"}}
- {{.lvt.Flash "error"}}
- {{end}}
+ {{.lvt.FlashTag "success"}}
+ {{.lvt.FlashTag "error"}}
@@ -56,13 +52,11 @@
name="title"
value="{{.InputTitle}}"
placeholder="What needs to be done?"
- {{if .lvt.HasError "title"}}aria-invalid="true"{{end}}
+ {{.lvt.AriaInvalid "title"}}
autofocus
>
- {{if .lvt.HasError "title"}}
- {{.lvt.Error "title"}}
- {{end}}
-
+ {{.lvt.ErrorTag "title"}}
+
diff --git a/todos/todos.tmpl b/todos/todos.tmpl
index 7da37d3..68962a1 100644
--- a/todos/todos.tmpl
+++ b/todos/todos.tmpl
@@ -11,13 +11,11 @@
placeholder="What needs to be done?"
required
aria-required="true"
- {{ if .lvt.HasError "text" }}aria-invalid="true"{{ end }}
+ {{.lvt.AriaInvalid "text"}}
/>
-
+
- {{ if .lvt.HasError "text" }}
- {{ .lvt.Error "text" }}
- {{ end }}
+ {{.lvt.ErrorTag "text"}}
{{ end }}
diff --git a/ws-disabled/ws-disabled.tmpl b/ws-disabled/ws-disabled.tmpl
index e1af344..bd2871b 100644
--- a/ws-disabled/ws-disabled.tmpl
+++ b/ws-disabled/ws-disabled.tmpl
@@ -12,12 +12,8 @@
WebSocket is disabled. The client library uses HTTP fetch for all actions
and applies tree-based DOM updates without page reloads.
- {{if .lvt.Flash "success"}}
- {{.lvt.Flash "success"}}
- {{end}}
- {{if .lvt.Flash "error"}}
- {{.lvt.Flash "error"}}
- {{end}}
+ {{.lvt.FlashTag "success"}}
+ {{.lvt.FlashTag "error"}}