├── README.md ├── bulkupdate ├── handlers.go ├── templates.templ └── templates_templ.go ├── clicktoedit ├── handlers.go ├── templates.templ └── templates_templ.go ├── clicktoload ├── handlers.go ├── templates.templ └── templates_templ.go ├── csrf ├── handlers.go ├── templates.templ └── templates_templ.go ├── deleterow ├── handlers.go ├── templates.templ └── templates_templ.go ├── editrow ├── handlers.go ├── templates.templ └── templates_templ.go ├── go.mod ├── go.sum ├── home.templ ├── home_templ.go ├── inlinevalidation ├── handlers.go ├── templates.templ └── templates_templ.go ├── lazyload ├── bars.svg ├── handlers.go ├── templates.templ ├── templates_templ.go └── tokyo.png ├── main.go └── shared ├── layout.templ ├── layout_templ.go └── shared.go /README.md: -------------------------------------------------------------------------------- 1 | # Go HTMX Examples 2 | 3 | implemented in Go and templ. 4 | 5 | ## Tasks 6 | 7 | ### run 8 | 9 | Runs the app and looks for changes. 10 | 11 | ``` 12 | reflex -r '.*\.(go|templ)' -R '.*_templ\.go' -s -- sh -c 'templ generate && go run .' 13 | ``` 14 | -------------------------------------------------------------------------------- /bulkupdate/handlers.go: -------------------------------------------------------------------------------- 1 | package bulkupdate 2 | 3 | import ( 4 | "log" 5 | "net/http" 6 | "strconv" 7 | ) 8 | 9 | type user struct { 10 | name, email string 11 | active bool 12 | } 13 | 14 | var inMemDB []user = []user{ 15 | {"Joe Smith", "joe@smith.org", true}, 16 | {"Angie MacDowell", "angie@macdowell.org", true}, 17 | {"Fuqua Tarketon", "fuqua@tarketon.org", true}, 18 | {"Kim Yee", "kim@yee.org", false}, 19 | } 20 | 21 | func Handlers(prefix string, mux *http.ServeMux) { 22 | mux.HandleFunc(prefix+"/", index) 23 | mux.HandleFunc(prefix+"/activate", putActivate) 24 | mux.HandleFunc(prefix+"/deactivate", putDeactivate) 25 | } 26 | 27 | func index(w http.ResponseWriter, r *http.Request) { 28 | // Load users 29 | Index(inMemDB).Render(r.Context(), w) 30 | } 31 | 32 | func putActivate(w http.ResponseWriter, r *http.Request) { 33 | if err := r.ParseForm(); err != nil { 34 | log.Println(err) 35 | w.WriteHeader(500) 36 | return 37 | } 38 | ids := map[int]bool{} 39 | for _, i := range r.Form["ids"] { 40 | id, _ := strconv.Atoi(i) 41 | user := inMemDB[id] 42 | user.active = true 43 | inMemDB[id] = user 44 | ids[id] = true 45 | } 46 | tbody(inMemDB, ids).Render(r.Context(), w) 47 | } 48 | 49 | func putDeactivate(w http.ResponseWriter, r *http.Request) { 50 | if err := r.ParseForm(); err != nil { 51 | log.Println(err) 52 | w.WriteHeader(500) 53 | return 54 | } 55 | ids := map[int]bool{} 56 | for _, i := range r.Form["ids"] { 57 | id, _ := strconv.Atoi(i) 58 | user := inMemDB[id] 59 | user.active = false 60 | inMemDB[id] = user 61 | ids[id] = true 62 | } 63 | tbody(inMemDB, ids).Render(r.Context(), w) 64 | } 65 | -------------------------------------------------------------------------------- /bulkupdate/templates.templ: -------------------------------------------------------------------------------- 1 | package bulkupdate 2 | 3 | import ( 4 | "fmt" 5 | 6 | "examples/shared" 7 | ) 8 | 9 | templ demo(users []user) { 10 |

Select Rows And Activate Or Deactivate Below

11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | @tbody(users, map[int]bool{}) 22 |
NameEmailStatus
23 |
24 |
25 | 26 | 27 |
28 | 39 | } 40 | 41 | templ tbody(users []user, modified map[int]bool) { 42 | 43 | for k, u := range users { 44 | 53 | 54 | { u.name } 55 | { u.email } 56 | 57 | if u.active { 58 | Active 59 | } else { 60 | Inactive 61 | } 62 | 63 | 64 | } 65 | 66 | } 67 | 68 | templ Index(users []user) { 69 | @shared.Layout("Bulk Update") { 70 |

Bulk Update

71 | @demo(users) 72 | } 73 | } 74 | 75 | -------------------------------------------------------------------------------- /bulkupdate/templates_templ.go: -------------------------------------------------------------------------------- 1 | // Code generated by templ@(devel) DO NOT EDIT. 2 | 3 | package bulkupdate 4 | 5 | //lint:file-ignore SA4006 This context is only used if a nested component is present. 6 | 7 | import "github.com/a-h/templ" 8 | import "context" 9 | import "io" 10 | import "bytes" 11 | 12 | // GoExpression 13 | import ( 14 | "fmt" 15 | 16 | "examples/shared" 17 | ) 18 | 19 | func demo(users []user) templ.Component { 20 | return templ.ComponentFunc(func(ctx context.Context, w io.Writer) (err error) { 21 | templBuffer, templIsBuffer := w.(*bytes.Buffer) 22 | if !templIsBuffer { 23 | templBuffer = templ.GetBuffer() 24 | defer templ.ReleaseBuffer(templBuffer) 25 | } 26 | ctx = templ.InitializeContext(ctx) 27 | var_1 := templ.GetChildren(ctx) 28 | if var_1 == nil { 29 | var_1 = templ.NopComponent 30 | } 31 | ctx = templ.ClearChildren(ctx) 32 | // Element (standard) 33 | _, err = templBuffer.WriteString("") 43 | if err != nil { 44 | return err 45 | } 46 | // Text 47 | var_2 := `Select Rows And Activate Or Deactivate Below` 48 | _, err = templBuffer.WriteString(var_2) 49 | if err != nil { 50 | return err 51 | } 52 | _, err = templBuffer.WriteString("") 53 | if err != nil { 54 | return err 55 | } 56 | // Element (standard) 57 | _, err = templBuffer.WriteString("") 67 | if err != nil { 68 | return err 69 | } 70 | // Element (standard) 71 | _, err = templBuffer.WriteString("") 81 | if err != nil { 82 | return err 83 | } 84 | // Element (standard) 85 | _, err = templBuffer.WriteString("") 86 | if err != nil { 87 | return err 88 | } 89 | // Element (standard) 90 | _, err = templBuffer.WriteString("") 91 | if err != nil { 92 | return err 93 | } 94 | // Element (standard) 95 | _, err = templBuffer.WriteString("") 96 | if err != nil { 97 | return err 98 | } 99 | _, err = templBuffer.WriteString("") 100 | if err != nil { 101 | return err 102 | } 103 | // Element (standard) 104 | _, err = templBuffer.WriteString("") 105 | if err != nil { 106 | return err 107 | } 108 | // Text 109 | var_3 := `Name` 110 | _, err = templBuffer.WriteString(var_3) 111 | if err != nil { 112 | return err 113 | } 114 | _, err = templBuffer.WriteString("") 115 | if err != nil { 116 | return err 117 | } 118 | // Element (standard) 119 | _, err = templBuffer.WriteString("") 120 | if err != nil { 121 | return err 122 | } 123 | // Text 124 | var_4 := `Email` 125 | _, err = templBuffer.WriteString(var_4) 126 | if err != nil { 127 | return err 128 | } 129 | _, err = templBuffer.WriteString("") 130 | if err != nil { 131 | return err 132 | } 133 | // Element (standard) 134 | _, err = templBuffer.WriteString("") 135 | if err != nil { 136 | return err 137 | } 138 | // Text 139 | var_5 := `Status` 140 | _, err = templBuffer.WriteString(var_5) 141 | if err != nil { 142 | return err 143 | } 144 | _, err = templBuffer.WriteString("") 145 | if err != nil { 146 | return err 147 | } 148 | _, err = templBuffer.WriteString("") 149 | if err != nil { 150 | return err 151 | } 152 | _, err = templBuffer.WriteString("") 153 | if err != nil { 154 | return err 155 | } 156 | // TemplElement 157 | err = tbody(users, map[int]bool{}).Render(ctx, templBuffer) 158 | if err != nil { 159 | return err 160 | } 161 | _, err = templBuffer.WriteString("") 162 | if err != nil { 163 | return err 164 | } 165 | _, err = templBuffer.WriteString("") 166 | if err != nil { 167 | return err 168 | } 169 | // Element (standard) 170 | _, err = templBuffer.WriteString("") 192 | if err != nil { 193 | return err 194 | } 195 | // Element (standard) 196 | _, err = templBuffer.WriteString("") 206 | if err != nil { 207 | return err 208 | } 209 | // Element (standard) 210 | _, err = templBuffer.WriteString("") 224 | if err != nil { 225 | return err 226 | } 227 | // Text 228 | var_6 := `Activate` 229 | _, err = templBuffer.WriteString(var_6) 230 | if err != nil { 231 | return err 232 | } 233 | _, err = templBuffer.WriteString("") 234 | if err != nil { 235 | return err 236 | } 237 | _, err = templBuffer.WriteString("") 238 | if err != nil { 239 | return err 240 | } 241 | // Element (standard) 242 | _, err = templBuffer.WriteString("") 252 | if err != nil { 253 | return err 254 | } 255 | // Element (standard) 256 | _, err = templBuffer.WriteString("") 270 | if err != nil { 271 | return err 272 | } 273 | // Text 274 | var_7 := `Deactivate` 275 | _, err = templBuffer.WriteString(var_7) 276 | if err != nil { 277 | return err 278 | } 279 | _, err = templBuffer.WriteString("") 280 | if err != nil { 281 | return err 282 | } 283 | _, err = templBuffer.WriteString("") 284 | if err != nil { 285 | return err 286 | } 287 | _, err = templBuffer.WriteString("") 288 | if err != nil { 289 | return err 290 | } 291 | // RawElement 292 | _, err = templBuffer.WriteString("") 313 | if err != nil { 314 | return err 315 | } 316 | if !templIsBuffer { 317 | _, err = io.Copy(w, templBuffer) 318 | } 319 | return err 320 | }) 321 | } 322 | 323 | func tbody(users []user, modified map[int]bool) templ.Component { 324 | return templ.ComponentFunc(func(ctx context.Context, w io.Writer) (err error) { 325 | templBuffer, templIsBuffer := w.(*bytes.Buffer) 326 | if !templIsBuffer { 327 | templBuffer = templ.GetBuffer() 328 | defer templ.ReleaseBuffer(templBuffer) 329 | } 330 | ctx = templ.InitializeContext(ctx) 331 | var_9 := templ.GetChildren(ctx) 332 | if var_9 == nil { 333 | var_9 = templ.NopComponent 334 | } 335 | ctx = templ.ClearChildren(ctx) 336 | // Element (standard) 337 | _, err = templBuffer.WriteString("") 347 | if err != nil { 348 | return err 349 | } 350 | // For 351 | for k, u := range users { 352 | // Element (standard) 353 | _, err = templBuffer.WriteString("") 373 | if err != nil { 374 | return err 375 | } 376 | // Element (standard) 377 | _, err = templBuffer.WriteString("") 378 | if err != nil { 379 | return err 380 | } 381 | // Element (void) 382 | _, err = templBuffer.WriteString("") 412 | if err != nil { 413 | return err 414 | } 415 | _, err = templBuffer.WriteString("") 416 | if err != nil { 417 | return err 418 | } 419 | // Element (standard) 420 | _, err = templBuffer.WriteString("") 421 | if err != nil { 422 | return err 423 | } 424 | // StringExpression 425 | var var_10 string = u.name 426 | _, err = templBuffer.WriteString(templ.EscapeString(var_10)) 427 | if err != nil { 428 | return err 429 | } 430 | _, err = templBuffer.WriteString("") 431 | if err != nil { 432 | return err 433 | } 434 | // Element (standard) 435 | _, err = templBuffer.WriteString("") 436 | if err != nil { 437 | return err 438 | } 439 | // StringExpression 440 | var var_11 string = u.email 441 | _, err = templBuffer.WriteString(templ.EscapeString(var_11)) 442 | if err != nil { 443 | return err 444 | } 445 | _, err = templBuffer.WriteString("") 446 | if err != nil { 447 | return err 448 | } 449 | // Element (standard) 450 | _, err = templBuffer.WriteString("") 451 | if err != nil { 452 | return err 453 | } 454 | // If 455 | if u.active { 456 | // Text 457 | var_12 := `Active` 458 | _, err = templBuffer.WriteString(var_12) 459 | if err != nil { 460 | return err 461 | } 462 | } else { 463 | // Text 464 | var_13 := `Inactive` 465 | _, err = templBuffer.WriteString(var_13) 466 | if err != nil { 467 | return err 468 | } 469 | } 470 | _, err = templBuffer.WriteString("") 471 | if err != nil { 472 | return err 473 | } 474 | _, err = templBuffer.WriteString("") 475 | if err != nil { 476 | return err 477 | } 478 | } 479 | _, err = templBuffer.WriteString("") 480 | if err != nil { 481 | return err 482 | } 483 | if !templIsBuffer { 484 | _, err = io.Copy(w, templBuffer) 485 | } 486 | return err 487 | }) 488 | } 489 | 490 | func Index(users []user) templ.Component { 491 | return templ.ComponentFunc(func(ctx context.Context, w io.Writer) (err error) { 492 | templBuffer, templIsBuffer := w.(*bytes.Buffer) 493 | if !templIsBuffer { 494 | templBuffer = templ.GetBuffer() 495 | defer templ.ReleaseBuffer(templBuffer) 496 | } 497 | ctx = templ.InitializeContext(ctx) 498 | var_14 := templ.GetChildren(ctx) 499 | if var_14 == nil { 500 | var_14 = templ.NopComponent 501 | } 502 | ctx = templ.ClearChildren(ctx) 503 | // TemplElement 504 | var_15 := templ.ComponentFunc(func(ctx context.Context, w io.Writer) (err error) { 505 | templBuffer, templIsBuffer := w.(*bytes.Buffer) 506 | if !templIsBuffer { 507 | templBuffer = templ.GetBuffer() 508 | defer templ.ReleaseBuffer(templBuffer) 509 | } 510 | // Element (standard) 511 | _, err = templBuffer.WriteString("") 521 | if err != nil { 522 | return err 523 | } 524 | // Text 525 | var_16 := `Bulk Update` 526 | _, err = templBuffer.WriteString(var_16) 527 | if err != nil { 528 | return err 529 | } 530 | _, err = templBuffer.WriteString("") 531 | if err != nil { 532 | return err 533 | } 534 | // Whitespace (normalised) 535 | _, err = templBuffer.WriteString(` `) 536 | if err != nil { 537 | return err 538 | } 539 | // TemplElement 540 | err = demo(users).Render(ctx, templBuffer) 541 | if err != nil { 542 | return err 543 | } 544 | if !templIsBuffer { 545 | _, err = io.Copy(w, templBuffer) 546 | } 547 | return err 548 | }) 549 | err = shared.Layout("Bulk Update").Render(templ.WithChildren(ctx, var_15), templBuffer) 550 | if err != nil { 551 | return err 552 | } 553 | if !templIsBuffer { 554 | _, err = io.Copy(w, templBuffer) 555 | } 556 | return err 557 | }) 558 | } 559 | 560 | -------------------------------------------------------------------------------- /clicktoedit/handlers.go: -------------------------------------------------------------------------------- 1 | package clicktoedit 2 | 3 | import ( 4 | "log" 5 | "net/http" 6 | ) 7 | 8 | type user struct { 9 | firstName, lastName, email string 10 | } 11 | 12 | var demoUser user = user{ 13 | firstName: "Joe", 14 | lastName: "Blow", 15 | email: "joe@blow.com", 16 | } 17 | 18 | func Handlers(prefix string, mux *http.ServeMux) { 19 | mux.HandleFunc(prefix+"/", index) 20 | mux.HandleFunc(prefix, index) 21 | mux.HandleFunc(prefix+"/contact/1", putUser) 22 | mux.HandleFunc(prefix+"/contact/1/edit", editForm) 23 | } 24 | 25 | func index(w http.ResponseWriter, r *http.Request) { 26 | // Load user 27 | user := demoUser 28 | if r.Header.Get("HX-Request") == "true" { 29 | Display(user).Render(r.Context(), w) 30 | return 31 | } 32 | Index(user).Render(r.Context(), w) 33 | } 34 | 35 | func editForm(w http.ResponseWriter, r *http.Request) { 36 | // Load user 37 | user := demoUser 38 | Form(user).Render(r.Context(), w) 39 | } 40 | 41 | func putUser(w http.ResponseWriter, r *http.Request) { 42 | // Load user 43 | if err := r.ParseForm(); err != nil { 44 | log.Println(err) 45 | w.WriteHeader(500) 46 | return 47 | } 48 | demoUser = user{ 49 | firstName: r.FormValue("firstName"), 50 | lastName: r.FormValue("lastName"), 51 | email: r.FormValue("email"), 52 | } 53 | Display(demoUser).Render(r.Context(), w) 54 | } 55 | -------------------------------------------------------------------------------- /clicktoedit/templates.templ: -------------------------------------------------------------------------------- 1 | package clicktoedit 2 | 3 | import "examples/shared" 4 | 5 | templ Display(u user) { 6 |
7 |
: { u.firstName }
8 |
: { u.lastName }
9 |
: { u.email }
10 | 11 |
12 | } 13 | 14 | templ Form(u user) { 15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 | } 31 | 32 | templ Index(u user) { 33 | @shared.Layout("Click to Edit") { 34 |

Click to Edit

35 | @Display(u) 36 | } 37 | } 38 | 39 | -------------------------------------------------------------------------------- /clicktoedit/templates_templ.go: -------------------------------------------------------------------------------- 1 | // Code generated by templ@(devel) DO NOT EDIT. 2 | 3 | package clicktoedit 4 | 5 | //lint:file-ignore SA4006 This context is only used if a nested component is present. 6 | 7 | import "github.com/a-h/templ" 8 | import "context" 9 | import "io" 10 | import "bytes" 11 | 12 | // GoExpression 13 | import "examples/shared" 14 | 15 | func Display(u user) templ.Component { 16 | return templ.ComponentFunc(func(ctx context.Context, w io.Writer) (err error) { 17 | templBuffer, templIsBuffer := w.(*bytes.Buffer) 18 | if !templIsBuffer { 19 | templBuffer = templ.GetBuffer() 20 | defer templ.ReleaseBuffer(templBuffer) 21 | } 22 | ctx = templ.InitializeContext(ctx) 23 | var_1 := templ.GetChildren(ctx) 24 | if var_1 == nil { 25 | var_1 = templ.NopComponent 26 | } 27 | ctx = templ.ClearChildren(ctx) 28 | // Element (standard) 29 | _, err = templBuffer.WriteString("") 43 | if err != nil { 44 | return err 45 | } 46 | // Element (standard) 47 | _, err = templBuffer.WriteString("
") 48 | if err != nil { 49 | return err 50 | } 51 | // Element (standard) 52 | _, err = templBuffer.WriteString("") 63 | if err != nil { 64 | return err 65 | } 66 | // Text 67 | var_3 := `: ` 68 | _, err = templBuffer.WriteString(var_3) 69 | if err != nil { 70 | return err 71 | } 72 | // StringExpression 73 | var var_4 string = u.firstName 74 | _, err = templBuffer.WriteString(templ.EscapeString(var_4)) 75 | if err != nil { 76 | return err 77 | } 78 | _, err = templBuffer.WriteString("
") 79 | if err != nil { 80 | return err 81 | } 82 | // Element (standard) 83 | _, err = templBuffer.WriteString("
") 84 | if err != nil { 85 | return err 86 | } 87 | // Element (standard) 88 | _, err = templBuffer.WriteString("") 99 | if err != nil { 100 | return err 101 | } 102 | // Text 103 | var_6 := `: ` 104 | _, err = templBuffer.WriteString(var_6) 105 | if err != nil { 106 | return err 107 | } 108 | // StringExpression 109 | var var_7 string = u.lastName 110 | _, err = templBuffer.WriteString(templ.EscapeString(var_7)) 111 | if err != nil { 112 | return err 113 | } 114 | _, err = templBuffer.WriteString("
") 115 | if err != nil { 116 | return err 117 | } 118 | // Element (standard) 119 | _, err = templBuffer.WriteString("
") 120 | if err != nil { 121 | return err 122 | } 123 | // Element (standard) 124 | _, err = templBuffer.WriteString("") 135 | if err != nil { 136 | return err 137 | } 138 | // Text 139 | var_9 := `: ` 140 | _, err = templBuffer.WriteString(var_9) 141 | if err != nil { 142 | return err 143 | } 144 | // StringExpression 145 | var var_10 string = u.email 146 | _, err = templBuffer.WriteString(templ.EscapeString(var_10)) 147 | if err != nil { 148 | return err 149 | } 150 | _, err = templBuffer.WriteString("
") 151 | if err != nil { 152 | return err 153 | } 154 | // Element (standard) 155 | _, err = templBuffer.WriteString("") 169 | if err != nil { 170 | return err 171 | } 172 | // Text 173 | var_11 := `Click To Edit` 174 | _, err = templBuffer.WriteString(var_11) 175 | if err != nil { 176 | return err 177 | } 178 | _, err = templBuffer.WriteString("") 179 | if err != nil { 180 | return err 181 | } 182 | _, err = templBuffer.WriteString("") 183 | if err != nil { 184 | return err 185 | } 186 | if !templIsBuffer { 187 | _, err = io.Copy(w, templBuffer) 188 | } 189 | return err 190 | }) 191 | } 192 | 193 | func Form(u user) templ.Component { 194 | return templ.ComponentFunc(func(ctx context.Context, w io.Writer) (err error) { 195 | templBuffer, templIsBuffer := w.(*bytes.Buffer) 196 | if !templIsBuffer { 197 | templBuffer = templ.GetBuffer() 198 | defer templ.ReleaseBuffer(templBuffer) 199 | } 200 | ctx = templ.InitializeContext(ctx) 201 | var_12 := templ.GetChildren(ctx) 202 | if var_12 == nil { 203 | var_12 = templ.NopComponent 204 | } 205 | ctx = templ.ClearChildren(ctx) 206 | // Element (standard) 207 | _, err = templBuffer.WriteString("") 225 | if err != nil { 226 | return err 227 | } 228 | // Element (standard) 229 | _, err = templBuffer.WriteString("") 239 | if err != nil { 240 | return err 241 | } 242 | // Element (standard) 243 | _, err = templBuffer.WriteString("") 253 | if err != nil { 254 | return err 255 | } 256 | // Element (standard) 257 | _, err = templBuffer.WriteString("") 268 | if err != nil { 269 | return err 270 | } 271 | // Element (void) 272 | _, err = templBuffer.WriteString("") 306 | if err != nil { 307 | return err 308 | } 309 | _, err = templBuffer.WriteString("") 310 | if err != nil { 311 | return err 312 | } 313 | _, err = templBuffer.WriteString("") 314 | if err != nil { 315 | return err 316 | } 317 | // Element (standard) 318 | _, err = templBuffer.WriteString("") 328 | if err != nil { 329 | return err 330 | } 331 | // Element (standard) 332 | _, err = templBuffer.WriteString("") 342 | if err != nil { 343 | return err 344 | } 345 | // Element (standard) 346 | _, err = templBuffer.WriteString("") 357 | if err != nil { 358 | return err 359 | } 360 | // Element (void) 361 | _, err = templBuffer.WriteString("") 395 | if err != nil { 396 | return err 397 | } 398 | _, err = templBuffer.WriteString("") 399 | if err != nil { 400 | return err 401 | } 402 | _, err = templBuffer.WriteString("") 403 | if err != nil { 404 | return err 405 | } 406 | // Element (standard) 407 | _, err = templBuffer.WriteString("") 417 | if err != nil { 418 | return err 419 | } 420 | // Element (standard) 421 | _, err = templBuffer.WriteString("") 431 | if err != nil { 432 | return err 433 | } 434 | // Element (standard) 435 | _, err = templBuffer.WriteString("") 446 | if err != nil { 447 | return err 448 | } 449 | // Element (void) 450 | _, err = templBuffer.WriteString("") 484 | if err != nil { 485 | return err 486 | } 487 | _, err = templBuffer.WriteString("") 488 | if err != nil { 489 | return err 490 | } 491 | _, err = templBuffer.WriteString("") 492 | if err != nil { 493 | return err 494 | } 495 | // Element (standard) 496 | _, err = templBuffer.WriteString("") 506 | if err != nil { 507 | return err 508 | } 509 | // Element (standard) 510 | _, err = templBuffer.WriteString("") 520 | if err != nil { 521 | return err 522 | } 523 | // Element (standard) 524 | _, err = templBuffer.WriteString("") 534 | if err != nil { 535 | return err 536 | } 537 | // Text 538 | var_16 := `Submit` 539 | _, err = templBuffer.WriteString(var_16) 540 | if err != nil { 541 | return err 542 | } 543 | _, err = templBuffer.WriteString("") 544 | if err != nil { 545 | return err 546 | } 547 | _, err = templBuffer.WriteString("") 548 | if err != nil { 549 | return err 550 | } 551 | // Element (standard) 552 | _, err = templBuffer.WriteString("") 562 | if err != nil { 563 | return err 564 | } 565 | // Element (standard) 566 | _, err = templBuffer.WriteString("") 580 | if err != nil { 581 | return err 582 | } 583 | // Text 584 | var_17 := `Cancel` 585 | _, err = templBuffer.WriteString(var_17) 586 | if err != nil { 587 | return err 588 | } 589 | _, err = templBuffer.WriteString("") 590 | if err != nil { 591 | return err 592 | } 593 | _, err = templBuffer.WriteString("") 594 | if err != nil { 595 | return err 596 | } 597 | _, err = templBuffer.WriteString("") 598 | if err != nil { 599 | return err 600 | } 601 | _, err = templBuffer.WriteString("") 602 | if err != nil { 603 | return err 604 | } 605 | if !templIsBuffer { 606 | _, err = io.Copy(w, templBuffer) 607 | } 608 | return err 609 | }) 610 | } 611 | 612 | func Index(u user) templ.Component { 613 | return templ.ComponentFunc(func(ctx context.Context, w io.Writer) (err error) { 614 | templBuffer, templIsBuffer := w.(*bytes.Buffer) 615 | if !templIsBuffer { 616 | templBuffer = templ.GetBuffer() 617 | defer templ.ReleaseBuffer(templBuffer) 618 | } 619 | ctx = templ.InitializeContext(ctx) 620 | var_18 := templ.GetChildren(ctx) 621 | if var_18 == nil { 622 | var_18 = templ.NopComponent 623 | } 624 | ctx = templ.ClearChildren(ctx) 625 | // TemplElement 626 | var_19 := templ.ComponentFunc(func(ctx context.Context, w io.Writer) (err error) { 627 | templBuffer, templIsBuffer := w.(*bytes.Buffer) 628 | if !templIsBuffer { 629 | templBuffer = templ.GetBuffer() 630 | defer templ.ReleaseBuffer(templBuffer) 631 | } 632 | // Element (standard) 633 | _, err = templBuffer.WriteString("") 643 | if err != nil { 644 | return err 645 | } 646 | // Text 647 | var_20 := `Click to Edit` 648 | _, err = templBuffer.WriteString(var_20) 649 | if err != nil { 650 | return err 651 | } 652 | _, err = templBuffer.WriteString("") 653 | if err != nil { 654 | return err 655 | } 656 | // Whitespace (normalised) 657 | _, err = templBuffer.WriteString(` `) 658 | if err != nil { 659 | return err 660 | } 661 | // TemplElement 662 | err = Display(u).Render(ctx, templBuffer) 663 | if err != nil { 664 | return err 665 | } 666 | if !templIsBuffer { 667 | _, err = io.Copy(w, templBuffer) 668 | } 669 | return err 670 | }) 671 | err = shared.Layout("Click to Edit").Render(templ.WithChildren(ctx, var_19), templBuffer) 672 | if err != nil { 673 | return err 674 | } 675 | if !templIsBuffer { 676 | _, err = io.Copy(w, templBuffer) 677 | } 678 | return err 679 | }) 680 | } 681 | 682 | -------------------------------------------------------------------------------- /clicktoload/handlers.go: -------------------------------------------------------------------------------- 1 | package clicktoload 2 | 3 | import ( 4 | "fmt" 5 | "net/http" 6 | "strconv" 7 | "time" 8 | 9 | "github.com/rs/xid" 10 | ) 11 | 12 | type user struct { 13 | name, email, id string 14 | } 15 | 16 | func Handlers(prefix string, mux *http.ServeMux) { 17 | mux.HandleFunc(prefix+"/", index) 18 | mux.HandleFunc(prefix+"/contacts/", getPage) 19 | } 20 | 21 | func index(w http.ResponseWriter, r *http.Request) { 22 | // Load users 23 | Index(getUsers(1)).Render(r.Context(), w) 24 | } 25 | 26 | func getPage(w http.ResponseWriter, r *http.Request) { 27 | page, _ := strconv.Atoi(r.URL.Query().Get("page")) 28 | tbody(getUsers(page), page).Render(r.Context(), w) 29 | } 30 | 31 | func getUsers(page int) []user { 32 | var users []user 33 | for i := 0; i < 10; i++ { 34 | users = append(users, user{ 35 | "Agent Smith", 36 | fmt.Sprintf("void%d@null.org", (page*10)+i), 37 | xid.NewWithTime(time.Now()).String(), 38 | }) 39 | } 40 | return users 41 | } 42 | -------------------------------------------------------------------------------- /clicktoload/templates.templ: -------------------------------------------------------------------------------- 1 | package clicktoload 2 | 3 | import ( 4 | "fmt" 5 | 6 | "examples/shared" 7 | ) 8 | 9 | templ demo(users []user, page int) { 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | @tbody(users, page) 18 |
NameEmailID
19 | } 20 | 21 | templ tbody(users []user, page int) { 22 | for _, u := range users { 23 | 24 | { u.name } 25 | { u.email } 26 | { u.id } 27 | 28 | } 29 | @replaceMe(page) 30 | } 31 | 32 | templ replaceMe(page int) { 33 | 34 | 35 | 36 | } 37 | 38 | templ Index(users []user) { 39 | @shared.Layout("Click to Load") { 40 |

Click to Load

41 | @demo(users, 1) 42 | } 43 | } 44 | 45 | -------------------------------------------------------------------------------- /clicktoload/templates_templ.go: -------------------------------------------------------------------------------- 1 | // Code generated by templ@(devel) DO NOT EDIT. 2 | 3 | package clicktoload 4 | 5 | //lint:file-ignore SA4006 This context is only used if a nested component is present. 6 | 7 | import "github.com/a-h/templ" 8 | import "context" 9 | import "io" 10 | import "bytes" 11 | 12 | // GoExpression 13 | import ( 14 | "fmt" 15 | 16 | "examples/shared" 17 | ) 18 | 19 | func demo(users []user, page int) templ.Component { 20 | return templ.ComponentFunc(func(ctx context.Context, w io.Writer) (err error) { 21 | templBuffer, templIsBuffer := w.(*bytes.Buffer) 22 | if !templIsBuffer { 23 | templBuffer = templ.GetBuffer() 24 | defer templ.ReleaseBuffer(templBuffer) 25 | } 26 | ctx = templ.InitializeContext(ctx) 27 | var_1 := templ.GetChildren(ctx) 28 | if var_1 == nil { 29 | var_1 = templ.NopComponent 30 | } 31 | ctx = templ.ClearChildren(ctx) 32 | // Element (standard) 33 | _, err = templBuffer.WriteString("") 43 | if err != nil { 44 | return err 45 | } 46 | // Element (standard) 47 | _, err = templBuffer.WriteString("") 48 | if err != nil { 49 | return err 50 | } 51 | // Element (standard) 52 | _, err = templBuffer.WriteString("") 53 | if err != nil { 54 | return err 55 | } 56 | // Element (standard) 57 | _, err = templBuffer.WriteString("") 58 | if err != nil { 59 | return err 60 | } 61 | // Text 62 | var_2 := `Name` 63 | _, err = templBuffer.WriteString(var_2) 64 | if err != nil { 65 | return err 66 | } 67 | _, err = templBuffer.WriteString("") 68 | if err != nil { 69 | return err 70 | } 71 | // Element (standard) 72 | _, err = templBuffer.WriteString("") 73 | if err != nil { 74 | return err 75 | } 76 | // Text 77 | var_3 := `Email` 78 | _, err = templBuffer.WriteString(var_3) 79 | if err != nil { 80 | return err 81 | } 82 | _, err = templBuffer.WriteString("") 83 | if err != nil { 84 | return err 85 | } 86 | // Element (standard) 87 | _, err = templBuffer.WriteString("") 88 | if err != nil { 89 | return err 90 | } 91 | // Text 92 | var_4 := `ID` 93 | _, err = templBuffer.WriteString(var_4) 94 | if err != nil { 95 | return err 96 | } 97 | _, err = templBuffer.WriteString("") 98 | if err != nil { 99 | return err 100 | } 101 | _, err = templBuffer.WriteString("") 102 | if err != nil { 103 | return err 104 | } 105 | _, err = templBuffer.WriteString("") 106 | if err != nil { 107 | return err 108 | } 109 | // Element (standard) 110 | _, err = templBuffer.WriteString("") 111 | if err != nil { 112 | return err 113 | } 114 | // TemplElement 115 | err = tbody(users, page).Render(ctx, templBuffer) 116 | if err != nil { 117 | return err 118 | } 119 | _, err = templBuffer.WriteString("") 120 | if err != nil { 121 | return err 122 | } 123 | _, err = templBuffer.WriteString("") 124 | if err != nil { 125 | return err 126 | } 127 | if !templIsBuffer { 128 | _, err = io.Copy(w, templBuffer) 129 | } 130 | return err 131 | }) 132 | } 133 | 134 | func tbody(users []user, page int) templ.Component { 135 | return templ.ComponentFunc(func(ctx context.Context, w io.Writer) (err error) { 136 | templBuffer, templIsBuffer := w.(*bytes.Buffer) 137 | if !templIsBuffer { 138 | templBuffer = templ.GetBuffer() 139 | defer templ.ReleaseBuffer(templBuffer) 140 | } 141 | ctx = templ.InitializeContext(ctx) 142 | var_5 := templ.GetChildren(ctx) 143 | if var_5 == nil { 144 | var_5 = templ.NopComponent 145 | } 146 | ctx = templ.ClearChildren(ctx) 147 | // For 148 | for _, u := range users { 149 | // Element (standard) 150 | _, err = templBuffer.WriteString("") 151 | if err != nil { 152 | return err 153 | } 154 | // Element (standard) 155 | _, err = templBuffer.WriteString("") 156 | if err != nil { 157 | return err 158 | } 159 | // StringExpression 160 | var var_6 string = u.name 161 | _, err = templBuffer.WriteString(templ.EscapeString(var_6)) 162 | if err != nil { 163 | return err 164 | } 165 | _, err = templBuffer.WriteString("") 166 | if err != nil { 167 | return err 168 | } 169 | // Element (standard) 170 | _, err = templBuffer.WriteString("") 171 | if err != nil { 172 | return err 173 | } 174 | // StringExpression 175 | var var_7 string = u.email 176 | _, err = templBuffer.WriteString(templ.EscapeString(var_7)) 177 | if err != nil { 178 | return err 179 | } 180 | _, err = templBuffer.WriteString("") 181 | if err != nil { 182 | return err 183 | } 184 | // Element (standard) 185 | _, err = templBuffer.WriteString("") 186 | if err != nil { 187 | return err 188 | } 189 | // StringExpression 190 | var var_8 string = u.id 191 | _, err = templBuffer.WriteString(templ.EscapeString(var_8)) 192 | if err != nil { 193 | return err 194 | } 195 | _, err = templBuffer.WriteString("") 196 | if err != nil { 197 | return err 198 | } 199 | _, err = templBuffer.WriteString("") 200 | if err != nil { 201 | return err 202 | } 203 | } 204 | // TemplElement 205 | err = replaceMe(page).Render(ctx, templBuffer) 206 | if err != nil { 207 | return err 208 | } 209 | if !templIsBuffer { 210 | _, err = io.Copy(w, templBuffer) 211 | } 212 | return err 213 | }) 214 | } 215 | 216 | func replaceMe(page int) templ.Component { 217 | return templ.ComponentFunc(func(ctx context.Context, w io.Writer) (err error) { 218 | templBuffer, templIsBuffer := w.(*bytes.Buffer) 219 | if !templIsBuffer { 220 | templBuffer = templ.GetBuffer() 221 | defer templ.ReleaseBuffer(templBuffer) 222 | } 223 | ctx = templ.InitializeContext(ctx) 224 | var_9 := templ.GetChildren(ctx) 225 | if var_9 == nil { 226 | var_9 = templ.NopComponent 227 | } 228 | ctx = templ.ClearChildren(ctx) 229 | // Element (standard) 230 | _, err = templBuffer.WriteString("") 240 | if err != nil { 241 | return err 242 | } 243 | // Element (standard) 244 | _, err = templBuffer.WriteString("") 254 | if err != nil { 255 | return err 256 | } 257 | // Element (standard) 258 | _, err = templBuffer.WriteString("") 292 | if err != nil { 293 | return err 294 | } 295 | // Text 296 | var_10 := `Load More Agents...` 297 | _, err = templBuffer.WriteString(var_10) 298 | if err != nil { 299 | return err 300 | } 301 | _, err = templBuffer.WriteString("") 302 | if err != nil { 303 | return err 304 | } 305 | _, err = templBuffer.WriteString("") 306 | if err != nil { 307 | return err 308 | } 309 | _, err = templBuffer.WriteString("") 310 | if err != nil { 311 | return err 312 | } 313 | if !templIsBuffer { 314 | _, err = io.Copy(w, templBuffer) 315 | } 316 | return err 317 | }) 318 | } 319 | 320 | func Index(users []user) templ.Component { 321 | return templ.ComponentFunc(func(ctx context.Context, w io.Writer) (err error) { 322 | templBuffer, templIsBuffer := w.(*bytes.Buffer) 323 | if !templIsBuffer { 324 | templBuffer = templ.GetBuffer() 325 | defer templ.ReleaseBuffer(templBuffer) 326 | } 327 | ctx = templ.InitializeContext(ctx) 328 | var_11 := templ.GetChildren(ctx) 329 | if var_11 == nil { 330 | var_11 = templ.NopComponent 331 | } 332 | ctx = templ.ClearChildren(ctx) 333 | // TemplElement 334 | var_12 := templ.ComponentFunc(func(ctx context.Context, w io.Writer) (err error) { 335 | templBuffer, templIsBuffer := w.(*bytes.Buffer) 336 | if !templIsBuffer { 337 | templBuffer = templ.GetBuffer() 338 | defer templ.ReleaseBuffer(templBuffer) 339 | } 340 | // Element (standard) 341 | _, err = templBuffer.WriteString("") 351 | if err != nil { 352 | return err 353 | } 354 | // Text 355 | var_13 := `Click to Load` 356 | _, err = templBuffer.WriteString(var_13) 357 | if err != nil { 358 | return err 359 | } 360 | _, err = templBuffer.WriteString("") 361 | if err != nil { 362 | return err 363 | } 364 | // Whitespace (normalised) 365 | _, err = templBuffer.WriteString(` `) 366 | if err != nil { 367 | return err 368 | } 369 | // TemplElement 370 | err = demo(users, 1).Render(ctx, templBuffer) 371 | if err != nil { 372 | return err 373 | } 374 | if !templIsBuffer { 375 | _, err = io.Copy(w, templBuffer) 376 | } 377 | return err 378 | }) 379 | err = shared.Layout("Click to Load").Render(templ.WithChildren(ctx, var_12), templBuffer) 380 | if err != nil { 381 | return err 382 | } 383 | if !templIsBuffer { 384 | _, err = io.Copy(w, templBuffer) 385 | } 386 | return err 387 | }) 388 | } 389 | 390 | -------------------------------------------------------------------------------- /csrf/handlers.go: -------------------------------------------------------------------------------- 1 | package csrf 2 | 3 | import ( 4 | "log" 5 | "net/http" 6 | 7 | "github.com/justinas/nosurf" 8 | ) 9 | 10 | type user struct { 11 | firstName, lastName, email string 12 | } 13 | 14 | var demoUser user = user{ 15 | firstName: "Joe", 16 | lastName: "Blow", 17 | email: "joe@blow.com", 18 | } 19 | 20 | func Handlers(prefix string, mux *http.ServeMux) { 21 | mux.HandleFunc(prefix+"/", index) 22 | mux.HandleFunc(prefix, index) 23 | mux.Handle(prefix+"/contact/1", nosurf.New(http.HandlerFunc(putUser))) 24 | mux.Handle(prefix+"/contact/1/edit", nosurf.New(http.HandlerFunc(editForm))) 25 | } 26 | 27 | func index(w http.ResponseWriter, r *http.Request) { 28 | // Load user 29 | user := demoUser 30 | if r.Header.Get("HX-Request") == "true" { 31 | Display(user).Render(r.Context(), w) 32 | return 33 | } 34 | Index(user).Render(r.Context(), w) 35 | } 36 | 37 | func editForm(w http.ResponseWriter, r *http.Request) { 38 | // Load user 39 | user := demoUser 40 | Form(user, nosurf.Token(r)).Render(r.Context(), w) 41 | } 42 | 43 | func putUser(w http.ResponseWriter, r *http.Request) { 44 | // Load user 45 | if err := r.ParseForm(); err != nil { 46 | log.Println(err) 47 | w.WriteHeader(500) 48 | return 49 | } 50 | demoUser = user{ 51 | firstName: r.FormValue("firstName"), 52 | lastName: r.FormValue("lastName"), 53 | email: r.FormValue("email"), 54 | } 55 | Display(demoUser).Render(r.Context(), w) 56 | } 57 | -------------------------------------------------------------------------------- /csrf/templates.templ: -------------------------------------------------------------------------------- 1 | package csrf 2 | 3 | import ( 4 | "fmt" 5 | 6 | "examples/shared" 7 | ) 8 | 9 | templ Display(u user) { 10 |
11 |
: { u.firstName }
12 |
: { u.lastName }
13 |
: { u.email }
14 | 15 |
16 | } 17 | 18 | templ Form(u user, csrfToken string) { 19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 | } 35 | 36 | templ Index(u user) { 37 | @shared.Layout("Click to Edit") { 38 |

Click to Edit

39 | @Display(u) 40 | } 41 | } 42 | 43 | -------------------------------------------------------------------------------- /csrf/templates_templ.go: -------------------------------------------------------------------------------- 1 | // Code generated by templ@(devel) DO NOT EDIT. 2 | 3 | package csrf 4 | 5 | //lint:file-ignore SA4006 This context is only used if a nested component is present. 6 | 7 | import "github.com/a-h/templ" 8 | import "context" 9 | import "io" 10 | import "bytes" 11 | 12 | // GoExpression 13 | import ( 14 | "fmt" 15 | 16 | "examples/shared" 17 | ) 18 | 19 | func Display(u user) templ.Component { 20 | return templ.ComponentFunc(func(ctx context.Context, w io.Writer) (err error) { 21 | templBuffer, templIsBuffer := w.(*bytes.Buffer) 22 | if !templIsBuffer { 23 | templBuffer = templ.GetBuffer() 24 | defer templ.ReleaseBuffer(templBuffer) 25 | } 26 | ctx = templ.InitializeContext(ctx) 27 | var_1 := templ.GetChildren(ctx) 28 | if var_1 == nil { 29 | var_1 = templ.NopComponent 30 | } 31 | ctx = templ.ClearChildren(ctx) 32 | // Element (standard) 33 | _, err = templBuffer.WriteString("") 47 | if err != nil { 48 | return err 49 | } 50 | // Element (standard) 51 | _, err = templBuffer.WriteString("
") 52 | if err != nil { 53 | return err 54 | } 55 | // Element (standard) 56 | _, err = templBuffer.WriteString("") 67 | if err != nil { 68 | return err 69 | } 70 | // Text 71 | var_3 := `: ` 72 | _, err = templBuffer.WriteString(var_3) 73 | if err != nil { 74 | return err 75 | } 76 | // StringExpression 77 | var var_4 string = u.firstName 78 | _, err = templBuffer.WriteString(templ.EscapeString(var_4)) 79 | if err != nil { 80 | return err 81 | } 82 | _, err = templBuffer.WriteString("
") 83 | if err != nil { 84 | return err 85 | } 86 | // Element (standard) 87 | _, err = templBuffer.WriteString("
") 88 | if err != nil { 89 | return err 90 | } 91 | // Element (standard) 92 | _, err = templBuffer.WriteString("") 103 | if err != nil { 104 | return err 105 | } 106 | // Text 107 | var_6 := `: ` 108 | _, err = templBuffer.WriteString(var_6) 109 | if err != nil { 110 | return err 111 | } 112 | // StringExpression 113 | var var_7 string = u.lastName 114 | _, err = templBuffer.WriteString(templ.EscapeString(var_7)) 115 | if err != nil { 116 | return err 117 | } 118 | _, err = templBuffer.WriteString("
") 119 | if err != nil { 120 | return err 121 | } 122 | // Element (standard) 123 | _, err = templBuffer.WriteString("
") 124 | if err != nil { 125 | return err 126 | } 127 | // Element (standard) 128 | _, err = templBuffer.WriteString("") 139 | if err != nil { 140 | return err 141 | } 142 | // Text 143 | var_9 := `: ` 144 | _, err = templBuffer.WriteString(var_9) 145 | if err != nil { 146 | return err 147 | } 148 | // StringExpression 149 | var var_10 string = u.email 150 | _, err = templBuffer.WriteString(templ.EscapeString(var_10)) 151 | if err != nil { 152 | return err 153 | } 154 | _, err = templBuffer.WriteString("
") 155 | if err != nil { 156 | return err 157 | } 158 | // Element (standard) 159 | _, err = templBuffer.WriteString("") 173 | if err != nil { 174 | return err 175 | } 176 | // Text 177 | var_11 := `Click To Edit` 178 | _, err = templBuffer.WriteString(var_11) 179 | if err != nil { 180 | return err 181 | } 182 | _, err = templBuffer.WriteString("") 183 | if err != nil { 184 | return err 185 | } 186 | _, err = templBuffer.WriteString("") 187 | if err != nil { 188 | return err 189 | } 190 | if !templIsBuffer { 191 | _, err = io.Copy(w, templBuffer) 192 | } 193 | return err 194 | }) 195 | } 196 | 197 | func Form(u user, csrfToken string) templ.Component { 198 | return templ.ComponentFunc(func(ctx context.Context, w io.Writer) (err error) { 199 | templBuffer, templIsBuffer := w.(*bytes.Buffer) 200 | if !templIsBuffer { 201 | templBuffer = templ.GetBuffer() 202 | defer templ.ReleaseBuffer(templBuffer) 203 | } 204 | ctx = templ.InitializeContext(ctx) 205 | var_12 := templ.GetChildren(ctx) 206 | if var_12 == nil { 207 | var_12 = templ.NopComponent 208 | } 209 | ctx = templ.ClearChildren(ctx) 210 | // Element (standard) 211 | _, err = templBuffer.WriteString("") 245 | if err != nil { 246 | return err 247 | } 248 | // Element (standard) 249 | _, err = templBuffer.WriteString("") 259 | if err != nil { 260 | return err 261 | } 262 | // Element (standard) 263 | _, err = templBuffer.WriteString("") 273 | if err != nil { 274 | return err 275 | } 276 | // Element (standard) 277 | _, err = templBuffer.WriteString("") 288 | if err != nil { 289 | return err 290 | } 291 | // Element (void) 292 | _, err = templBuffer.WriteString("") 326 | if err != nil { 327 | return err 328 | } 329 | _, err = templBuffer.WriteString("") 330 | if err != nil { 331 | return err 332 | } 333 | _, err = templBuffer.WriteString("") 334 | if err != nil { 335 | return err 336 | } 337 | // Element (standard) 338 | _, err = templBuffer.WriteString("") 348 | if err != nil { 349 | return err 350 | } 351 | // Element (standard) 352 | _, err = templBuffer.WriteString("") 362 | if err != nil { 363 | return err 364 | } 365 | // Element (standard) 366 | _, err = templBuffer.WriteString("") 377 | if err != nil { 378 | return err 379 | } 380 | // Element (void) 381 | _, err = templBuffer.WriteString("") 415 | if err != nil { 416 | return err 417 | } 418 | _, err = templBuffer.WriteString("") 419 | if err != nil { 420 | return err 421 | } 422 | _, err = templBuffer.WriteString("") 423 | if err != nil { 424 | return err 425 | } 426 | // Element (standard) 427 | _, err = templBuffer.WriteString("") 437 | if err != nil { 438 | return err 439 | } 440 | // Element (standard) 441 | _, err = templBuffer.WriteString("") 451 | if err != nil { 452 | return err 453 | } 454 | // Element (standard) 455 | _, err = templBuffer.WriteString("") 466 | if err != nil { 467 | return err 468 | } 469 | // Element (void) 470 | _, err = templBuffer.WriteString("") 504 | if err != nil { 505 | return err 506 | } 507 | _, err = templBuffer.WriteString("") 508 | if err != nil { 509 | return err 510 | } 511 | _, err = templBuffer.WriteString("") 512 | if err != nil { 513 | return err 514 | } 515 | // Element (standard) 516 | _, err = templBuffer.WriteString("") 526 | if err != nil { 527 | return err 528 | } 529 | // Element (standard) 530 | _, err = templBuffer.WriteString("") 540 | if err != nil { 541 | return err 542 | } 543 | // Element (standard) 544 | _, err = templBuffer.WriteString("") 554 | if err != nil { 555 | return err 556 | } 557 | // Text 558 | var_16 := `Submit` 559 | _, err = templBuffer.WriteString(var_16) 560 | if err != nil { 561 | return err 562 | } 563 | _, err = templBuffer.WriteString("") 564 | if err != nil { 565 | return err 566 | } 567 | _, err = templBuffer.WriteString("") 568 | if err != nil { 569 | return err 570 | } 571 | // Element (standard) 572 | _, err = templBuffer.WriteString("") 582 | if err != nil { 583 | return err 584 | } 585 | // Element (standard) 586 | _, err = templBuffer.WriteString("") 600 | if err != nil { 601 | return err 602 | } 603 | // Text 604 | var_17 := `Cancel` 605 | _, err = templBuffer.WriteString(var_17) 606 | if err != nil { 607 | return err 608 | } 609 | _, err = templBuffer.WriteString("") 610 | if err != nil { 611 | return err 612 | } 613 | _, err = templBuffer.WriteString("") 614 | if err != nil { 615 | return err 616 | } 617 | _, err = templBuffer.WriteString("") 618 | if err != nil { 619 | return err 620 | } 621 | _, err = templBuffer.WriteString("") 622 | if err != nil { 623 | return err 624 | } 625 | if !templIsBuffer { 626 | _, err = io.Copy(w, templBuffer) 627 | } 628 | return err 629 | }) 630 | } 631 | 632 | func Index(u user) templ.Component { 633 | return templ.ComponentFunc(func(ctx context.Context, w io.Writer) (err error) { 634 | templBuffer, templIsBuffer := w.(*bytes.Buffer) 635 | if !templIsBuffer { 636 | templBuffer = templ.GetBuffer() 637 | defer templ.ReleaseBuffer(templBuffer) 638 | } 639 | ctx = templ.InitializeContext(ctx) 640 | var_18 := templ.GetChildren(ctx) 641 | if var_18 == nil { 642 | var_18 = templ.NopComponent 643 | } 644 | ctx = templ.ClearChildren(ctx) 645 | // TemplElement 646 | var_19 := templ.ComponentFunc(func(ctx context.Context, w io.Writer) (err error) { 647 | templBuffer, templIsBuffer := w.(*bytes.Buffer) 648 | if !templIsBuffer { 649 | templBuffer = templ.GetBuffer() 650 | defer templ.ReleaseBuffer(templBuffer) 651 | } 652 | // Element (standard) 653 | _, err = templBuffer.WriteString("") 663 | if err != nil { 664 | return err 665 | } 666 | // Text 667 | var_20 := `Click to Edit` 668 | _, err = templBuffer.WriteString(var_20) 669 | if err != nil { 670 | return err 671 | } 672 | _, err = templBuffer.WriteString("") 673 | if err != nil { 674 | return err 675 | } 676 | // Whitespace (normalised) 677 | _, err = templBuffer.WriteString(` `) 678 | if err != nil { 679 | return err 680 | } 681 | // TemplElement 682 | err = Display(u).Render(ctx, templBuffer) 683 | if err != nil { 684 | return err 685 | } 686 | if !templIsBuffer { 687 | _, err = io.Copy(w, templBuffer) 688 | } 689 | return err 690 | }) 691 | err = shared.Layout("Click to Edit").Render(templ.WithChildren(ctx, var_19), templBuffer) 692 | if err != nil { 693 | return err 694 | } 695 | if !templIsBuffer { 696 | _, err = io.Copy(w, templBuffer) 697 | } 698 | return err 699 | }) 700 | } 701 | 702 | -------------------------------------------------------------------------------- /deleterow/handlers.go: -------------------------------------------------------------------------------- 1 | package deleterow 2 | 3 | import ( 4 | "fmt" 5 | "net/http" 6 | "strings" 7 | ) 8 | 9 | type user struct { 10 | name, email, id string 11 | } 12 | 13 | func Handlers(prefix string, mux *http.ServeMux) { 14 | mux.HandleFunc(prefix+"/", index) 15 | mux.HandleFunc(prefix+"/contact/", deleteUser) 16 | } 17 | 18 | func index(w http.ResponseWriter, r *http.Request) { 19 | // Load users 20 | Index().Render(r.Context(), w) 21 | } 22 | 23 | func deleteUser(w http.ResponseWriter, r *http.Request) { 24 | segments := strings.Split(r.URL.Path, "/") 25 | userID := segments[len(segments)-1] 26 | fmt.Println("Delete user: ", userID) 27 | } 28 | -------------------------------------------------------------------------------- /deleterow/templates.templ: -------------------------------------------------------------------------------- 1 | package deleterow 2 | 3 | import "examples/shared" 4 | 5 | templ demo() { 6 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 |
NameEmailStatus
Joe Smithjoe@smith.orgActive
Angie MacDowellangie@macdowell.orgActive
Fuqua Tarkentonfuqua@tarkenton.orgActive
Kim Yeekim@yee.orgInactive
45 | } 46 | 47 | templ Index() { 48 | @shared.Layout("Delete Row") { 49 |

Delete Row

50 | @demo() 51 | } 52 | } 53 | 54 | -------------------------------------------------------------------------------- /deleterow/templates_templ.go: -------------------------------------------------------------------------------- 1 | // Code generated by templ@(devel) DO NOT EDIT. 2 | 3 | package deleterow 4 | 5 | //lint:file-ignore SA4006 This context is only used if a nested component is present. 6 | 7 | import "github.com/a-h/templ" 8 | import "context" 9 | import "io" 10 | import "bytes" 11 | 12 | // GoExpression 13 | import "examples/shared" 14 | 15 | func demo() templ.Component { 16 | return templ.ComponentFunc(func(ctx context.Context, w io.Writer) (err error) { 17 | templBuffer, templIsBuffer := w.(*bytes.Buffer) 18 | if !templIsBuffer { 19 | templBuffer = templ.GetBuffer() 20 | defer templ.ReleaseBuffer(templBuffer) 21 | } 22 | ctx = templ.InitializeContext(ctx) 23 | var_1 := templ.GetChildren(ctx) 24 | if var_1 == nil { 25 | var_1 = templ.NopComponent 26 | } 27 | ctx = templ.ClearChildren(ctx) 28 | // RawElement 29 | _, err = templBuffer.WriteString("") 45 | if err != nil { 46 | return err 47 | } 48 | // Element (standard) 49 | _, err = templBuffer.WriteString("") 59 | if err != nil { 60 | return err 61 | } 62 | // Element (standard) 63 | _, err = templBuffer.WriteString("") 64 | if err != nil { 65 | return err 66 | } 67 | // Element (standard) 68 | _, err = templBuffer.WriteString("") 69 | if err != nil { 70 | return err 71 | } 72 | // Element (standard) 73 | _, err = templBuffer.WriteString("") 74 | if err != nil { 75 | return err 76 | } 77 | // Text 78 | var_3 := `Name` 79 | _, err = templBuffer.WriteString(var_3) 80 | if err != nil { 81 | return err 82 | } 83 | _, err = templBuffer.WriteString("") 84 | if err != nil { 85 | return err 86 | } 87 | // Element (standard) 88 | _, err = templBuffer.WriteString("") 89 | if err != nil { 90 | return err 91 | } 92 | // Text 93 | var_4 := `Email` 94 | _, err = templBuffer.WriteString(var_4) 95 | if err != nil { 96 | return err 97 | } 98 | _, err = templBuffer.WriteString("") 99 | if err != nil { 100 | return err 101 | } 102 | // Element (standard) 103 | _, err = templBuffer.WriteString("") 104 | if err != nil { 105 | return err 106 | } 107 | // Text 108 | var_5 := `Status` 109 | _, err = templBuffer.WriteString(var_5) 110 | if err != nil { 111 | return err 112 | } 113 | _, err = templBuffer.WriteString("") 114 | if err != nil { 115 | return err 116 | } 117 | // Element (standard) 118 | _, err = templBuffer.WriteString("") 119 | if err != nil { 120 | return err 121 | } 122 | _, err = templBuffer.WriteString("") 123 | if err != nil { 124 | return err 125 | } 126 | _, err = templBuffer.WriteString("") 127 | if err != nil { 128 | return err 129 | } 130 | _, err = templBuffer.WriteString("") 131 | if err != nil { 132 | return err 133 | } 134 | // Element (standard) 135 | _, err = templBuffer.WriteString("") 153 | if err != nil { 154 | return err 155 | } 156 | // Element (standard) 157 | _, err = templBuffer.WriteString("") 158 | if err != nil { 159 | return err 160 | } 161 | // Element (standard) 162 | _, err = templBuffer.WriteString("") 163 | if err != nil { 164 | return err 165 | } 166 | // Text 167 | var_6 := `Joe Smith` 168 | _, err = templBuffer.WriteString(var_6) 169 | if err != nil { 170 | return err 171 | } 172 | _, err = templBuffer.WriteString("") 173 | if err != nil { 174 | return err 175 | } 176 | // Element (standard) 177 | _, err = templBuffer.WriteString("") 178 | if err != nil { 179 | return err 180 | } 181 | // Text 182 | var_7 := `joe@smith.org` 183 | _, err = templBuffer.WriteString(var_7) 184 | if err != nil { 185 | return err 186 | } 187 | _, err = templBuffer.WriteString("") 188 | if err != nil { 189 | return err 190 | } 191 | // Element (standard) 192 | _, err = templBuffer.WriteString("") 193 | if err != nil { 194 | return err 195 | } 196 | // Text 197 | var_8 := `Active` 198 | _, err = templBuffer.WriteString(var_8) 199 | if err != nil { 200 | return err 201 | } 202 | _, err = templBuffer.WriteString("") 203 | if err != nil { 204 | return err 205 | } 206 | // Element (standard) 207 | _, err = templBuffer.WriteString("") 208 | if err != nil { 209 | return err 210 | } 211 | // Element (standard) 212 | _, err = templBuffer.WriteString("") 226 | if err != nil { 227 | return err 228 | } 229 | // Text 230 | var_9 := `Delete` 231 | _, err = templBuffer.WriteString(var_9) 232 | if err != nil { 233 | return err 234 | } 235 | _, err = templBuffer.WriteString("") 236 | if err != nil { 237 | return err 238 | } 239 | _, err = templBuffer.WriteString("") 240 | if err != nil { 241 | return err 242 | } 243 | _, err = templBuffer.WriteString("") 244 | if err != nil { 245 | return err 246 | } 247 | // Element (standard) 248 | _, err = templBuffer.WriteString("") 249 | if err != nil { 250 | return err 251 | } 252 | // Element (standard) 253 | _, err = templBuffer.WriteString("") 254 | if err != nil { 255 | return err 256 | } 257 | // Text 258 | var_10 := `Angie MacDowell` 259 | _, err = templBuffer.WriteString(var_10) 260 | if err != nil { 261 | return err 262 | } 263 | _, err = templBuffer.WriteString("") 264 | if err != nil { 265 | return err 266 | } 267 | // Element (standard) 268 | _, err = templBuffer.WriteString("") 269 | if err != nil { 270 | return err 271 | } 272 | // Text 273 | var_11 := `angie@macdowell.org` 274 | _, err = templBuffer.WriteString(var_11) 275 | if err != nil { 276 | return err 277 | } 278 | _, err = templBuffer.WriteString("") 279 | if err != nil { 280 | return err 281 | } 282 | // Element (standard) 283 | _, err = templBuffer.WriteString("") 284 | if err != nil { 285 | return err 286 | } 287 | // Text 288 | var_12 := `Active` 289 | _, err = templBuffer.WriteString(var_12) 290 | if err != nil { 291 | return err 292 | } 293 | _, err = templBuffer.WriteString("") 294 | if err != nil { 295 | return err 296 | } 297 | // Element (standard) 298 | _, err = templBuffer.WriteString("") 299 | if err != nil { 300 | return err 301 | } 302 | // Element (standard) 303 | _, err = templBuffer.WriteString("") 317 | if err != nil { 318 | return err 319 | } 320 | // Text 321 | var_13 := `Delete` 322 | _, err = templBuffer.WriteString(var_13) 323 | if err != nil { 324 | return err 325 | } 326 | _, err = templBuffer.WriteString("") 327 | if err != nil { 328 | return err 329 | } 330 | _, err = templBuffer.WriteString("") 331 | if err != nil { 332 | return err 333 | } 334 | _, err = templBuffer.WriteString("") 335 | if err != nil { 336 | return err 337 | } 338 | // Element (standard) 339 | _, err = templBuffer.WriteString("") 340 | if err != nil { 341 | return err 342 | } 343 | // Element (standard) 344 | _, err = templBuffer.WriteString("") 345 | if err != nil { 346 | return err 347 | } 348 | // Text 349 | var_14 := `Fuqua Tarkenton` 350 | _, err = templBuffer.WriteString(var_14) 351 | if err != nil { 352 | return err 353 | } 354 | _, err = templBuffer.WriteString("") 355 | if err != nil { 356 | return err 357 | } 358 | // Element (standard) 359 | _, err = templBuffer.WriteString("") 360 | if err != nil { 361 | return err 362 | } 363 | // Text 364 | var_15 := `fuqua@tarkenton.org` 365 | _, err = templBuffer.WriteString(var_15) 366 | if err != nil { 367 | return err 368 | } 369 | _, err = templBuffer.WriteString("") 370 | if err != nil { 371 | return err 372 | } 373 | // Element (standard) 374 | _, err = templBuffer.WriteString("") 375 | if err != nil { 376 | return err 377 | } 378 | // Text 379 | var_16 := `Active` 380 | _, err = templBuffer.WriteString(var_16) 381 | if err != nil { 382 | return err 383 | } 384 | _, err = templBuffer.WriteString("") 385 | if err != nil { 386 | return err 387 | } 388 | // Element (standard) 389 | _, err = templBuffer.WriteString("") 390 | if err != nil { 391 | return err 392 | } 393 | // Element (standard) 394 | _, err = templBuffer.WriteString("") 408 | if err != nil { 409 | return err 410 | } 411 | // Text 412 | var_17 := `Delete` 413 | _, err = templBuffer.WriteString(var_17) 414 | if err != nil { 415 | return err 416 | } 417 | _, err = templBuffer.WriteString("") 418 | if err != nil { 419 | return err 420 | } 421 | _, err = templBuffer.WriteString("") 422 | if err != nil { 423 | return err 424 | } 425 | _, err = templBuffer.WriteString("") 426 | if err != nil { 427 | return err 428 | } 429 | // Element (standard) 430 | _, err = templBuffer.WriteString("") 431 | if err != nil { 432 | return err 433 | } 434 | // Element (standard) 435 | _, err = templBuffer.WriteString("") 436 | if err != nil { 437 | return err 438 | } 439 | // Text 440 | var_18 := `Kim Yee` 441 | _, err = templBuffer.WriteString(var_18) 442 | if err != nil { 443 | return err 444 | } 445 | _, err = templBuffer.WriteString("") 446 | if err != nil { 447 | return err 448 | } 449 | // Element (standard) 450 | _, err = templBuffer.WriteString("") 451 | if err != nil { 452 | return err 453 | } 454 | // Text 455 | var_19 := `kim@yee.org` 456 | _, err = templBuffer.WriteString(var_19) 457 | if err != nil { 458 | return err 459 | } 460 | _, err = templBuffer.WriteString("") 461 | if err != nil { 462 | return err 463 | } 464 | // Element (standard) 465 | _, err = templBuffer.WriteString("") 466 | if err != nil { 467 | return err 468 | } 469 | // Text 470 | var_20 := `Inactive` 471 | _, err = templBuffer.WriteString(var_20) 472 | if err != nil { 473 | return err 474 | } 475 | _, err = templBuffer.WriteString("") 476 | if err != nil { 477 | return err 478 | } 479 | // Element (standard) 480 | _, err = templBuffer.WriteString("") 481 | if err != nil { 482 | return err 483 | } 484 | // Element (standard) 485 | _, err = templBuffer.WriteString("") 499 | if err != nil { 500 | return err 501 | } 502 | // Text 503 | var_21 := `Delete` 504 | _, err = templBuffer.WriteString(var_21) 505 | if err != nil { 506 | return err 507 | } 508 | _, err = templBuffer.WriteString("") 509 | if err != nil { 510 | return err 511 | } 512 | _, err = templBuffer.WriteString("") 513 | if err != nil { 514 | return err 515 | } 516 | _, err = templBuffer.WriteString("") 517 | if err != nil { 518 | return err 519 | } 520 | _, err = templBuffer.WriteString("") 521 | if err != nil { 522 | return err 523 | } 524 | _, err = templBuffer.WriteString("") 525 | if err != nil { 526 | return err 527 | } 528 | if !templIsBuffer { 529 | _, err = io.Copy(w, templBuffer) 530 | } 531 | return err 532 | }) 533 | } 534 | 535 | func Index() templ.Component { 536 | return templ.ComponentFunc(func(ctx context.Context, w io.Writer) (err error) { 537 | templBuffer, templIsBuffer := w.(*bytes.Buffer) 538 | if !templIsBuffer { 539 | templBuffer = templ.GetBuffer() 540 | defer templ.ReleaseBuffer(templBuffer) 541 | } 542 | ctx = templ.InitializeContext(ctx) 543 | var_22 := templ.GetChildren(ctx) 544 | if var_22 == nil { 545 | var_22 = templ.NopComponent 546 | } 547 | ctx = templ.ClearChildren(ctx) 548 | // TemplElement 549 | var_23 := templ.ComponentFunc(func(ctx context.Context, w io.Writer) (err error) { 550 | templBuffer, templIsBuffer := w.(*bytes.Buffer) 551 | if !templIsBuffer { 552 | templBuffer = templ.GetBuffer() 553 | defer templ.ReleaseBuffer(templBuffer) 554 | } 555 | // Element (standard) 556 | _, err = templBuffer.WriteString("") 566 | if err != nil { 567 | return err 568 | } 569 | // Text 570 | var_24 := `Delete Row` 571 | _, err = templBuffer.WriteString(var_24) 572 | if err != nil { 573 | return err 574 | } 575 | _, err = templBuffer.WriteString("") 576 | if err != nil { 577 | return err 578 | } 579 | // Whitespace (normalised) 580 | _, err = templBuffer.WriteString(` `) 581 | if err != nil { 582 | return err 583 | } 584 | // TemplElement 585 | err = demo().Render(ctx, templBuffer) 586 | if err != nil { 587 | return err 588 | } 589 | if !templIsBuffer { 590 | _, err = io.Copy(w, templBuffer) 591 | } 592 | return err 593 | }) 594 | err = shared.Layout("Delete Row").Render(templ.WithChildren(ctx, var_23), templBuffer) 595 | if err != nil { 596 | return err 597 | } 598 | if !templIsBuffer { 599 | _, err = io.Copy(w, templBuffer) 600 | } 601 | return err 602 | }) 603 | } 604 | 605 | -------------------------------------------------------------------------------- /editrow/handlers.go: -------------------------------------------------------------------------------- 1 | package editrow 2 | 3 | import ( 4 | "net/http" 5 | "strconv" 6 | "strings" 7 | ) 8 | 9 | type user struct { 10 | name, email string 11 | } 12 | 13 | var users = []user{ 14 | {"Joe Smith", "joe@smith.org"}, 15 | {"Angie MacDowell", "angie@macdowell.org"}, 16 | {"Fuqua Tarkenton", "fuqua@tarkenton.org"}, 17 | {"Kim Yee", "kim@yee.org"}, 18 | } 19 | 20 | func Handlers(prefix string, mux *http.ServeMux) { 21 | mux.HandleFunc(prefix+"/", index) 22 | mux.HandleFunc(prefix+"/edit/", editUser) 23 | mux.HandleFunc(prefix+"/contact/", contacts) 24 | } 25 | 26 | func index(w http.ResponseWriter, r *http.Request) { 27 | // Load users 28 | Index(users).Render(r.Context(), w) 29 | } 30 | 31 | func editUser(w http.ResponseWriter, r *http.Request) { 32 | segments := strings.Split(r.URL.Path, "/") 33 | userID, _ := strconv.Atoi(segments[len(segments)-1]) 34 | form(userID, users[userID]).Render(r.Context(), w) 35 | } 36 | 37 | func contacts(w http.ResponseWriter, r *http.Request) { 38 | if r.Method == http.MethodGet { 39 | getRow(w, r) 40 | return 41 | } 42 | if r.Method == http.MethodPut { 43 | putUser(w, r) 44 | return 45 | } 46 | w.WriteHeader(404) 47 | } 48 | 49 | func getRow(w http.ResponseWriter, r *http.Request) { 50 | segments := strings.Split(r.URL.Path, "/") 51 | userID, _ := strconv.Atoi(segments[len(segments)-1]) 52 | row(userID, users[userID]).Render(r.Context(), w) 53 | } 54 | 55 | func putUser(w http.ResponseWriter, r *http.Request) { 56 | segments := strings.Split(r.URL.Path, "/") 57 | userID, _ := strconv.Atoi(segments[len(segments)-1]) 58 | r.ParseForm() 59 | name, email := r.FormValue("name"), r.FormValue("email") 60 | users[userID] = user{name, email} 61 | row(userID, users[userID]).Render(r.Context(), w) 62 | } 63 | -------------------------------------------------------------------------------- /editrow/templates.templ: -------------------------------------------------------------------------------- 1 | package editrow 2 | 3 | import ( 4 | "fmt" 5 | 6 | "examples/shared" 7 | ) 8 | 9 | templ demo(users []user) { 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | for i, u := range users { 18 | @row(i, u) 19 | } 20 |
NameEmail
21 | } 22 | 23 | templ row(id int, u user) { 24 | 25 | { u.name } 26 | { u.email } 27 | 28 | 29 | } 30 | 31 | templ form(id int, u user) { 32 | 33 | 34 | 35 | 36 | 37 | } 38 | 39 | templ Index(users []user) { 40 | @shared.Layout("Delete Row") { 41 |

Edit Row

42 | @demo(users) 43 | } 44 | } 45 | 46 | -------------------------------------------------------------------------------- /editrow/templates_templ.go: -------------------------------------------------------------------------------- 1 | // Code generated by templ@(devel) DO NOT EDIT. 2 | 3 | package editrow 4 | 5 | //lint:file-ignore SA4006 This context is only used if a nested component is present. 6 | 7 | import "github.com/a-h/templ" 8 | import "context" 9 | import "io" 10 | import "bytes" 11 | 12 | // GoExpression 13 | import ( 14 | "fmt" 15 | 16 | "examples/shared" 17 | ) 18 | 19 | func demo(users []user) templ.Component { 20 | return templ.ComponentFunc(func(ctx context.Context, w io.Writer) (err error) { 21 | templBuffer, templIsBuffer := w.(*bytes.Buffer) 22 | if !templIsBuffer { 23 | templBuffer = templ.GetBuffer() 24 | defer templ.ReleaseBuffer(templBuffer) 25 | } 26 | ctx = templ.InitializeContext(ctx) 27 | var_1 := templ.GetChildren(ctx) 28 | if var_1 == nil { 29 | var_1 = templ.NopComponent 30 | } 31 | ctx = templ.ClearChildren(ctx) 32 | // Element (standard) 33 | _, err = templBuffer.WriteString("") 43 | if err != nil { 44 | return err 45 | } 46 | // Element (standard) 47 | _, err = templBuffer.WriteString("") 48 | if err != nil { 49 | return err 50 | } 51 | // Element (standard) 52 | _, err = templBuffer.WriteString("") 53 | if err != nil { 54 | return err 55 | } 56 | // Element (standard) 57 | _, err = templBuffer.WriteString("") 58 | if err != nil { 59 | return err 60 | } 61 | // Text 62 | var_2 := `Name` 63 | _, err = templBuffer.WriteString(var_2) 64 | if err != nil { 65 | return err 66 | } 67 | _, err = templBuffer.WriteString("") 68 | if err != nil { 69 | return err 70 | } 71 | // Element (standard) 72 | _, err = templBuffer.WriteString("") 73 | if err != nil { 74 | return err 75 | } 76 | // Text 77 | var_3 := `Email` 78 | _, err = templBuffer.WriteString(var_3) 79 | if err != nil { 80 | return err 81 | } 82 | _, err = templBuffer.WriteString("") 83 | if err != nil { 84 | return err 85 | } 86 | // Element (standard) 87 | _, err = templBuffer.WriteString("") 88 | if err != nil { 89 | return err 90 | } 91 | _, err = templBuffer.WriteString("") 92 | if err != nil { 93 | return err 94 | } 95 | _, err = templBuffer.WriteString("") 96 | if err != nil { 97 | return err 98 | } 99 | _, err = templBuffer.WriteString("") 100 | if err != nil { 101 | return err 102 | } 103 | // Element (standard) 104 | _, err = templBuffer.WriteString("") 118 | if err != nil { 119 | return err 120 | } 121 | // For 122 | for i, u := range users { 123 | // TemplElement 124 | err = row(i, u).Render(ctx, templBuffer) 125 | if err != nil { 126 | return err 127 | } 128 | } 129 | _, err = templBuffer.WriteString("") 130 | if err != nil { 131 | return err 132 | } 133 | _, err = templBuffer.WriteString("") 134 | if err != nil { 135 | return err 136 | } 137 | if !templIsBuffer { 138 | _, err = io.Copy(w, templBuffer) 139 | } 140 | return err 141 | }) 142 | } 143 | 144 | func row(id int, u user) templ.Component { 145 | return templ.ComponentFunc(func(ctx context.Context, w io.Writer) (err error) { 146 | templBuffer, templIsBuffer := w.(*bytes.Buffer) 147 | if !templIsBuffer { 148 | templBuffer = templ.GetBuffer() 149 | defer templ.ReleaseBuffer(templBuffer) 150 | } 151 | ctx = templ.InitializeContext(ctx) 152 | var_4 := templ.GetChildren(ctx) 153 | if var_4 == nil { 154 | var_4 = templ.NopComponent 155 | } 156 | ctx = templ.ClearChildren(ctx) 157 | // Element (standard) 158 | _, err = templBuffer.WriteString("") 159 | if err != nil { 160 | return err 161 | } 162 | // Element (standard) 163 | _, err = templBuffer.WriteString("") 164 | if err != nil { 165 | return err 166 | } 167 | // StringExpression 168 | var var_5 string = u.name 169 | _, err = templBuffer.WriteString(templ.EscapeString(var_5)) 170 | if err != nil { 171 | return err 172 | } 173 | _, err = templBuffer.WriteString("") 174 | if err != nil { 175 | return err 176 | } 177 | // Element (standard) 178 | _, err = templBuffer.WriteString("") 179 | if err != nil { 180 | return err 181 | } 182 | // StringExpression 183 | var var_6 string = u.email 184 | _, err = templBuffer.WriteString(templ.EscapeString(var_6)) 185 | if err != nil { 186 | return err 187 | } 188 | _, err = templBuffer.WriteString("") 189 | if err != nil { 190 | return err 191 | } 192 | // Element (standard) 193 | _, err = templBuffer.WriteString("") 194 | if err != nil { 195 | return err 196 | } 197 | // Element (standard) 198 | _, err = templBuffer.WriteString("") 224 | if err != nil { 225 | return err 226 | } 227 | // Text 228 | var_7 := `Edit` 229 | _, err = templBuffer.WriteString(var_7) 230 | if err != nil { 231 | return err 232 | } 233 | _, err = templBuffer.WriteString("") 234 | if err != nil { 235 | return err 236 | } 237 | _, err = templBuffer.WriteString("") 238 | if err != nil { 239 | return err 240 | } 241 | _, err = templBuffer.WriteString("") 242 | if err != nil { 243 | return err 244 | } 245 | if !templIsBuffer { 246 | _, err = io.Copy(w, templBuffer) 247 | } 248 | return err 249 | }) 250 | } 251 | 252 | func form(id int, u user) templ.Component { 253 | return templ.ComponentFunc(func(ctx context.Context, w io.Writer) (err error) { 254 | templBuffer, templIsBuffer := w.(*bytes.Buffer) 255 | if !templIsBuffer { 256 | templBuffer = templ.GetBuffer() 257 | defer templ.ReleaseBuffer(templBuffer) 258 | } 259 | ctx = templ.InitializeContext(ctx) 260 | var_8 := templ.GetChildren(ctx) 261 | if var_8 == nil { 262 | var_8 = templ.NopComponent 263 | } 264 | ctx = templ.ClearChildren(ctx) 265 | // Element (standard) 266 | _, err = templBuffer.WriteString("") 296 | if err != nil { 297 | return err 298 | } 299 | // Element (standard) 300 | _, err = templBuffer.WriteString("") 301 | if err != nil { 302 | return err 303 | } 304 | // Element (void) 305 | _, err = templBuffer.WriteString("") 331 | if err != nil { 332 | return err 333 | } 334 | _, err = templBuffer.WriteString("") 335 | if err != nil { 336 | return err 337 | } 338 | // Element (standard) 339 | _, err = templBuffer.WriteString("") 340 | if err != nil { 341 | return err 342 | } 343 | // Element (void) 344 | _, err = templBuffer.WriteString("") 370 | if err != nil { 371 | return err 372 | } 373 | _, err = templBuffer.WriteString("") 374 | if err != nil { 375 | return err 376 | } 377 | // Element (standard) 378 | _, err = templBuffer.WriteString("") 379 | if err != nil { 380 | return err 381 | } 382 | // Element (standard) 383 | _, err = templBuffer.WriteString("") 409 | if err != nil { 410 | return err 411 | } 412 | // Text 413 | var_9 := `Cancel` 414 | _, err = templBuffer.WriteString(var_9) 415 | if err != nil { 416 | return err 417 | } 418 | _, err = templBuffer.WriteString("") 419 | if err != nil { 420 | return err 421 | } 422 | // Element (standard) 423 | _, err = templBuffer.WriteString("") 453 | if err != nil { 454 | return err 455 | } 456 | // Text 457 | var_10 := `Save` 458 | _, err = templBuffer.WriteString(var_10) 459 | if err != nil { 460 | return err 461 | } 462 | _, err = templBuffer.WriteString("") 463 | if err != nil { 464 | return err 465 | } 466 | _, err = templBuffer.WriteString("") 467 | if err != nil { 468 | return err 469 | } 470 | _, err = templBuffer.WriteString("") 471 | if err != nil { 472 | return err 473 | } 474 | if !templIsBuffer { 475 | _, err = io.Copy(w, templBuffer) 476 | } 477 | return err 478 | }) 479 | } 480 | 481 | func Index(users []user) templ.Component { 482 | return templ.ComponentFunc(func(ctx context.Context, w io.Writer) (err error) { 483 | templBuffer, templIsBuffer := w.(*bytes.Buffer) 484 | if !templIsBuffer { 485 | templBuffer = templ.GetBuffer() 486 | defer templ.ReleaseBuffer(templBuffer) 487 | } 488 | ctx = templ.InitializeContext(ctx) 489 | var_11 := templ.GetChildren(ctx) 490 | if var_11 == nil { 491 | var_11 = templ.NopComponent 492 | } 493 | ctx = templ.ClearChildren(ctx) 494 | // TemplElement 495 | var_12 := templ.ComponentFunc(func(ctx context.Context, w io.Writer) (err error) { 496 | templBuffer, templIsBuffer := w.(*bytes.Buffer) 497 | if !templIsBuffer { 498 | templBuffer = templ.GetBuffer() 499 | defer templ.ReleaseBuffer(templBuffer) 500 | } 501 | // Element (standard) 502 | _, err = templBuffer.WriteString("") 512 | if err != nil { 513 | return err 514 | } 515 | // Text 516 | var_13 := `Edit Row` 517 | _, err = templBuffer.WriteString(var_13) 518 | if err != nil { 519 | return err 520 | } 521 | _, err = templBuffer.WriteString("") 522 | if err != nil { 523 | return err 524 | } 525 | // Whitespace (normalised) 526 | _, err = templBuffer.WriteString(` `) 527 | if err != nil { 528 | return err 529 | } 530 | // TemplElement 531 | err = demo(users).Render(ctx, templBuffer) 532 | if err != nil { 533 | return err 534 | } 535 | if !templIsBuffer { 536 | _, err = io.Copy(w, templBuffer) 537 | } 538 | return err 539 | }) 540 | err = shared.Layout("Delete Row").Render(templ.WithChildren(ctx, var_12), templBuffer) 541 | if err != nil { 542 | return err 543 | } 544 | if !templIsBuffer { 545 | _, err = io.Copy(w, templBuffer) 546 | } 547 | return err 548 | }) 549 | } 550 | 551 | -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module examples 2 | 3 | go 1.21 4 | 5 | require ( 6 | github.com/a-h/pathvars v0.0.12 7 | github.com/a-h/templ v0.2.234-0.20230416205859-20293271f3c5 8 | github.com/rs/xid v1.5.0 9 | github.com/yosssi/gohtml v0.0.0-20201013000340-ee4748c638f4 10 | ) 11 | 12 | require ( 13 | github.com/justinas/nosurf v1.1.1 // indirect 14 | golang.org/x/net v0.9.0 // indirect 15 | ) 16 | -------------------------------------------------------------------------------- /go.sum: -------------------------------------------------------------------------------- 1 | github.com/a-h/pathvars v0.0.12 h1:B4JaZGvHKNgNNlw8LMayPM/Hc0f3xZ2PXivu8YIl/X0= 2 | github.com/a-h/pathvars v0.0.12/go.mod h1:7rLTtvDVyKneR/N65hC0lh2sZ2KRyAmWFaOvv00uxb0= 3 | github.com/a-h/templ v0.2.233 h1:EnZqZmtV0YICqWG6MtLNmTcWuFkl2ImyQ63SIpWaM2Y= 4 | github.com/a-h/templ v0.2.233/go.mod h1:h1DdzFMWVApvTcZBNmM6+mD6EPq6uYkncMNF7zdLj9I= 5 | github.com/a-h/templ v0.2.234-0.20230416205859-20293271f3c5 h1:NeF/iw7KU9W7CYYJimd5x7ooOXCLrfo8FcHdFPUU+2w= 6 | github.com/a-h/templ v0.2.234-0.20230416205859-20293271f3c5/go.mod h1:nqma2qb9ViAJOP4MBucyH+SPbOyNDZaRQyusfpK4PjY= 7 | github.com/justinas/nosurf v1.1.1 h1:92Aw44hjSK4MxJeMSyDa7jwuI9GR2J/JCQiaKvXXSlk= 8 | github.com/justinas/nosurf v1.1.1/go.mod h1:ALpWdSbuNGy2lZWtyXdjkYv4edL23oSEgfBT1gPJ5BQ= 9 | github.com/rs/xid v1.5.0 h1:mKX4bl4iPYJtEIxp6CYiUuLQ/8DYMoz0PUdtGgMFRVc= 10 | github.com/rs/xid v1.5.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= 11 | github.com/yosssi/gohtml v0.0.0-20201013000340-ee4748c638f4 h1:0sw0nJM544SpsihWx1bkXdYLQDlzRflMgFJQ4Yih9ts= 12 | github.com/yosssi/gohtml v0.0.0-20201013000340-ee4748c638f4/go.mod h1:+ccdNT0xMY1dtc5XBxumbYfOUhmduiGudqaDgD2rVRE= 13 | golang.org/x/net v0.9.0 h1:aWJ/m6xSmxWBx+V0XRHTlrYrPG56jKsLdTFmsSsCzOM= 14 | golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns= 15 | -------------------------------------------------------------------------------- /home.templ: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "examples/shared" 4 | 5 | templ Home(examples []Example) { 6 | @shared.Layout("Home") { 7 |

Examples:

8 | 9 | 10 | 11 | 12 | 13 | 14 | for _, e := range examples { 15 | 16 | 17 | 18 | 19 | } 20 |
PatternDescription
{ e.Name }{ e.Desc }
21 | } 22 | } 23 | 24 | -------------------------------------------------------------------------------- /home_templ.go: -------------------------------------------------------------------------------- 1 | // Code generated by templ@(devel) DO NOT EDIT. 2 | 3 | package main 4 | 5 | //lint:file-ignore SA4006 This context is only used if a nested component is present. 6 | 7 | import "github.com/a-h/templ" 8 | import "context" 9 | import "io" 10 | import "bytes" 11 | 12 | // GoExpression 13 | import "examples/shared" 14 | 15 | func Home(examples []Example) templ.Component { 16 | return templ.ComponentFunc(func(ctx context.Context, w io.Writer) (err error) { 17 | templBuffer, templIsBuffer := w.(*bytes.Buffer) 18 | if !templIsBuffer { 19 | templBuffer = templ.GetBuffer() 20 | defer templ.ReleaseBuffer(templBuffer) 21 | } 22 | ctx = templ.InitializeContext(ctx) 23 | var_1 := templ.GetChildren(ctx) 24 | if var_1 == nil { 25 | var_1 = templ.NopComponent 26 | } 27 | ctx = templ.ClearChildren(ctx) 28 | // TemplElement 29 | var_2 := templ.ComponentFunc(func(ctx context.Context, w io.Writer) (err error) { 30 | templBuffer, templIsBuffer := w.(*bytes.Buffer) 31 | if !templIsBuffer { 32 | templBuffer = templ.GetBuffer() 33 | defer templ.ReleaseBuffer(templBuffer) 34 | } 35 | // Element (standard) 36 | _, err = templBuffer.WriteString("") 46 | if err != nil { 47 | return err 48 | } 49 | // Text 50 | var_3 := `Examples:` 51 | _, err = templBuffer.WriteString(var_3) 52 | if err != nil { 53 | return err 54 | } 55 | _, err = templBuffer.WriteString("") 56 | if err != nil { 57 | return err 58 | } 59 | // Whitespace (normalised) 60 | _, err = templBuffer.WriteString(` `) 61 | if err != nil { 62 | return err 63 | } 64 | // Element (standard) 65 | _, err = templBuffer.WriteString("") 75 | if err != nil { 76 | return err 77 | } 78 | // Element (standard) 79 | _, err = templBuffer.WriteString("") 80 | if err != nil { 81 | return err 82 | } 83 | // Element (standard) 84 | _, err = templBuffer.WriteString("") 85 | if err != nil { 86 | return err 87 | } 88 | // Element (standard) 89 | _, err = templBuffer.WriteString("") 90 | if err != nil { 91 | return err 92 | } 93 | // Text 94 | var_4 := `Pattern` 95 | _, err = templBuffer.WriteString(var_4) 96 | if err != nil { 97 | return err 98 | } 99 | _, err = templBuffer.WriteString("") 100 | if err != nil { 101 | return err 102 | } 103 | // Element (standard) 104 | _, err = templBuffer.WriteString("") 105 | if err != nil { 106 | return err 107 | } 108 | // Text 109 | var_5 := `Description` 110 | _, err = templBuffer.WriteString(var_5) 111 | if err != nil { 112 | return err 113 | } 114 | _, err = templBuffer.WriteString("") 115 | if err != nil { 116 | return err 117 | } 118 | _, err = templBuffer.WriteString("") 119 | if err != nil { 120 | return err 121 | } 122 | _, err = templBuffer.WriteString("") 123 | if err != nil { 124 | return err 125 | } 126 | // Element (standard) 127 | _, err = templBuffer.WriteString("") 128 | if err != nil { 129 | return err 130 | } 131 | // For 132 | for _, e := range examples { 133 | // Element (standard) 134 | _, err = templBuffer.WriteString("") 135 | if err != nil { 136 | return err 137 | } 138 | // Element (standard) 139 | _, err = templBuffer.WriteString("") 140 | if err != nil { 141 | return err 142 | } 143 | // Element (standard) 144 | _, err = templBuffer.WriteString("") 167 | if err != nil { 168 | return err 169 | } 170 | // StringExpression 171 | var var_7 string = e.Name 172 | _, err = templBuffer.WriteString(templ.EscapeString(var_7)) 173 | if err != nil { 174 | return err 175 | } 176 | _, err = templBuffer.WriteString("") 177 | if err != nil { 178 | return err 179 | } 180 | _, err = templBuffer.WriteString("") 181 | if err != nil { 182 | return err 183 | } 184 | // Element (standard) 185 | _, err = templBuffer.WriteString("") 186 | if err != nil { 187 | return err 188 | } 189 | // StringExpression 190 | var var_8 string = e.Desc 191 | _, err = templBuffer.WriteString(templ.EscapeString(var_8)) 192 | if err != nil { 193 | return err 194 | } 195 | _, err = templBuffer.WriteString("") 196 | if err != nil { 197 | return err 198 | } 199 | _, err = templBuffer.WriteString("") 200 | if err != nil { 201 | return err 202 | } 203 | } 204 | _, err = templBuffer.WriteString("") 205 | if err != nil { 206 | return err 207 | } 208 | _, err = templBuffer.WriteString("") 209 | if err != nil { 210 | return err 211 | } 212 | if !templIsBuffer { 213 | _, err = io.Copy(w, templBuffer) 214 | } 215 | return err 216 | }) 217 | err = shared.Layout("Home").Render(templ.WithChildren(ctx, var_2), templBuffer) 218 | if err != nil { 219 | return err 220 | } 221 | if !templIsBuffer { 222 | _, err = io.Copy(w, templBuffer) 223 | } 224 | return err 225 | }) 226 | } 227 | 228 | -------------------------------------------------------------------------------- /inlinevalidation/handlers.go: -------------------------------------------------------------------------------- 1 | package inlinevalidation 2 | 3 | import ( 4 | "errors" 5 | "net/http" 6 | 7 | "github.com/a-h/pathvars" 8 | ) 9 | 10 | var validateMatcher = pathvars.NewExtractor("/inline-validation/validate/{name}") 11 | 12 | func Handlers(prefix string, mux *http.ServeMux) { 13 | mux.HandleFunc(prefix+"/", index) 14 | mux.HandleFunc(prefix+"/validate/", validate) 15 | } 16 | 17 | func index(w http.ResponseWriter, r *http.Request) { 18 | Index().Render(r.Context(), w) 19 | } 20 | 21 | func validate(w http.ResponseWriter, r *http.Request) { 22 | vals, ok := validateMatcher.Extract(r.URL) 23 | if !ok { 24 | w.WriteHeader(500) 25 | return 26 | } 27 | name, ok := vals["name"] 28 | if !ok { 29 | w.WriteHeader(500) 30 | return 31 | } 32 | f, ok := fields[name] 33 | if !ok { 34 | w.WriteHeader(500) 35 | return 36 | } 37 | if err := r.ParseForm(); err != nil { 38 | w.WriteHeader(500) 39 | return 40 | } 41 | val := r.FormValue(name) 42 | inp(f, name, val, f.validator(val)).Render(r.Context(), w) 43 | } 44 | 45 | type field struct { 46 | text string 47 | validator func(string) error 48 | } 49 | 50 | var fields = map[string]field{ 51 | "email": { 52 | text: "Email", 53 | validator: func(value string) error { 54 | if value != "test@test.com" { 55 | return errors.New("Only test@test.com is valid.") 56 | } 57 | return nil 58 | }, 59 | }, 60 | "firstName": { 61 | text: "First Name", 62 | validator: func(value string) error { 63 | if value == "" { 64 | return errors.New("Required") 65 | } 66 | return nil 67 | }, 68 | }, 69 | "lastName": { 70 | text: "Last Name", 71 | validator: func(value string) error { 72 | if value == "" { 73 | return errors.New("Required") 74 | } 75 | return nil 76 | }, 77 | }, 78 | } 79 | -------------------------------------------------------------------------------- /inlinevalidation/templates.templ: -------------------------------------------------------------------------------- 1 | package inlinevalidation 2 | 3 | import "examples/shared" 4 | 5 | templ demo() { 6 |
7 | @inp(fields["email"], "email", "", nil) 8 | @inp(fields["firstName"], "firstName", "", nil) 9 | @inp(fields["lastName"], "lastName", "", nil) 10 |
11 |
12 |
13 |
14 | } 15 | 16 | templ inp(f field, name, value string, validation error) { 17 |
18 | 19 |
24 | if validation != nil { 25 |

{ validation.Error() }

26 | } 27 |
28 | } 29 | 30 | templ Index() { 31 | @shared.Layout("Inline Validation") { 32 |

Inline Validation

33 | @demo() 34 | } 35 | } 36 | 37 | -------------------------------------------------------------------------------- /inlinevalidation/templates_templ.go: -------------------------------------------------------------------------------- 1 | // Code generated by templ@(devel) DO NOT EDIT. 2 | 3 | package inlinevalidation 4 | 5 | //lint:file-ignore SA4006 This context is only used if a nested component is present. 6 | 7 | import "github.com/a-h/templ" 8 | import "context" 9 | import "io" 10 | import "bytes" 11 | 12 | // GoExpression 13 | import "examples/shared" 14 | 15 | func demo() templ.Component { 16 | return templ.ComponentFunc(func(ctx context.Context, w io.Writer) (err error) { 17 | templBuffer, templIsBuffer := w.(*bytes.Buffer) 18 | if !templIsBuffer { 19 | templBuffer = templ.GetBuffer() 20 | defer templ.ReleaseBuffer(templBuffer) 21 | } 22 | ctx = templ.InitializeContext(ctx) 23 | var_1 := templ.GetChildren(ctx) 24 | if var_1 == nil { 25 | var_1 = templ.NopComponent 26 | } 27 | ctx = templ.ClearChildren(ctx) 28 | // Element (standard) 29 | _, err = templBuffer.WriteString("") 39 | if err != nil { 40 | return err 41 | } 42 | // TemplElement 43 | err = inp(fields["email"], "email", "", nil).Render(ctx, templBuffer) 44 | if err != nil { 45 | return err 46 | } 47 | // TemplElement 48 | err = inp(fields["firstName"], "firstName", "", nil).Render(ctx, templBuffer) 49 | if err != nil { 50 | return err 51 | } 52 | // TemplElement 53 | err = inp(fields["lastName"], "lastName", "", nil).Render(ctx, templBuffer) 54 | if err != nil { 55 | return err 56 | } 57 | // Element (standard) 58 | _, err = templBuffer.WriteString("") 68 | if err != nil { 69 | return err 70 | } 71 | // Element (standard) 72 | _, err = templBuffer.WriteString("") 82 | if err != nil { 83 | return err 84 | } 85 | // Element (standard) 86 | _, err = templBuffer.WriteString("") 96 | if err != nil { 97 | return err 98 | } 99 | // Text 100 | var_2 := `Submit` 101 | _, err = templBuffer.WriteString(var_2) 102 | if err != nil { 103 | return err 104 | } 105 | _, err = templBuffer.WriteString("") 106 | if err != nil { 107 | return err 108 | } 109 | _, err = templBuffer.WriteString("") 110 | if err != nil { 111 | return err 112 | } 113 | _, err = templBuffer.WriteString("") 114 | if err != nil { 115 | return err 116 | } 117 | _, err = templBuffer.WriteString("") 118 | if err != nil { 119 | return err 120 | } 121 | if !templIsBuffer { 122 | _, err = io.Copy(w, templBuffer) 123 | } 124 | return err 125 | }) 126 | } 127 | 128 | func inp(f field, name, value string, validation error) templ.Component { 129 | return templ.ComponentFunc(func(ctx context.Context, w io.Writer) (err error) { 130 | templBuffer, templIsBuffer := w.(*bytes.Buffer) 131 | if !templIsBuffer { 132 | templBuffer = templ.GetBuffer() 133 | defer templ.ReleaseBuffer(templBuffer) 134 | } 135 | ctx = templ.InitializeContext(ctx) 136 | var_3 := templ.GetChildren(ctx) 137 | if var_3 == nil { 138 | var_3 = templ.NopComponent 139 | } 140 | ctx = templ.ClearChildren(ctx) 141 | // Element (standard) 142 | _, err = templBuffer.WriteString("") 160 | if err != nil { 161 | return err 162 | } 163 | // Element (standard) 164 | _, err = templBuffer.WriteString("") 174 | if err != nil { 175 | return err 176 | } 177 | // StringExpression 178 | var var_4 string = f.text 179 | _, err = templBuffer.WriteString(templ.EscapeString(var_4)) 180 | if err != nil { 181 | return err 182 | } 183 | _, err = templBuffer.WriteString("") 184 | if err != nil { 185 | return err 186 | } 187 | // Element (standard) 188 | _, err = templBuffer.WriteString("") 198 | if err != nil { 199 | return err 200 | } 201 | // Element (void) 202 | _, err = templBuffer.WriteString("") 267 | if err != nil { 268 | return err 269 | } 270 | _, err = templBuffer.WriteString("") 271 | if err != nil { 272 | return err 273 | } 274 | // If 275 | if validation != nil { 276 | // Element (standard) 277 | _, err = templBuffer.WriteString("") 287 | if err != nil { 288 | return err 289 | } 290 | // StringExpression 291 | var var_5 string = validation.Error() 292 | _, err = templBuffer.WriteString(templ.EscapeString(var_5)) 293 | if err != nil { 294 | return err 295 | } 296 | _, err = templBuffer.WriteString("

") 297 | if err != nil { 298 | return err 299 | } 300 | } 301 | _, err = templBuffer.WriteString("") 302 | if err != nil { 303 | return err 304 | } 305 | if !templIsBuffer { 306 | _, err = io.Copy(w, templBuffer) 307 | } 308 | return err 309 | }) 310 | } 311 | 312 | func Index() templ.Component { 313 | return templ.ComponentFunc(func(ctx context.Context, w io.Writer) (err error) { 314 | templBuffer, templIsBuffer := w.(*bytes.Buffer) 315 | if !templIsBuffer { 316 | templBuffer = templ.GetBuffer() 317 | defer templ.ReleaseBuffer(templBuffer) 318 | } 319 | ctx = templ.InitializeContext(ctx) 320 | var_6 := templ.GetChildren(ctx) 321 | if var_6 == nil { 322 | var_6 = templ.NopComponent 323 | } 324 | ctx = templ.ClearChildren(ctx) 325 | // TemplElement 326 | var_7 := templ.ComponentFunc(func(ctx context.Context, w io.Writer) (err error) { 327 | templBuffer, templIsBuffer := w.(*bytes.Buffer) 328 | if !templIsBuffer { 329 | templBuffer = templ.GetBuffer() 330 | defer templ.ReleaseBuffer(templBuffer) 331 | } 332 | // Element (standard) 333 | _, err = templBuffer.WriteString("") 343 | if err != nil { 344 | return err 345 | } 346 | // Text 347 | var_8 := `Inline Validation` 348 | _, err = templBuffer.WriteString(var_8) 349 | if err != nil { 350 | return err 351 | } 352 | _, err = templBuffer.WriteString("") 353 | if err != nil { 354 | return err 355 | } 356 | // Whitespace (normalised) 357 | _, err = templBuffer.WriteString(` `) 358 | if err != nil { 359 | return err 360 | } 361 | // TemplElement 362 | err = demo().Render(ctx, templBuffer) 363 | if err != nil { 364 | return err 365 | } 366 | if !templIsBuffer { 367 | _, err = io.Copy(w, templBuffer) 368 | } 369 | return err 370 | }) 371 | err = shared.Layout("Inline Validation").Render(templ.WithChildren(ctx, var_7), templBuffer) 372 | if err != nil { 373 | return err 374 | } 375 | if !templIsBuffer { 376 | _, err = io.Copy(w, templBuffer) 377 | } 378 | return err 379 | }) 380 | } 381 | 382 | -------------------------------------------------------------------------------- /lazyload/bars.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 7 | 11 | 12 | 13 | 17 | 21 | 22 | 23 | 27 | 31 | 32 | 33 | 37 | 41 | 42 | 43 | 47 | 51 | 52 | 53 | -------------------------------------------------------------------------------- /lazyload/handlers.go: -------------------------------------------------------------------------------- 1 | package lazyload 2 | 3 | import ( 4 | _ "embed" 5 | "net/http" 6 | "time" 7 | ) 8 | 9 | var ( 10 | //go:embed tokyo.png 11 | graphBytes []byte 12 | //go:embed bars.svg 13 | barsBytes []byte 14 | ) 15 | 16 | func Handlers(prefix string, mux *http.ServeMux) { 17 | mux.HandleFunc(prefix+"/", index) 18 | mux.HandleFunc(prefix+"/graph", graph) 19 | mux.HandleFunc(prefix+"/bars.svg", bars) 20 | mux.HandleFunc(prefix+"/tokyo.png", tokyo) 21 | } 22 | 23 | func index(w http.ResponseWriter, r *http.Request) { 24 | Index().Render(r.Context(), w) 25 | } 26 | 27 | func graph(w http.ResponseWriter, r *http.Request) { 28 | time.Sleep(2 * time.Second) 29 | graphImage().Render(r.Context(), w) 30 | } 31 | 32 | func bars(w http.ResponseWriter, r *http.Request) { 33 | w.Header().Set("Content-Type", "image/svg+xml") 34 | w.Write(barsBytes) 35 | } 36 | 37 | func tokyo(w http.ResponseWriter, r *http.Request) { 38 | w.Write(graphBytes) 39 | } 40 | -------------------------------------------------------------------------------- /lazyload/templates.templ: -------------------------------------------------------------------------------- 1 | package lazyload 2 | 3 | import "examples/shared" 4 | 5 | templ demo() { 6 | 14 |
Result loading...
15 | } 16 | 17 | templ graphImage() { 18 | Tokyo Climate 19 | } 20 | 21 | templ Index() { 22 | @shared.Layout("Lazy Loading") { 23 |

Lazy Loading

24 | @demo() 25 | } 26 | } 27 | 28 | -------------------------------------------------------------------------------- /lazyload/templates_templ.go: -------------------------------------------------------------------------------- 1 | // Code generated by templ@(devel) DO NOT EDIT. 2 | 3 | package lazyload 4 | 5 | //lint:file-ignore SA4006 This context is only used if a nested component is present. 6 | 7 | import "github.com/a-h/templ" 8 | import "context" 9 | import "io" 10 | import "bytes" 11 | 12 | // GoExpression 13 | import "examples/shared" 14 | 15 | func demo() templ.Component { 16 | return templ.ComponentFunc(func(ctx context.Context, w io.Writer) (err error) { 17 | templBuffer, templIsBuffer := w.(*bytes.Buffer) 18 | if !templIsBuffer { 19 | templBuffer = templ.GetBuffer() 20 | defer templ.ReleaseBuffer(templBuffer) 21 | } 22 | ctx = templ.InitializeContext(ctx) 23 | var_1 := templ.GetChildren(ctx) 24 | if var_1 == nil { 25 | var_1 = templ.NopComponent 26 | } 27 | ctx = templ.ClearChildren(ctx) 28 | // RawElement 29 | _, err = templBuffer.WriteString("") 47 | if err != nil { 48 | return err 49 | } 50 | // Element (standard) 51 | _, err = templBuffer.WriteString("") 65 | if err != nil { 66 | return err 67 | } 68 | // Element (void) 69 | _, err = templBuffer.WriteString("") 91 | if err != nil { 92 | return err 93 | } 94 | _, err = templBuffer.WriteString("") 95 | if err != nil { 96 | return err 97 | } 98 | if !templIsBuffer { 99 | _, err = io.Copy(w, templBuffer) 100 | } 101 | return err 102 | }) 103 | } 104 | 105 | func graphImage() templ.Component { 106 | return templ.ComponentFunc(func(ctx context.Context, w io.Writer) (err error) { 107 | templBuffer, templIsBuffer := w.(*bytes.Buffer) 108 | if !templIsBuffer { 109 | templBuffer = templ.GetBuffer() 110 | defer templ.ReleaseBuffer(templBuffer) 111 | } 112 | ctx = templ.InitializeContext(ctx) 113 | var_3 := templ.GetChildren(ctx) 114 | if var_3 == nil { 115 | var_3 = templ.NopComponent 116 | } 117 | ctx = templ.ClearChildren(ctx) 118 | // Element (void) 119 | _, err = templBuffer.WriteString("") 133 | if err != nil { 134 | return err 135 | } 136 | if !templIsBuffer { 137 | _, err = io.Copy(w, templBuffer) 138 | } 139 | return err 140 | }) 141 | } 142 | 143 | func Index() templ.Component { 144 | return templ.ComponentFunc(func(ctx context.Context, w io.Writer) (err error) { 145 | templBuffer, templIsBuffer := w.(*bytes.Buffer) 146 | if !templIsBuffer { 147 | templBuffer = templ.GetBuffer() 148 | defer templ.ReleaseBuffer(templBuffer) 149 | } 150 | ctx = templ.InitializeContext(ctx) 151 | var_4 := templ.GetChildren(ctx) 152 | if var_4 == nil { 153 | var_4 = templ.NopComponent 154 | } 155 | ctx = templ.ClearChildren(ctx) 156 | // TemplElement 157 | var_5 := templ.ComponentFunc(func(ctx context.Context, w io.Writer) (err error) { 158 | templBuffer, templIsBuffer := w.(*bytes.Buffer) 159 | if !templIsBuffer { 160 | templBuffer = templ.GetBuffer() 161 | defer templ.ReleaseBuffer(templBuffer) 162 | } 163 | // Element (standard) 164 | _, err = templBuffer.WriteString("") 174 | if err != nil { 175 | return err 176 | } 177 | // Text 178 | var_6 := `Lazy Loading` 179 | _, err = templBuffer.WriteString(var_6) 180 | if err != nil { 181 | return err 182 | } 183 | _, err = templBuffer.WriteString("") 184 | if err != nil { 185 | return err 186 | } 187 | // Whitespace (normalised) 188 | _, err = templBuffer.WriteString(` `) 189 | if err != nil { 190 | return err 191 | } 192 | // TemplElement 193 | err = demo().Render(ctx, templBuffer) 194 | if err != nil { 195 | return err 196 | } 197 | if !templIsBuffer { 198 | _, err = io.Copy(w, templBuffer) 199 | } 200 | return err 201 | }) 202 | err = shared.Layout("Lazy Loading").Render(templ.WithChildren(ctx, var_5), templBuffer) 203 | if err != nil { 204 | return err 205 | } 206 | if !templIsBuffer { 207 | _, err = io.Copy(w, templBuffer) 208 | } 209 | return err 210 | }) 211 | } 212 | 213 | -------------------------------------------------------------------------------- /lazyload/tokyo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joerdav/go-htmx-examples/fe6fe1f9b34228a49162333813f8602deaa59dea/lazyload/tokyo.png -------------------------------------------------------------------------------- /main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "examples/bulkupdate" 5 | "examples/clicktoedit" 6 | "examples/clicktoload" 7 | "examples/csrf" 8 | "examples/deleterow" 9 | "examples/editrow" 10 | "examples/inlinevalidation" 11 | "examples/lazyload" 12 | "log" 13 | "net/http" 14 | 15 | "github.com/a-h/templ" 16 | ) 17 | 18 | func main() { 19 | if err := run(); err != nil { 20 | log.Fatal(err) 21 | } 22 | } 23 | 24 | func run() error { 25 | r := http.NewServeMux() 26 | r.Handle("/", templ.Handler(Home(examples))) 27 | for _, e := range examples { 28 | log.Printf("Serving %q on /%s", e.Name, e.Slug) 29 | e.Handlers("/"+e.Slug, r) 30 | } 31 | log.Println("Listening on localhost:2468") 32 | return http.ListenAndServe("localhost:2468", r) 33 | } 34 | 35 | type Example struct { 36 | Name, Desc, Slug string 37 | Handlers func(string, *http.ServeMux) 38 | } 39 | 40 | var examples = []Example{ 41 | { 42 | Name: "CSRF Protection", 43 | Desc: "Demonstrates how to do CSRF Protection", 44 | Slug: "csrf", 45 | Handlers: csrf.Handlers, 46 | }, 47 | { 48 | Name: "Click To Edit", 49 | Desc: "Demonstrates inline editing of a data object", 50 | Slug: "click-to-edit", 51 | Handlers: clicktoedit.Handlers, 52 | }, 53 | { 54 | Name: "Bulk Update", 55 | Desc: "Demonstrates bulk updating of multiple rows of data", 56 | Slug: "bulk-update", 57 | Handlers: bulkupdate.Handlers, 58 | }, 59 | { 60 | Name: "Click to Load", 61 | Desc: "Demonstrates clicking to load more rows in a table", 62 | Slug: "click-to-load", 63 | Handlers: clicktoload.Handlers, 64 | }, 65 | { 66 | Name: "Delete Row", 67 | Desc: "Demonstrates row deletion in a table", 68 | Slug: "delete-row", 69 | Handlers: deleterow.Handlers, 70 | }, 71 | { 72 | Name: "Edit Row", 73 | Desc: "Demonstrates how to edit rows in a table", 74 | Slug: "edit-row", 75 | Handlers: editrow.Handlers, 76 | }, 77 | { 78 | Name: "Lazy Loading", 79 | Desc: "Demonstrates how to lazy load content", 80 | Slug: "lazy-loading", 81 | Handlers: lazyload.Handlers, 82 | }, 83 | { 84 | Name: "Inline Validation", 85 | Desc: "Demonstrates how to do inline field validation", 86 | Slug: "inline-validation", 87 | Handlers: inlinevalidation.Handlers, 88 | }, 89 | } 90 | -------------------------------------------------------------------------------- /shared/layout.templ: -------------------------------------------------------------------------------- 1 | package shared 2 | 3 | import "os" 4 | 5 | templ Layout(title string) { 6 | 7 | 8 | 9 | 16 | 17 | Go htmx examples - { title } 18 | 19 | if os.Getenv("DEBUG") == "true" { 20 | 30 | } 31 | 32 | 33 | @Nav() 34 |
35 | { children... } 36 |
37 | 38 | 39 | 40 | 41 | } 42 | 43 | templ Nav() { 44 | 49 | } 50 | 51 | -------------------------------------------------------------------------------- /shared/layout_templ.go: -------------------------------------------------------------------------------- 1 | // Code generated by templ@(devel) DO NOT EDIT. 2 | 3 | package shared 4 | 5 | //lint:file-ignore SA4006 This context is only used if a nested component is present. 6 | 7 | import "github.com/a-h/templ" 8 | import "context" 9 | import "io" 10 | import "bytes" 11 | 12 | // GoExpression 13 | import "os" 14 | 15 | func Layout(title string) templ.Component { 16 | return templ.ComponentFunc(func(ctx context.Context, w io.Writer) (err error) { 17 | templBuffer, templIsBuffer := w.(*bytes.Buffer) 18 | if !templIsBuffer { 19 | templBuffer = templ.GetBuffer() 20 | defer templ.ReleaseBuffer(templBuffer) 21 | } 22 | ctx = templ.InitializeContext(ctx) 23 | var_1 := templ.GetChildren(ctx) 24 | if var_1 == nil { 25 | var_1 = templ.NopComponent 26 | } 27 | ctx = templ.ClearChildren(ctx) 28 | // Element (standard) 29 | _, err = templBuffer.WriteString("") 30 | if err != nil { 31 | return err 32 | } 33 | // Element (standard) 34 | _, err = templBuffer.WriteString("") 35 | if err != nil { 36 | return err 37 | } 38 | // Element (void) 39 | _, err = templBuffer.WriteString("") 53 | if err != nil { 54 | return err 55 | } 56 | // RawElement 57 | _, err = templBuffer.WriteString("") 74 | if err != nil { 75 | return err 76 | } 77 | // Element (void) 78 | _, err = templBuffer.WriteString("") 92 | if err != nil { 93 | return err 94 | } 95 | // Element (standard) 96 | _, err = templBuffer.WriteString("") 97 | if err != nil { 98 | return err 99 | } 100 | // Text 101 | var_3 := `Go htmx examples - ` 102 | _, err = templBuffer.WriteString(var_3) 103 | if err != nil { 104 | return err 105 | } 106 | // StringExpression 107 | var var_4 string = title 108 | _, err = templBuffer.WriteString(templ.EscapeString(var_4)) 109 | if err != nil { 110 | return err 111 | } 112 | _, err = templBuffer.WriteString("") 113 | if err != nil { 114 | return err 115 | } 116 | // RawElement 117 | _, err = templBuffer.WriteString("") 127 | if err != nil { 128 | return err 129 | } 130 | // Text 131 | var_5 := `` 132 | _, err = templBuffer.WriteString(var_5) 133 | if err != nil { 134 | return err 135 | } 136 | _, err = templBuffer.WriteString("") 137 | if err != nil { 138 | return err 139 | } 140 | // If 141 | if os.Getenv("DEBUG") == "true" { 142 | // RawElement 143 | _, err = templBuffer.WriteString("") 163 | if err != nil { 164 | return err 165 | } 166 | } 167 | _, err = templBuffer.WriteString("") 168 | if err != nil { 169 | return err 170 | } 171 | // Element (standard) 172 | _, err = templBuffer.WriteString("") 173 | if err != nil { 174 | return err 175 | } 176 | // TemplElement 177 | err = Nav().Render(ctx, templBuffer) 178 | if err != nil { 179 | return err 180 | } 181 | // Element (standard) 182 | _, err = templBuffer.WriteString("") 196 | if err != nil { 197 | return err 198 | } 199 | // Children 200 | err = var_1.Render(ctx, templBuffer) 201 | if err != nil { 202 | return err 203 | } 204 | _, err = templBuffer.WriteString("") 205 | if err != nil { 206 | return err 207 | } 208 | // RawElement 209 | _, err = templBuffer.WriteString("") 219 | if err != nil { 220 | return err 221 | } 222 | // Text 223 | var_7 := `` 224 | _, err = templBuffer.WriteString(var_7) 225 | if err != nil { 226 | return err 227 | } 228 | _, err = templBuffer.WriteString("") 229 | if err != nil { 230 | return err 231 | } 232 | // RawElement 233 | _, err = templBuffer.WriteString("") 243 | if err != nil { 244 | return err 245 | } 246 | // Text 247 | var_8 := `` 248 | _, err = templBuffer.WriteString(var_8) 249 | if err != nil { 250 | return err 251 | } 252 | _, err = templBuffer.WriteString("") 253 | if err != nil { 254 | return err 255 | } 256 | _, err = templBuffer.WriteString("") 257 | if err != nil { 258 | return err 259 | } 260 | _, err = templBuffer.WriteString("") 261 | if err != nil { 262 | return err 263 | } 264 | if !templIsBuffer { 265 | _, err = io.Copy(w, templBuffer) 266 | } 267 | return err 268 | }) 269 | } 270 | 271 | func Nav() templ.Component { 272 | return templ.ComponentFunc(func(ctx context.Context, w io.Writer) (err error) { 273 | templBuffer, templIsBuffer := w.(*bytes.Buffer) 274 | if !templIsBuffer { 275 | templBuffer = templ.GetBuffer() 276 | defer templ.ReleaseBuffer(templBuffer) 277 | } 278 | ctx = templ.InitializeContext(ctx) 279 | var_9 := templ.GetChildren(ctx) 280 | if var_9 == nil { 281 | var_9 = templ.NopComponent 282 | } 283 | ctx = templ.ClearChildren(ctx) 284 | // Element (standard) 285 | _, err = templBuffer.WriteString("") 303 | if err != nil { 304 | return err 305 | } 306 | // Element (standard) 307 | _, err = templBuffer.WriteString("") 317 | if err != nil { 318 | return err 319 | } 320 | // Element (standard) 321 | _, err = templBuffer.WriteString("") 331 | if err != nil { 332 | return err 333 | } 334 | // Element (standard) 335 | _, err = templBuffer.WriteString("") 349 | if err != nil { 350 | return err 351 | } 352 | // Text 353 | var_10 := `Go HTMX Examples` 354 | _, err = templBuffer.WriteString(var_10) 355 | if err != nil { 356 | return err 357 | } 358 | _, err = templBuffer.WriteString("") 359 | if err != nil { 360 | return err 361 | } 362 | _, err = templBuffer.WriteString("") 363 | if err != nil { 364 | return err 365 | } 366 | _, err = templBuffer.WriteString("") 367 | if err != nil { 368 | return err 369 | } 370 | _, err = templBuffer.WriteString("") 371 | if err != nil { 372 | return err 373 | } 374 | if !templIsBuffer { 375 | _, err = io.Copy(w, templBuffer) 376 | } 377 | return err 378 | }) 379 | } 380 | 381 | -------------------------------------------------------------------------------- /shared/shared.go: -------------------------------------------------------------------------------- 1 | package shared 2 | 3 | import ( 4 | "bytes" 5 | "context" 6 | "io" 7 | 8 | "github.com/a-h/templ" 9 | "github.com/yosssi/gohtml" 10 | ) 11 | 12 | func Raw() templ.ComponentFunc { 13 | return func(ctx context.Context, w io.Writer) error { 14 | b := new(bytes.Buffer) 15 | if err := templ.GetChildren(ctx).Render(ctx, b); err != nil { 16 | return err 17 | } 18 | gohtml.Condense = true 19 | str := templ.EscapeString(gohtml.Format(b.String())) 20 | if _, err := w.Write([]byte(str)); err != nil { 21 | return err 22 | } 23 | return nil 24 | } 25 | } 26 | --------------------------------------------------------------------------------