From 52439ee836c80d0cdcda411e12f84eee75fd7dab Mon Sep 17 00:00:00 2001 From: "Alexander \"Arav\" Andreev" Date: Thu, 13 Jun 2024 04:49:55 +0400 Subject: [PATCH] Moving to a Templ template engine stage 1. --- .gitignore | 1 + Makefile | 8 +++- go.mod | 5 +- go.sum | 5 +- internal/http/web_handlers.go | 9 ++-- web/base.templ | 59 +++++++++++++++++++++++ web/errorXXX.templ | 26 +++++++++++ web/guestbook.templ | 88 +++++++++++++++++++++++++++++++++++ web/index.templ | 67 ++++++++++++++++++++++++++ web/rss.templ | 38 +++++++++++++++ 10 files changed, 299 insertions(+), 7 deletions(-) create mode 100644 web/base.templ create mode 100644 web/errorXXX.templ create mode 100644 web/guestbook.templ create mode 100644 web/index.templ create mode 100644 web/rss.templ diff --git a/.gitignore b/.gitignore index e8a308b..d079956 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,6 @@ .vscode *.pug.go +*_templ.go bin/dwelling-home *.sqlite *.sqlite* diff --git a/Makefile b/Makefile index e106f2c..5906cb2 100755 --- a/Makefile +++ b/Makefile @@ -12,7 +12,7 @@ LDFLAGS=-ldflags "-s -w -X main.version=${VERSION}" -tags osusergo,netgo .PHONY: run install uninstall clean -${TARGET}: web/*.pug.go +${TARGET}: web/*_templ.go go build -o bin/$@ ${LDFLAGS} ${FLAGS} cmd/$@/main.go web/*.pug.go: web/templates/*.pug @@ -21,6 +21,12 @@ ifeq (,$(wildcard $(shell go env GOPATH)/bin/jade)) endif go generate web/web.go +web/*_templ.go: web/*.templ +ifeq (,$(wildcard $(shell go env GOPATH)/bin/templ)) + go install github.com/a-h/templ/cmd/templ@latest +endif + TEMPL_EXPERIMENT=rawgo $(shell go env GOPATH)/bin/templ generate + run: bin/${TARGET} -listen 127.0.0.1:18123 -database-path . -captcha-expiry 10m \ -guestbook-page-size 10 diff --git a/go.mod b/go.mod index c814399..05080dd 100644 --- a/go.mod +++ b/go.mod @@ -1,10 +1,13 @@ module git.arav.su/Arav/dwelling-home -go 1.17 +go 1.21 + +toolchain go1.22.4 require ( git.arav.su/Arav/justcaptcha/v2 v2.1.0 git.arav.su/Arav/justguestbook v1.3.2 + github.com/a-h/templ v0.2.707 github.com/gomarkdown/markdown v0.0.0-20230922112808-5421fefb8386 github.com/pkg/errors v0.9.1 ) diff --git a/go.sum b/go.sum index b7c62a2..9fba1ff 100644 --- a/go.sum +++ b/go.sum @@ -4,12 +4,16 @@ git.arav.su/Arav/justcaptcha/v2 v2.1.0 h1:EFerW2mP60rDczu1mPbJb7DiDeAQOcw83/KiWc git.arav.su/Arav/justcaptcha/v2 v2.1.0/go.mod h1:Ntab6TUAqCo/H9LSWOd4IQ9ANnp8G1PEygXtORcdTOY= git.arav.su/Arav/justguestbook v1.3.2 h1:B1AzS14dW3bVlp0Qj6pu1PrJlWaPK1mplmx3UNBcxo4= git.arav.su/Arav/justguestbook v1.3.2/go.mod h1:Umo/AzSOKu+OU+03V7/QQ6m6N0nXyeRAGOZT4P5ol98= +github.com/a-h/templ v0.2.707 h1:T1Gkd2ugbRglZ9rYw/VBchWOSZVKmetDbBkm4YubM7U= +github.com/a-h/templ v0.2.707/go.mod h1:5cqsugkq9IerRNucNsI4DEamdHPsoGMQy99DzydLhM8= github.com/fogleman/gg v1.3.0 h1:/7zJX8F6AaYQc57WQCyN9cAIz+4bCJGO9B+dyW29am8= github.com/fogleman/gg v1.3.0/go.mod h1:R/bRT+9gY/C5z7JzPU0zXsXHKM4/ayA+zqcVNZzPa1k= github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 h1:DACJavvAHhabrF08vX0COfcOBJRhZ8lUbR+ZWIs0Y5g= github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGwJL78qG/PmXZO1EjYhfJinVAhrmmHX6Z8B9k= github.com/gomarkdown/markdown v0.0.0-20230922112808-5421fefb8386 h1:EcQR3gusLHN46TAD+G+EbaaqJArt5vHhNpXAa12PQf4= github.com/gomarkdown/markdown v0.0.0-20230922112808-5421fefb8386/go.mod h1:JDGcbDT52eL4fju3sZ4TeHGsQwhG9nbDV21aMyhwPoA= +github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= +github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/mattn/go-sqlite3 v1.14.16/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg= github.com/mattn/go-sqlite3 v1.14.18 h1:JL0eqdCOq6DJVNPSvArO/bIV9/P7fbGrV00LZHc+5aI= github.com/mattn/go-sqlite3 v1.14.18/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg= @@ -44,7 +48,6 @@ golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.12.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= -golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= diff --git a/internal/http/web_handlers.go b/internal/http/web_handlers.go index ac3e5fe..a829fba 100644 --- a/internal/http/web_handlers.go +++ b/internal/http/web_handlers.go @@ -1,6 +1,7 @@ package http import ( + "context" "log" "math" "net/http" @@ -36,7 +37,7 @@ func NewHandlers(captchaExpire time.Duration, owner string, gbPageSize int64, } func (h *Handlers) Index(w http.ResponseWriter, r *http.Request) { - web.Index("", w) + web.Index().Render(context.Background(), w) } func (h *Handlers) Privacy(w http.ResponseWriter, r *http.Request) { @@ -146,7 +147,7 @@ func (h *Handlers) Guestbook(w http.ResponseWriter, r *http.Request) { dwc := dwcaptcha.NewDwellingCaptcha(h.captchaExpire) _, id := inmemdb.New(r.RemoteAddr, dwc) - web.Guestbook("/ Guestbook", h.owner, string(id), pageCount, entries, r, w) + web.Guestbook(string(id), h.owner, entries, pageCount, r).Render(context.Background(), w) } func (h *Handlers) GuestbookAdmin(w http.ResponseWriter, r *http.Request) { @@ -174,7 +175,7 @@ func (h *Handlers) RSS(w http.ResponseWriter, r *http.Request) { scheme = "http" } - web.RSS(scheme+"://"+r.Host, h.owner, posts, r, w) + web.RSS(scheme+"://"+r.Host, h.owner, posts, r).Render(context.Background(), w) } func ServeAsset(path string) func(http.ResponseWriter, *http.Request) { @@ -186,7 +187,7 @@ func ServeAsset(path string) func(http.ResponseWriter, *http.Request) { func Error(w http.ResponseWriter, code int, reason, message, referer string) { w.WriteHeader(code) - web.ErrorXXX("/ "+http.StatusText(code), reason, message, referer, code, w) + web.ErrorXXX(code, reason, message, referer).Render(context.Background(), w) } func cleanupNewlines(text string) (out string) { diff --git a/web/base.templ b/web/base.templ new file mode 100644 index 0000000..4ca3133 --- /dev/null +++ b/web/base.templ @@ -0,0 +1,59 @@ +package web + +import "strings" + +templ base(title, description, keywords, canonical, heading string, head templ.Component) { + + + + if title != "" { + { title } - Arav's dwelling + } else { + Arav's dwelling + } + + + + + + + + + + + @head + + +
+ + +
+ { children... } + + + +} + +var navElements = []string{"Stuff", "Mindflow", "About", "Guestbook"} + +templ navigation(heading string) { + for _, n := range navElements { + if n == heading { + continue + } + { n } + } + + if heading != "" { +

{ heading }

+ } +} \ No newline at end of file diff --git a/web/errorXXX.templ b/web/errorXXX.templ new file mode 100644 index 0000000..c6d16aa --- /dev/null +++ b/web/errorXXX.templ @@ -0,0 +1,26 @@ +package web + +import "fmt" +import "net/http" + +templ ErrorXXX(errCode int, reason, message, referer string) { + {{ errText := http.StatusText(errCode) }} + @base(errText, errText, + "", "", errText, nil) { +
+

{ fmt.Sprint(errCode) }

+ { errText } + if reason != "" { +

{ reason }

+ } + if message != "" { +

{ message }

+ } +
+ if referer != "" { +
+

Go back

+
+ } +} +} \ No newline at end of file diff --git a/web/guestbook.templ b/web/guestbook.templ new file mode 100644 index 0000000..5ef9c37 --- /dev/null +++ b/web/guestbook.templ @@ -0,0 +1,88 @@ +package web + +import "fmt" +import "strconv" +import "strings" +import "net/http" + +import "git.arav.su/Arav/justguestbook" + +import "git.arav.su/Arav/dwelling-home/pkg/util" + +templ Guestbook(captchaID, owner string, entries []*justguestbook.Entry, pageCount int64, r *http.Request) { +@base("Guestbook", + "This is my guestbook. Welcome.", + "guestbook, personal", "/guestbook", "Guestbook", guestbookHead()) { +
+ + + + + + +
+ Use > to make a quote. +
+ + + CAPTCHA + + Valid for 10 minutes. + + +
+
+ for _, entry := range entries { +
+
+ {{ created_tz := util.ToClientTimezone(entry.Created, r).Format("Monday _2 January 2006 15:04:05 -07:00") }} + {{ website := "" }} + if !entry.HideWebsite { + {{ website = entry.Website }} + } + { strconv.FormatInt(entry.ID, 10) } by { entry.Name } { website } on +
+ for _, line := range strings.Split(entry.Message, "\n") { + if len(line) > 0 && line[0] == '>' { +

{ line }

+ } else { +

{ line }

+ } + } + if entry.Reply != nil { +
+
+ {{ reply_created_tz := util.ToClientTimezone(entry.Reply.Created, r).Format("Monday _2 January 2006 15:04:05 -07:00") }} + Reply by { owner } in +
+ for _, line := range strings.Split(entry.Reply.Message, "\n") { + if len(line) > 0 && line[0] == '>' { +

{ line }

+ } else { +

{ line }

+ } + } +
+ } +
+ } + if len(entries) == 0 { +

No posts.

+ } +
+ if pageCount > 1 { +
+ {{ var n int64 = 1 }} + for ; n <= pageCount; n++ { + {{ strN := strconv.FormatInt(n, 10) }} + + +} \ No newline at end of file diff --git a/web/index.templ b/web/index.templ new file mode 100644 index 0000000..ebc5d00 --- /dev/null +++ b/web/index.templ @@ -0,0 +1,67 @@ +package web + +templ Index() { +@base("", + "A homepage of a russian guy Alexander aka Arav. Not just homepage, but something more...", "/", + "homepage, personal, blog, services, self-hosting", "", nil) { +
+ + arav.su + . + onion + . + ygg + . + i2p + ah + + arav.neocities.org +
+ + radio + . + onion + . + ygg + . + i2p + ah + + + files + . + onion + . + ygg + . + i2p + ah + + + upload + . + onion + . + ygg + . + i2p + ah + + + git + . + onion + . + ygg + . + i2p + ah + +
+
+

+ Welcome, Anon. I'm Alexander aka Arav, I self-host some services for myself, friends and you. Not much I have to offer, but maybe you'll find something useful for yourself. :) +

+
+ } +} \ No newline at end of file diff --git a/web/rss.templ b/web/rss.templ new file mode 100644 index 0000000..2849cb0 --- /dev/null +++ b/web/rss.templ @@ -0,0 +1,38 @@ +package web + +import "time" +import "strings" +import "net/http" + +import "git.arav.su/Arav/dwelling-home/pkg/mindflow" +import "git.arav.su/Arav/dwelling-home/pkg/util" + +templ RSS(host, author string, posts []mindflow.Post, r *http.Request) { +@templ.Raw("") + + + Arav's dwelling + What's going on with me and my machines. + en-gb + { host } + + for _, post := range posts { + + { post.Title } + { post.Category.Name } + { post.PostID() } + { util.ToClientTimezone(post.Date, r).Format(time.RFC1123Z) } + { post.PostURL(r.Host, true) } + { author } + + @templ.Raw("{ line }

+ } + @templ.Raw("]]>") +
+
+ } +
+
+} \ No newline at end of file