initial commit - added base, need to fix templ errors

This commit is contained in:
2025-08-17 10:58:31 +00:00
commit 59d82ae563
20 changed files with 1512 additions and 0 deletions

11
templates/footer.templ Normal file
View File

@@ -0,0 +1,11 @@
package templates
templ Footer() {
<footer class="footer">
<p>
© 2025 Valentine Bott | Built with Go + Templ + HTMX |
<a href="https://git.valxntine.dev/valxntine/blog">Source Code</a> |
Last updated: <span class="blink">●</span> Now-ish
</p>
</footer>
}

40
templates/footer_templ.go Normal file
View File

@@ -0,0 +1,40 @@
// Code generated by templ - DO NOT EDIT.
// templ: version: v0.3.943
package templates
//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"
func Footer() 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, "<footer class=\"footer\"><p>© 2025 Valentine Bott | Built with Go + Templ + HTMX | <a href=\"https://git.valxntine.dev/valxntine/blog\">Source Code</a> | Last updated: <span class=\"blink\">●</span> Now-ish</p></footer>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
return nil
})
}
var _ = templruntime.GeneratedTemplate

8
templates/header.templ Normal file
View File

@@ -0,0 +1,8 @@
package templates
templ Header(title, subtitle string) {
<div class="header">
<h1>{ title }</h1>
<div class="subtitle">{ subtitle }</div>
</div>
}

66
templates/header_templ.go Normal file
View File

@@ -0,0 +1,66 @@
// Code generated by templ - DO NOT EDIT.
// templ: version: v0.3.943
package templates
//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"
func Header(title, subtitle 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, "<div class=\"header\"><h1>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var2 string
templ_7745c5c3_Var2, templ_7745c5c3_Err = templ.JoinStringErrs(title)
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/header.templ`, Line: 5, Col: 15}
}
_, 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><div class=\"subtitle\">")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var3 string
templ_7745c5c3_Var3, templ_7745c5c3_Err = templ.JoinStringErrs(subtitle)
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/header.templ`, Line: 6, Col: 36}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var3))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 3, "</div></div>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
return nil
})
}
var _ = templruntime.GeneratedTemplate

12
templates/home.templ Normal file
View File

@@ -0,0 +1,12 @@
package templates
templ HomePage(data models.Data) {
@Layout(data.Title) {
@Header(data.Title, data.Subtitle)
@Nav()
<main>
@PostList(data.Posts, data.CurrentPage, data.TotalPages)
</main>
@Footer()
}
}

82
templates/home_templ.go Normal file
View File

@@ -0,0 +1,82 @@
// Code generated by templ - DO NOT EDIT.
// templ: version: v0.3.943
package templates
//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"
func HomePage(data models.Data) 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_Var2 := 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 = Header(data.Title, data.Subtitle).Render(ctx, templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, " ")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = Nav().Render(ctx, templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, " <main>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = PostList(data.Posts, data.CurrentPage, data.TotalPages).Render(ctx, templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 3, "</main>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = Footer().Render(ctx, templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
return nil
})
templ_7745c5c3_Err = Layout(data.Title).Render(templ.WithChildren(ctx, templ_7745c5c3_Var2), templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
return nil
})
}
var _ = templruntime.GeneratedTemplate

25
templates/layout.templ Normal file
View File

@@ -0,0 +1,25 @@
package templates
templ Layout(title string) {
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<title>{ title }</title>
<script src="https://unpkg.com/htmx.org@1.9.6"></script>
</head>
<body>
{ children... }
<script>
document.body.addEventListener('htmx:beforeRequest', function(e) {
e.detail.elt.classList.add('loading');
});
document.body.addEventListener('htmx:afterRequest', function(e) {
e.detail.elt.classList.remove('loading');
});
</script>
</body>
</html>
}

61
templates/layout_templ.go Normal file
View File

@@ -0,0 +1,61 @@
// Code generated by templ - DO NOT EDIT.
// templ: version: v0.3.943
package templates
//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"
func Layout(title 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, "<!doctype html><html lang=\"en\"><head><meta charset=\"UTF-8\"><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\"><title>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var2 string
templ_7745c5c3_Var2, templ_7745c5c3_Err = templ.JoinStringErrs(title)
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/layout.templ`, Line: 9, Col: 18}
}
_, 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, "</title><script src=\"https://unpkg.com/htmx.org@1.9.6\"></script></head><body>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templ_7745c5c3_Var1.Render(ctx, templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 3, "<script>\n document.body.addEventListener('htmx:beforeRequest', function(e) {\n e.detail.elt.classList.add('loading');\n });\n\n document.body.addEventListener('htmx:afterRequest', function(e) {\n e.detail.elt.classList.remove('loading');\n });\n </script></body></html>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
return nil
})
}
var _ = templruntime.GeneratedTemplate

11
templates/nav.templ Normal file
View File

@@ -0,0 +1,11 @@
package templates
templ Nav() {
<nav class="nav">
<a href="/" hx-get="/" hx-target="main" hx-push-url="true">home</a>
<a href="/tags" hx-get="/tags" hx-target="main" hx-push-url="true">tags</a>
<a href="/about" hx-get="/about" hx-target="main" hx-push-url="true">about</a>
<a href="/archive" hx-get="/archive" hx-target="main" hx-push-url="true">archive</a>
<a href="mailto:valentine.bott@gmail.com">Contact Me</a>
</nav>
}

40
templates/nav_templ.go Normal file
View File

@@ -0,0 +1,40 @@
// Code generated by templ - DO NOT EDIT.
// templ: version: v0.3.943
package templates
//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"
func Nav() 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, "<nav class=\"nav\"><a href=\"/\" hx-get=\"/\" hx-target=\"main\" hx-push-url=\"true\">home</a> <a href=\"/tags\" hx-get=\"/tags\" hx-target=\"main\" hx-push-url=\"true\">tags</a> <a href=\"/about\" hx-get=\"/about\" hx-target=\"main\" hx-push-url=\"true\">about</a> <a href=\"/archive\" hx-get=\"/archive\" hx-target=\"main\" hx-push-url=\"true\">archive</a> <a href=\"mailto:valentine.bott@gmail.com\">Contact Me</a></nav>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
return nil
})
}
var _ = templruntime.GeneratedTemplate

View File

@@ -0,0 +1,29 @@
package templates
import "fmt"
templ Pagination(currentPage, totalPages int) {
<div class="pagination">
if currentPage > 1 {
<a href={ templ.URL(fmt.Sprintf("/?page=%d", currentPage-1)) }
hx-get={ fmt.Sprintf("/?page=%d", currentPage-1) }
hx-target="#post-list"
hx-swap="outerHTML">
<- Previous
</a>
}
<span class="page-info">
Page { fmt.Sprintf("%d", currentPage) }
</span>
if currentPage < totalPages {
<a href={ templ.URL(fmt.Sprintf("/?page=%d", currentPage+1)) }
hx-get={ fmt.Sprintf("/?page=%d", currentPage+1) }
hx-target="#post-list"
hx-swap="outerHTML">
Next ->
</a>
}
</div>
}

29
templates/post.templ Normal file
View File

@@ -0,0 +1,29 @@
package templates
templ PostDetail(post models.Post) {
<article class="post-detail">
<h1 class="post-title">{ post.Title }</h1>
<div class="post-meta">
Published: { post.PublishedAt.Format("January 2, 2006") } |
Tags:
for i, tag := range post.Tags {
if i > 0 {
,
}
<a href={ templ.URL("/tags/" + tag) }>{ tag }</a>
}
| { fmt.Sprintf("%d", post.WordCount) } words
</div>
<div class="post-content">
{ templ.Raw(post.Content) }
</div>
<div class="post-footer">
<a href="/"
hx-get="/"
hx-target="main"
hx-push-url="true">
<- Back to Posts
</a>
</div>
</article>
}

57
templates/posts.templ Normal file
View File

@@ -0,0 +1,57 @@
package templates
import "time"
templ PostList(posts []models.Post, page, totalPages int) {
<div id="post-list">
<ul class="blog-posts">
for _, post := range posts {
@PostListItem(post)
}
</ul>
if totalPages > 1 {
@Pagination(page, totalPages)
}
</div>
}
templ PostListItem(post models.Post) {
<li class="blog-post">
<div class="post-title">
<a href={ templ.URL("/posts/" + post.Slug) }
hx-get={ "/posts/" + post.Slug }
hx-target="main"
hx-push-url="true">
{ post.Title }
</a>
</div>
<div class="post-meta">
Posted: { post.PublishedAt.Format("2006-01-02") } |
Tags:
for i, tag := range post.Tags {
if i > 0 {
,
}
<a href={ templ.URL("/tags/" + tag) }
hx-get={ "/tags/" + tag }
hx-target="main"
hx-push-url="true">
{ tag }
</a>
}
| Words: { fmt.Sprintf("%d", post.WordCount) }
</div>
<div class="post-excerpt">
{ post.Excerpt }
</div>
<div class="read-more">
<a href={ templ.URL("/posts/" + post.Slug) }
hx-get={ "/posts/" + post.Slug }
hx-target="main"
hx-push-url=true>
[Read more...]
</a>
</div>
</li>
}