Changed: DB Params
This commit is contained in:
54
templ/examples/blog/main.go
Normal file
54
templ/examples/blog/main.go
Normal file
@@ -0,0 +1,54 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"net/http"
|
||||
|
||||
"github.com/a-h/templ"
|
||||
)
|
||||
|
||||
func main() {
|
||||
// Use a template that doesn't take parameters.
|
||||
http.Handle("/", templ.Handler(home()))
|
||||
|
||||
// Use a template that accesses data or handles form posts.
|
||||
http.Handle("/posts", NewPostsHandler())
|
||||
|
||||
// Start the server.
|
||||
fmt.Println("listening on http://localhost:8000")
|
||||
if err := http.ListenAndServe("localhost:8000", nil); err != nil {
|
||||
log.Printf("error listening: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func NewPostsHandler() PostsHandler {
|
||||
// Replace this in-memory function with a call to a database.
|
||||
postsGetter := func() (posts []Post, err error) {
|
||||
return []Post{{Name: "templ", Author: "author"}}, nil
|
||||
}
|
||||
return PostsHandler{
|
||||
GetPosts: postsGetter,
|
||||
Log: log.Default(),
|
||||
}
|
||||
}
|
||||
|
||||
type PostsHandler struct {
|
||||
Log *log.Logger
|
||||
GetPosts func() ([]Post, error)
|
||||
}
|
||||
|
||||
func (ph PostsHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||
ps, err := ph.GetPosts()
|
||||
if err != nil {
|
||||
ph.Log.Printf("failed to get posts: %v", err)
|
||||
http.Error(w, "failed to retrieve posts", http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
templ.Handler(posts(ps)).ServeHTTP(w, r)
|
||||
}
|
||||
|
||||
type Post struct {
|
||||
Name string
|
||||
Author string
|
||||
}
|
64
templ/examples/blog/posts.templ
Normal file
64
templ/examples/blog/posts.templ
Normal file
@@ -0,0 +1,64 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
)
|
||||
|
||||
templ headerTemplate(name string) {
|
||||
<header data-testid="headerTemplate">
|
||||
<h1>{ name }</h1>
|
||||
</header>
|
||||
}
|
||||
|
||||
templ footerTemplate() {
|
||||
<footer data-testid="footerTemplate">
|
||||
<div>© { fmt.Sprintf("%d", time.Now().Year()) }</div>
|
||||
</footer>
|
||||
}
|
||||
|
||||
templ navTemplate() {
|
||||
<nav data-testid="navTemplate">
|
||||
<ul>
|
||||
<li><a href="/">Home</a></li>
|
||||
<li><a href="/posts">Posts</a></li>
|
||||
</ul>
|
||||
</nav>
|
||||
}
|
||||
|
||||
templ layout(name string) {
|
||||
<html>
|
||||
<head><title>{ name }</title></head>
|
||||
<body>
|
||||
@headerTemplate(name)
|
||||
@navTemplate()
|
||||
<main>
|
||||
{ children... }
|
||||
</main>
|
||||
</body>
|
||||
@footerTemplate()
|
||||
</html>
|
||||
}
|
||||
|
||||
templ postsTemplate(posts []Post) {
|
||||
<div data-testid="postsTemplate">
|
||||
for _, p := range posts {
|
||||
<div data-testid="postsTemplatePost">
|
||||
<div data-testid="postsTemplatePostName">{ p.Name }</div>
|
||||
<div data-testid="postsTemplatePostAuthor">{ p.Author }</div>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
}
|
||||
|
||||
templ home() {
|
||||
@layout("Home") {
|
||||
<div data-testid="homeTemplate">Welcome to my website.</div>
|
||||
}
|
||||
}
|
||||
|
||||
templ posts(posts []Post) {
|
||||
@layout("Posts") {
|
||||
@postsTemplate(posts)
|
||||
}
|
||||
}
|
358
templ/examples/blog/posts_templ.go
Normal file
358
templ/examples/blog/posts_templ.go
Normal file
@@ -0,0 +1,358 @@
|
||||
// Code generated by templ - DO NOT EDIT.
|
||||
|
||||
// templ: version: v0.3.833
|
||||
package main
|
||||
|
||||
//lint:file-ignore SA4006 This context is only used if a nested component is present.
|
||||
|
||||
import "github.com/a-h/templ"
|
||||
import templruntime "github.com/a-h/templ/runtime"
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
)
|
||||
|
||||
func headerTemplate(name string) templ.Component {
|
||||
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
|
||||
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
|
||||
if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
|
||||
return templ_7745c5c3_CtxErr
|
||||
}
|
||||
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
|
||||
if !templ_7745c5c3_IsBuffer {
|
||||
defer func() {
|
||||
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err == nil {
|
||||
templ_7745c5c3_Err = templ_7745c5c3_BufErr
|
||||
}
|
||||
}()
|
||||
}
|
||||
ctx = templ.InitializeContext(ctx)
|
||||
templ_7745c5c3_Var1 := templ.GetChildren(ctx)
|
||||
if templ_7745c5c3_Var1 == nil {
|
||||
templ_7745c5c3_Var1 = templ.NopComponent
|
||||
}
|
||||
ctx = templ.ClearChildren(ctx)
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, "<header data-testid=\"headerTemplate\"><h1>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var2 string
|
||||
templ_7745c5c3_Var2, templ_7745c5c3_Err = templ.JoinStringErrs(name)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `templ/examples/blog/posts.templ`, Line: 10, Col: 12}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var2))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, "</h1></header>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
func footerTemplate() templ.Component {
|
||||
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
|
||||
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
|
||||
if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
|
||||
return templ_7745c5c3_CtxErr
|
||||
}
|
||||
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
|
||||
if !templ_7745c5c3_IsBuffer {
|
||||
defer func() {
|
||||
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err == nil {
|
||||
templ_7745c5c3_Err = templ_7745c5c3_BufErr
|
||||
}
|
||||
}()
|
||||
}
|
||||
ctx = templ.InitializeContext(ctx)
|
||||
templ_7745c5c3_Var3 := templ.GetChildren(ctx)
|
||||
if templ_7745c5c3_Var3 == nil {
|
||||
templ_7745c5c3_Var3 = templ.NopComponent
|
||||
}
|
||||
ctx = templ.ClearChildren(ctx)
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 3, "<footer data-testid=\"footerTemplate\"><div>© ")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var4 string
|
||||
templ_7745c5c3_Var4, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("%d", time.Now().Year()))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `templ/examples/blog/posts.templ`, Line: 16, Col: 52}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var4))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 4, "</div></footer>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
func navTemplate() templ.Component {
|
||||
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
|
||||
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
|
||||
if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
|
||||
return templ_7745c5c3_CtxErr
|
||||
}
|
||||
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
|
||||
if !templ_7745c5c3_IsBuffer {
|
||||
defer func() {
|
||||
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err == nil {
|
||||
templ_7745c5c3_Err = templ_7745c5c3_BufErr
|
||||
}
|
||||
}()
|
||||
}
|
||||
ctx = templ.InitializeContext(ctx)
|
||||
templ_7745c5c3_Var5 := templ.GetChildren(ctx)
|
||||
if templ_7745c5c3_Var5 == nil {
|
||||
templ_7745c5c3_Var5 = templ.NopComponent
|
||||
}
|
||||
ctx = templ.ClearChildren(ctx)
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 5, "<nav data-testid=\"navTemplate\"><ul><li><a href=\"/\">Home</a></li><li><a href=\"/posts\">Posts</a></li></ul></nav>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
func layout(name string) templ.Component {
|
||||
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
|
||||
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
|
||||
if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
|
||||
return templ_7745c5c3_CtxErr
|
||||
}
|
||||
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
|
||||
if !templ_7745c5c3_IsBuffer {
|
||||
defer func() {
|
||||
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err == nil {
|
||||
templ_7745c5c3_Err = templ_7745c5c3_BufErr
|
||||
}
|
||||
}()
|
||||
}
|
||||
ctx = templ.InitializeContext(ctx)
|
||||
templ_7745c5c3_Var6 := templ.GetChildren(ctx)
|
||||
if templ_7745c5c3_Var6 == nil {
|
||||
templ_7745c5c3_Var6 = templ.NopComponent
|
||||
}
|
||||
ctx = templ.ClearChildren(ctx)
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 6, "<html><head><title>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var7 string
|
||||
templ_7745c5c3_Var7, templ_7745c5c3_Err = templ.JoinStringErrs(name)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `templ/examples/blog/posts.templ`, Line: 31, Col: 21}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var7))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 7, "</title></head><body>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = headerTemplate(name).Render(ctx, templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = navTemplate().Render(ctx, templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 8, "<main>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templ_7745c5c3_Var6.Render(ctx, templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 9, "</main></body>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = footerTemplate().Render(ctx, templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 10, "</html>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
func postsTemplate(posts []Post) templ.Component {
|
||||
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
|
||||
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
|
||||
if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
|
||||
return templ_7745c5c3_CtxErr
|
||||
}
|
||||
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
|
||||
if !templ_7745c5c3_IsBuffer {
|
||||
defer func() {
|
||||
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err == nil {
|
||||
templ_7745c5c3_Err = templ_7745c5c3_BufErr
|
||||
}
|
||||
}()
|
||||
}
|
||||
ctx = templ.InitializeContext(ctx)
|
||||
templ_7745c5c3_Var8 := templ.GetChildren(ctx)
|
||||
if templ_7745c5c3_Var8 == nil {
|
||||
templ_7745c5c3_Var8 = templ.NopComponent
|
||||
}
|
||||
ctx = templ.ClearChildren(ctx)
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 11, "<div data-testid=\"postsTemplate\">")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
for _, p := range posts {
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 12, "<div data-testid=\"postsTemplatePost\"><div data-testid=\"postsTemplatePostName\">")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var9 string
|
||||
templ_7745c5c3_Var9, templ_7745c5c3_Err = templ.JoinStringErrs(p.Name)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `templ/examples/blog/posts.templ`, Line: 47, Col: 53}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var9))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 13, "</div><div data-testid=\"postsTemplatePostAuthor\">")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var10 string
|
||||
templ_7745c5c3_Var10, templ_7745c5c3_Err = templ.JoinStringErrs(p.Author)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `templ/examples/blog/posts.templ`, Line: 48, Col: 57}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var10))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 14, "</div></div>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 15, "</div>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
func home() templ.Component {
|
||||
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
|
||||
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
|
||||
if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
|
||||
return templ_7745c5c3_CtxErr
|
||||
}
|
||||
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
|
||||
if !templ_7745c5c3_IsBuffer {
|
||||
defer func() {
|
||||
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err == nil {
|
||||
templ_7745c5c3_Err = templ_7745c5c3_BufErr
|
||||
}
|
||||
}()
|
||||
}
|
||||
ctx = templ.InitializeContext(ctx)
|
||||
templ_7745c5c3_Var11 := templ.GetChildren(ctx)
|
||||
if templ_7745c5c3_Var11 == nil {
|
||||
templ_7745c5c3_Var11 = templ.NopComponent
|
||||
}
|
||||
ctx = templ.ClearChildren(ctx)
|
||||
templ_7745c5c3_Var12 := templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
|
||||
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
|
||||
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
|
||||
if !templ_7745c5c3_IsBuffer {
|
||||
defer func() {
|
||||
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err == nil {
|
||||
templ_7745c5c3_Err = templ_7745c5c3_BufErr
|
||||
}
|
||||
}()
|
||||
}
|
||||
ctx = templ.InitializeContext(ctx)
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 16, "<div data-testid=\"homeTemplate\">Welcome to my website.</div>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
return nil
|
||||
})
|
||||
templ_7745c5c3_Err = layout("Home").Render(templ.WithChildren(ctx, templ_7745c5c3_Var12), templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
func posts(posts []Post) templ.Component {
|
||||
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
|
||||
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
|
||||
if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
|
||||
return templ_7745c5c3_CtxErr
|
||||
}
|
||||
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
|
||||
if !templ_7745c5c3_IsBuffer {
|
||||
defer func() {
|
||||
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err == nil {
|
||||
templ_7745c5c3_Err = templ_7745c5c3_BufErr
|
||||
}
|
||||
}()
|
||||
}
|
||||
ctx = templ.InitializeContext(ctx)
|
||||
templ_7745c5c3_Var13 := templ.GetChildren(ctx)
|
||||
if templ_7745c5c3_Var13 == nil {
|
||||
templ_7745c5c3_Var13 = templ.NopComponent
|
||||
}
|
||||
ctx = templ.ClearChildren(ctx)
|
||||
templ_7745c5c3_Var14 := templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
|
||||
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
|
||||
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
|
||||
if !templ_7745c5c3_IsBuffer {
|
||||
defer func() {
|
||||
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err == nil {
|
||||
templ_7745c5c3_Err = templ_7745c5c3_BufErr
|
||||
}
|
||||
}()
|
||||
}
|
||||
ctx = templ.InitializeContext(ctx)
|
||||
templ_7745c5c3_Err = postsTemplate(posts).Render(ctx, templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
return nil
|
||||
})
|
||||
templ_7745c5c3_Err = layout("Posts").Render(templ.WithChildren(ctx, templ_7745c5c3_Var14), templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
var _ = templruntime.GeneratedTemplate
|
210
templ/examples/blog/posts_test.go
Normal file
210
templ/examples/blog/posts_test.go
Normal file
@@ -0,0 +1,210 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"log"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/PuerkitoBio/goquery"
|
||||
)
|
||||
|
||||
func TestHeader(t *testing.T) {
|
||||
// Pipe the rendered template into goquery.
|
||||
r, w := io.Pipe()
|
||||
go func() {
|
||||
_ = headerTemplate("Posts").Render(context.Background(), w)
|
||||
_ = w.Close()
|
||||
}()
|
||||
doc, err := goquery.NewDocumentFromReader(r)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to read template: %v", err)
|
||||
}
|
||||
// Expect the component to include a testid.
|
||||
if doc.Find(`[data-testid="headerTemplate"]`).Length() == 0 {
|
||||
t.Error("expected data-testid attribute to be rendered, but it wasn't")
|
||||
}
|
||||
// Expect the page name to be set correctly.
|
||||
expectedPageName := "Posts"
|
||||
if actualPageName := doc.Find("h1").Text(); actualPageName != expectedPageName {
|
||||
t.Errorf("expected page name %q, got %q", expectedPageName, actualPageName)
|
||||
}
|
||||
}
|
||||
|
||||
func TestFooter(t *testing.T) {
|
||||
// Pipe the rendered template into goquery.
|
||||
r, w := io.Pipe()
|
||||
go func() {
|
||||
_ = footerTemplate().Render(context.Background(), w)
|
||||
_ = w.Close()
|
||||
}()
|
||||
doc, err := goquery.NewDocumentFromReader(r)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to read template: %v", err)
|
||||
}
|
||||
// Expect the component to include a testid.
|
||||
if doc.Find(`[data-testid="footerTemplate"]`).Length() == 0 {
|
||||
t.Error("expected data-testid attribute to be rendered, but it wasn't")
|
||||
}
|
||||
// Expect the copyright notice to include the current year.
|
||||
expectedCopyrightNotice := fmt.Sprintf("© %d", time.Now().Year())
|
||||
if actualCopyrightNotice := doc.Find("div").Text(); actualCopyrightNotice != expectedCopyrightNotice {
|
||||
t.Errorf("expected copyright notice %q, got %q", expectedCopyrightNotice, actualCopyrightNotice)
|
||||
}
|
||||
}
|
||||
|
||||
func TestNav(t *testing.T) {
|
||||
r, w := io.Pipe()
|
||||
go func() {
|
||||
_ = navTemplate().Render(context.Background(), w)
|
||||
_ = w.Close()
|
||||
}()
|
||||
doc, err := goquery.NewDocumentFromReader(r)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to read template: %v", err)
|
||||
}
|
||||
// Expect the component to include a testid.
|
||||
if doc.Find(`[data-testid="navTemplate"]`).Length() == 0 {
|
||||
t.Error("expected data-testid attribute to be rendered, but it wasn't")
|
||||
}
|
||||
}
|
||||
|
||||
func TestHome(t *testing.T) {
|
||||
r, w := io.Pipe()
|
||||
go func() {
|
||||
_ = home().Render(context.Background(), w)
|
||||
_ = w.Close()
|
||||
}()
|
||||
doc, err := goquery.NewDocumentFromReader(r)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to read template: %v", err)
|
||||
}
|
||||
// Expect the page title to be set correctly.
|
||||
expectedTitle := "Home"
|
||||
if actualTitle := doc.Find("title").Text(); actualTitle != expectedTitle {
|
||||
t.Errorf("expected title name %q, got %q", expectedTitle, actualTitle)
|
||||
}
|
||||
// Expect the header to be rendered.
|
||||
if doc.Find(`[data-testid="headerTemplate"]`).Length() == 0 {
|
||||
t.Error("expected data-testid attribute to be rendered, but it wasn't")
|
||||
}
|
||||
// Expect the navigation to be rendered.
|
||||
if doc.Find(`[data-testid="navTemplate"]`).Length() == 0 {
|
||||
t.Error("expected nav to be rendered, but it wasn't")
|
||||
}
|
||||
// Expect the home template be rendered.
|
||||
if doc.Find(`[data-testid="homeTemplate"]`).Length() == 0 {
|
||||
t.Error("expected homeTemplate to be rendered, but it wasn't")
|
||||
}
|
||||
}
|
||||
|
||||
func TestPosts(t *testing.T) {
|
||||
testPosts := []Post{
|
||||
{Name: "Name1", Author: "Author1"},
|
||||
{Name: "Name2", Author: "Author2"},
|
||||
}
|
||||
r, w := io.Pipe()
|
||||
go func() {
|
||||
_ = posts(testPosts).Render(context.Background(), w)
|
||||
_ = w.Close()
|
||||
}()
|
||||
doc, err := goquery.NewDocumentFromReader(r)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to read template: %v", err)
|
||||
}
|
||||
// Assert.
|
||||
// Expect the page title to be set correctly.
|
||||
expectedTitle := "Posts"
|
||||
if actualTitle := doc.Find("title").Text(); actualTitle != expectedTitle {
|
||||
t.Errorf("expected title name %q, got %q", expectedTitle, actualTitle)
|
||||
}
|
||||
// Expect the header to be rendered.
|
||||
if doc.Find(`[data-testid="headerTemplate"]`).Length() == 0 {
|
||||
t.Error("expected data-testid attribute to be rendered, but it wasn't")
|
||||
}
|
||||
// Expect the navigation to be rendered.
|
||||
if doc.Find(`[data-testid="navTemplate"]`).Length() == 0 {
|
||||
t.Error("expected nav to be rendered, but it wasn't")
|
||||
}
|
||||
// Expect the posts to be rendered.
|
||||
if doc.Find(`[data-testid="postsTemplate"]`).Length() == 0 {
|
||||
t.Error("expected posts to be rendered, but it wasn't")
|
||||
}
|
||||
// Expect both posts to be rendered.
|
||||
if actualPostCount := doc.Find(`[data-testid="postsTemplatePost"]`).Length(); actualPostCount != len(testPosts) {
|
||||
t.Fatalf("expected %d posts to be rendered, found %d", len(testPosts), actualPostCount)
|
||||
}
|
||||
// Expect the posts to contain the author name.
|
||||
doc.Find(`[data-testid="postsTemplatePost"]`).Each(func(index int, sel *goquery.Selection) {
|
||||
expectedName := testPosts[index].Name
|
||||
if actualName := sel.Find(`[data-testid="postsTemplatePostName"]`).Text(); actualName != expectedName {
|
||||
t.Errorf("expected name %q, got %q", actualName, expectedName)
|
||||
}
|
||||
expectedAuthor := testPosts[index].Author
|
||||
if actualAuthor := sel.Find(`[data-testid="postsTemplatePostAuthor"]`).Text(); actualAuthor != expectedAuthor {
|
||||
t.Errorf("expected author %q, got %q", actualAuthor, expectedAuthor)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func TestPostsHandler(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
postGetter func() (posts []Post, err error)
|
||||
expectedStatus int
|
||||
assert func(doc *goquery.Document)
|
||||
}{
|
||||
{
|
||||
name: "database errors result in a 500 error",
|
||||
postGetter: func() (posts []Post, err error) {
|
||||
return nil, errors.New("database error")
|
||||
},
|
||||
expectedStatus: http.StatusInternalServerError,
|
||||
assert: func(doc *goquery.Document) {
|
||||
expected := "failed to retrieve posts\n"
|
||||
if actual := doc.Text(); actual != expected {
|
||||
t.Errorf("expected error message %q, got %q", expected, actual)
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "database success renders the posts",
|
||||
postGetter: func() (posts []Post, err error) {
|
||||
return []Post{
|
||||
{Name: "Name1", Author: "Author1"},
|
||||
{Name: "Name2", Author: "Author2"},
|
||||
}, nil
|
||||
},
|
||||
expectedStatus: http.StatusInternalServerError,
|
||||
assert: func(doc *goquery.Document) {
|
||||
if doc.Find(`[data-testid="postsTemplate"]`).Length() == 0 {
|
||||
t.Error("expected posts to be rendered, but it wasn't")
|
||||
}
|
||||
},
|
||||
},
|
||||
}
|
||||
for _, test := range tests {
|
||||
// Arrange.
|
||||
w := httptest.NewRecorder()
|
||||
r := httptest.NewRequest(http.MethodGet, "/posts", nil)
|
||||
|
||||
ph := NewPostsHandler()
|
||||
ph.Log = log.New(io.Discard, "", 0) // Suppress logging.
|
||||
ph.GetPosts = test.postGetter
|
||||
|
||||
// Act.
|
||||
ph.ServeHTTP(w, r)
|
||||
doc, err := goquery.NewDocumentFromReader(w.Result().Body)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to read template: %v", err)
|
||||
}
|
||||
|
||||
// Assert.
|
||||
test.assert(doc)
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user