feat: caching headers
This commit is contained in:
@@ -12,7 +12,7 @@ tmp_dir = "tmp"
|
||||
exclude_regex = ["_test.go", "_templ.go"]
|
||||
exclude_unchanged = false
|
||||
follow_symlink = false
|
||||
full_bin = ""
|
||||
full_bin = "dlv exec ./tmp/main --listen=127.0.0.1:2345 --headless=true --api-version=2 --accept-multiclient --continue --log --"
|
||||
include_dir = []
|
||||
include_ext = ["go", "tpl", "tmpl", "templ", "html", "css"]
|
||||
kill_delay = "0s"
|
||||
@@ -20,7 +20,6 @@ tmp_dir = "tmp"
|
||||
poll = false
|
||||
poll_interval = 0
|
||||
rerun = false
|
||||
rerun_delay = 500
|
||||
send_interrupt = false
|
||||
stop_on_error = true
|
||||
|
||||
@@ -28,6 +27,7 @@ tmp_dir = "tmp"
|
||||
enabled = true
|
||||
proxy_port = 8888
|
||||
app_port = 8080
|
||||
app_start_timeout = 50000000
|
||||
|
||||
[color]
|
||||
app = ""
|
||||
|
||||
Vendored
+8
@@ -9,6 +9,14 @@
|
||||
"program": "${workspaceFolder}/cmd/schreifuchs-ch/main.go",
|
||||
"cwd": "${workspaceFolder}",
|
||||
"showLog": true
|
||||
},
|
||||
{
|
||||
"name": "Attach to Air",
|
||||
"type": "go",
|
||||
"request": "attach",
|
||||
"mode": "remote",
|
||||
"port": 2345,
|
||||
"host": "127.0.0.1"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -13,9 +13,11 @@ require (
|
||||
github.com/cli/browser v1.3.0 // indirect
|
||||
github.com/fatih/color v1.16.0 // indirect
|
||||
github.com/fsnotify/fsnotify v1.7.0 // indirect
|
||||
github.com/klauspost/compress v1.18.4 // indirect
|
||||
github.com/mattn/go-colorable v0.1.13 // indirect
|
||||
github.com/mattn/go-isatty v0.0.20 // indirect
|
||||
github.com/natefinch/atomic v1.0.1 // indirect
|
||||
github.com/studio-b12/gowebdav v0.12.0 // indirect
|
||||
golang.org/x/mod v0.26.0 // indirect
|
||||
golang.org/x/net v0.42.0 // indirect
|
||||
golang.org/x/sync v0.16.0 // indirect
|
||||
|
||||
@@ -16,6 +16,8 @@ github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nos
|
||||
github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM=
|
||||
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/klauspost/compress v1.18.4 h1:RPhnKRAQ4Fh8zU2FY/6ZFDwTVTxgJ/EMydqSTzE9a2c=
|
||||
github.com/klauspost/compress v1.18.4/go.mod h1:R0h/fSBs8DE4ENlcrlib3PsXS61voFxhIs2DeRhCvJ4=
|
||||
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
|
||||
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
|
||||
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
|
||||
@@ -27,6 +29,8 @@ github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZb
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
|
||||
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
||||
github.com/studio-b12/gowebdav v0.12.0 h1:kFRtQECt8jmVAvA6RHBz3geXUGJHUZA6/IKpOVUs5kM=
|
||||
github.com/studio-b12/gowebdav v0.12.0/go.mod h1:bHA7t77X/QFExdeAnDzK6vKM34kEZAcE1OX4MfiwjkE=
|
||||
golang.org/x/mod v0.26.0 h1:EGMPT//Ezu+ylkCijjPc+f4Aih7sZvaAr+O3EHBxvZg=
|
||||
golang.org/x/mod v0.26.0/go.mod h1:/j6NAhSk8iQ723BGAUyoAcn7SlD7s15Dp9Nd/SfeaFQ=
|
||||
golang.org/x/net v0.42.0 h1:jzkYrhi3YQWD6MLBJcsklgQsoAcw89EcZbJw8Z614hs=
|
||||
|
||||
@@ -0,0 +1,47 @@
|
||||
package images
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"compress/flate"
|
||||
"encoding/base64"
|
||||
"io"
|
||||
)
|
||||
|
||||
func UIDFromPath(path string) (uid string, err error) {
|
||||
var b bytes.Buffer
|
||||
// NewWriter with NoDict (nil) creates a raw DEFLATE compressor
|
||||
zw, _ := flate.NewWriter(&b, flate.BestCompression)
|
||||
|
||||
_, err = zw.Write([]byte(path))
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
err = zw.Close() // Essential to flush the final bits
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
return base64.RawURLEncoding.EncodeToString(b.Bytes()), nil
|
||||
}
|
||||
|
||||
func PathFromUID(uid string) (string, error) {
|
||||
// 1. Decode the Base64 string back to compressed bytes
|
||||
compressedBytes, err := base64.RawURLEncoding.DecodeString(uid)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
// 2. Create a flate reader (NoDict/nil since you used nil in the writer)
|
||||
// flate.NewReader returns an io.ReadCloser
|
||||
reader := flate.NewReader(bytes.NewReader(compressedBytes))
|
||||
defer reader.Close()
|
||||
|
||||
// 3. Read the decompressed data into a buffer
|
||||
var out bytes.Buffer
|
||||
_, err = io.Copy(&out, reader)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return out.String(), nil
|
||||
}
|
||||
@@ -1,6 +1,10 @@
|
||||
package page
|
||||
|
||||
import "context"
|
||||
import (
|
||||
"context"
|
||||
"log/slog"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type PageHeader struct {
|
||||
UID string
|
||||
@@ -13,29 +17,41 @@ type Page struct {
|
||||
Content string
|
||||
}
|
||||
|
||||
func (s *Service) GetPages() (pages []PageHeader, err error) {
|
||||
pages = []PageHeader{
|
||||
{
|
||||
UID: "asdf",
|
||||
Title: "asdfAasdf!",
|
||||
CoverImageUID: "500-1000",
|
||||
},
|
||||
func (s *Service) GetPages(ctx context.Context) (pages []PageHeader, err error) {
|
||||
paths, err := s.fs.ReadDir("/")
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
for _, path := range paths {
|
||||
if strings.HasPrefix(path.Name(), ".") || // hidden files
|
||||
strings.HasPrefix(path.Name(), "_") { // hidden pages
|
||||
continue
|
||||
}
|
||||
page, err := s.getPageHeaders(ctx, path.Name())
|
||||
if err != nil { // just ignore missing pages
|
||||
slog.Error("could not open path", "path", path.Name(), "err", err)
|
||||
continue
|
||||
}
|
||||
pages = append(pages, page)
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func (s *Service) GetPage(ctx context.Context, uid string) (page Page, err error) {
|
||||
p, err := s.getPageHeaders(ctx, uid)
|
||||
slog.Debug("got page", "page", p, "err", err)
|
||||
content := `
|
||||
<h1>LOL</h1>
|
||||
<p>
|
||||
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed mollis ligula vel nisl pellentesque aliquet. Maecenas eu congue tortor. Nunc mattis ligula vel augue viverra cursus. Suspendisse potenti. Vivamus in risus vitae mi molestie feugiat. Cras sapien tortor, elementum ut tempus vel, commodo at dui. In hac habitasse platea dictumst. Integer nec ullamcorper purus, tincidunt elementum felis. Duis hendrerit tempor vestibulum. Nunc ut finibus tellus. Donec eu lacus sit amet sem suscipit imperdiet. Quisque cursus vulputate sodales. In sit amet nisl a est lacinia sagittis. </p>
|
||||
<img src="https://picsum.photos/500/1000">
|
||||
<img fetchpriority="low" loading="lazy" src="https://picsum.photos/500/1000">
|
||||
<h2>LOL</h2>
|
||||
<p>
|
||||
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed mollis ligula vel nisl pellentesque aliquet. Maecenas eu congue tortor. Nunc mattis ligula vel augue viverra cursus. Suspendisse potenti. Vivamus in risus vitae mi molestie feugiat. Cras sapien tortor, elementum ut tempus vel, commodo at dui. In hac habitasse platea dictumst. Integer nec ullamcorper purus, tincidunt elementum felis. Duis hendrerit tempor vestibulum. Nunc ut finibus tellus. Donec eu lacus sit amet sem suscipit imperdiet. Quisque cursus vulputate sodales. In sit amet nisl a est lacinia sagittis. </p>
|
||||
|
||||
<img src="https://picsum.photos/600/500">
|
||||
<img fetchpriority="low" loading="lazy" src="https://picsum.photos/600/500">
|
||||
|
||||
<p>
|
||||
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed mollis ligula vel nisl pellentesque aliquet. Maecenas eu congue tortor. Nunc mattis ligula vel augue viverra cursus. Suspendisse potenti. Vivamus in risus vitae mi molestie feugiat. Cras sapien tortor, elementum ut tempus vel, commodo at dui. In hac habitasse platea dictumst. Integer nec ullamcorper purus, tincidunt elementum felis. Duis hendrerit tempor vestibulum. Nunc ut finibus tellus. Donec eu lacus sit amet sem suscipit imperdiet. Quisque cursus vulputate sodales. In sit amet nisl a est lacinia sagittis. </p>
|
||||
@@ -43,6 +59,25 @@ Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed mollis ligula vel n
|
||||
<h3>LOL</h3>
|
||||
<p>
|
||||
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed mollis ligula vel nisl pellentesque aliquet. Maecenas eu congue tortor. Nunc mattis ligula vel augue viverra cursus. Suspendisse potenti. Vivamus in risus vitae mi molestie feugiat. Cras sapien tortor, elementum ut tempus vel, commodo at dui. In hac habitasse platea dictumst. Integer nec ullamcorper purus, tincidunt elementum felis. Duis hendrerit tempor vestibulum. Nunc ut finibus tellus. Donec eu lacus sit amet sem suscipit imperdiet. Quisque cursus vulputate sodales. In sit amet nisl a est lacinia sagittis. </p>
|
||||
<h2>LOL</h2>
|
||||
<p>
|
||||
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed mollis ligula vel nisl pellentesque aliquet. Maecenas eu congue tortor. Nunc mattis ligula vel augue viverra cursus. Suspendisse potenti. Vivamus in risus vitae mi molestie feugiat. Cras sapien tortor, elementum ut tempus vel, commodo at dui. In hac habitasse platea dictumst. Integer nec ullamcorper purus, tincidunt elementum felis. Duis hendrerit tempor vestibulum. Nunc ut finibus tellus. Donec eu lacus sit amet sem suscipit imperdiet. Quisque cursus vulputate sodales. In sit amet nisl a est lacinia sagittis. </p>
|
||||
|
||||
<img fetchpriority="low" loading="lazy" src="https://picsum.photos/601/500">
|
||||
|
||||
<p>
|
||||
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed mollis ligula vel nisl pellentesque aliquet. Maecenas eu congue tortor. Nunc mattis ligula vel augue viverra cursus. Suspendisse potenti. Vivamus in risus vitae mi molestie feugiat. Cras sapien tortor, elementum ut tempus vel, commodo at dui. In hac habitasse platea dictumst. Integer nec ullamcorper purus, tincidunt elementum felis. Duis hendrerit tempor vestibulum. Nunc ut finibus tellus. Donec eu lacus sit amet sem suscipit imperdiet. Quisque cursus vulputate sodales. In sit amet nisl a est lacinia sagittis. </p>
|
||||
|
||||
<h2>LOL</h2>
|
||||
<p>
|
||||
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed mollis ligula vel nisl pellentesque aliquet. Maecenas eu congue tortor. Nunc mattis ligula vel augue viverra cursus. Suspendisse potenti. Vivamus in risus vitae mi molestie feugiat. Cras sapien tortor, elementum ut tempus vel, commodo at dui. In hac habitasse platea dictumst. Integer nec ullamcorper purus, tincidunt elementum felis. Duis hendrerit tempor vestibulum. Nunc ut finibus tellus. Donec eu lacus sit amet sem suscipit imperdiet. Quisque cursus vulputate sodales. In sit amet nisl a est lacinia sagittis. </p>
|
||||
|
||||
<img fetchpriority="low" loading="lazy" src="https://picsum.photos/500/500">
|
||||
|
||||
<p>
|
||||
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed mollis ligula vel nisl pellentesque aliquet. Maecenas eu congue tortor. Nunc mattis ligula vel augue viverra cursus. Suspendisse potenti. Vivamus in risus vitae mi molestie feugiat. Cras sapien tortor, elementum ut tempus vel, commodo at dui. In hac habitasse platea dictumst. Integer nec ullamcorper purus, tincidunt elementum felis. Duis hendrerit tempor vestibulum. Nunc ut finibus tellus. Donec eu lacus sit amet sem suscipit imperdiet. Quisque cursus vulputate sodales. In sit amet nisl a est lacinia sagittis. </p>
|
||||
|
||||
|
||||
`
|
||||
page = Page{
|
||||
PageHeader: PageHeader{
|
||||
|
||||
@@ -0,0 +1,88 @@
|
||||
package page
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"compress/flate"
|
||||
"context"
|
||||
"encoding/base64"
|
||||
"errors"
|
||||
"fmt"
|
||||
"log/slog"
|
||||
"regexp"
|
||||
"strings"
|
||||
|
||||
"git.schreifuchs.ch/schreifuchs/schreifuchs.ch/internal/components/images"
|
||||
"git.schreifuchs.ch/schreifuchs/schreifuchs.ch/internal/components/translate"
|
||||
"github.com/studio-b12/gowebdav"
|
||||
)
|
||||
|
||||
var titleRGX = regexp.MustCompile(`(?m)^#\s+(.+)$`)
|
||||
|
||||
var (
|
||||
ErrMalFormedInput = errors.New("mal formed input")
|
||||
ErrNotFound = errors.New("not found")
|
||||
)
|
||||
|
||||
func (s *Service) getPageHeaders(ctx context.Context, uid string) (page PageHeader, err error) {
|
||||
info, err := s.fs.ReadDir(uid)
|
||||
if gowebdav.IsErrNotFound(err) { // try private
|
||||
err = ErrNotFound
|
||||
}
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
lang := translate.Language(ctx)
|
||||
|
||||
var coverImage *gowebdav.File
|
||||
var contentMD *gowebdav.File
|
||||
|
||||
for _, f := range info {
|
||||
file := f.(gowebdav.File)
|
||||
|
||||
if strings.HasPrefix(file.ContentType(), "image/") {
|
||||
coverImage = &file
|
||||
}
|
||||
|
||||
parts := strings.Split(file.Name(), ".")
|
||||
|
||||
// fallback content
|
||||
if contentMD == nil && len(parts) == 2 && parts[1] == "md" {
|
||||
contentMD = &file
|
||||
}
|
||||
// language content
|
||||
if len(parts) == 3 && parts[1] == lang && parts[2] == "md" {
|
||||
contentMD = &file
|
||||
}
|
||||
}
|
||||
|
||||
slog.Debug("loaded page infos", "cover", coverImage, "content", contentMD)
|
||||
|
||||
content, err := s.fs.Read(contentMD.Path())
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
title := titleRGX.FindStringSubmatch(string(content))
|
||||
if len(title) < 2 {
|
||||
err = fmt.Errorf("%w: no matches for title", ErrMalFormedInput)
|
||||
return
|
||||
}
|
||||
|
||||
page.UID = uid
|
||||
page.Title = title[1]
|
||||
page.CoverImageUID, err = images.UIDFromPath(coverImage.Path())
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func getImageUID(path string) string {
|
||||
var b bytes.Buffer
|
||||
// NewWriter with NoDict (nil) creates a raw DEFLATE compressor
|
||||
zw, _ := flate.NewWriter(&b, flate.BestCompression)
|
||||
|
||||
zw.Write([]byte(path))
|
||||
zw.Close() // Essential to flush the final bits
|
||||
|
||||
return base64.RawURLEncoding.EncodeToString(b.Bytes())
|
||||
}
|
||||
@@ -1,7 +1,23 @@
|
||||
package page
|
||||
|
||||
type Service struct{}
|
||||
import (
|
||||
"log/slog"
|
||||
|
||||
func New() *Service {
|
||||
return &Service{}
|
||||
"github.com/studio-b12/gowebdav"
|
||||
)
|
||||
|
||||
type Service struct {
|
||||
fs *gowebdav.Client
|
||||
}
|
||||
|
||||
func New(fs *gowebdav.Client) *Service {
|
||||
info, err := fs.ReadDir("/")
|
||||
if err != nil {
|
||||
slog.Error("could not read dir", "err", err)
|
||||
}
|
||||
|
||||
slog.Info("file info", "info", info)
|
||||
return &Service{
|
||||
fs: fs,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@ import (
|
||||
)
|
||||
|
||||
func (h *Handler) home(w http.ResponseWriter, r *http.Request) {
|
||||
pageHeaders, err := h.src.GetPages()
|
||||
pageHeaders, err := h.src.GetPages(r.Context())
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
return
|
||||
|
||||
@@ -22,6 +22,6 @@ func New(mux *http.ServeMux, srv pageService) *Handler {
|
||||
}
|
||||
|
||||
type pageService interface {
|
||||
GetPages() ([]page.PageHeader, error)
|
||||
GetPages(ctx context.Context) ([]page.PageHeader, error)
|
||||
GetPage(ctx context.Context, uid string) (page.Page, error)
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ package server
|
||||
import (
|
||||
"log/slog"
|
||||
"net/http"
|
||||
"os"
|
||||
"time"
|
||||
|
||||
"git.schreifuchs.ch/schreifuchs/schreifuchs.ch/internal/components/page"
|
||||
@@ -10,6 +11,7 @@ import (
|
||||
"git.schreifuchs.ch/schreifuchs/schreifuchs.ch/internal/handlers/handlehome"
|
||||
"git.schreifuchs.ch/schreifuchs/schreifuchs.ch/internal/templer"
|
||||
"git.schreifuchs.ch/schreifuchs/schreifuchs.ch/web"
|
||||
"github.com/studio-b12/gowebdav"
|
||||
)
|
||||
|
||||
func (s *Server) RegisterRoutes() (h http.Handler) {
|
||||
@@ -24,17 +26,26 @@ func (s *Server) RegisterRoutes() (h http.Handler) {
|
||||
return h
|
||||
}
|
||||
|
||||
func registerOther() http.Handler {
|
||||
func registerOther() (h http.Handler) {
|
||||
mux := http.NewServeMux()
|
||||
|
||||
pager := page.New()
|
||||
webdavClient := gowebdav.NewClient("https://cloud.schreifuchs.ch/remote.php/dav/files/test/website", "test", os.Getenv("TEST_PW"))
|
||||
if err := webdavClient.Connect(); err != nil {
|
||||
slog.Error("could not connect webdavClient", "err", err, "pw", os.Getenv("TEST_PW"))
|
||||
}
|
||||
|
||||
pager := page.New(webdavClient)
|
||||
|
||||
_ = handlehome.New(mux, pager)
|
||||
|
||||
mux.Handle("/", http.FileServer(http.FS(web.GetStaticFS())))
|
||||
|
||||
translator := translate.New()
|
||||
return translator.Middleware(mux)
|
||||
|
||||
h = mux
|
||||
h = translator.Middleware(h)
|
||||
h = cacheMiddleware(time.Second * 45)(h)
|
||||
return h
|
||||
}
|
||||
|
||||
func (s *Server) loggingMiddleware(next http.Handler) http.Handler {
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
package server
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io/fs"
|
||||
"log/slog"
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"git.schreifuchs.ch/schreifuchs/schreifuchs.ch/web"
|
||||
)
|
||||
@@ -13,7 +15,7 @@ func registerStatic(mux *http.ServeMux) {
|
||||
fileSystem := web.GetStaticFS()
|
||||
|
||||
// we still use go's fileServer to avoid unnecessary implementation
|
||||
fileServer := http.FileServer(http.FS(fileSystem))
|
||||
fileServer := cacheMiddleware(time.Hour * 24)(http.FileServer(http.FS(fileSystem)))
|
||||
|
||||
err := fs.WalkDir(fileSystem, ".", func(path string, d fs.DirEntry, err error) error {
|
||||
if err != nil {
|
||||
@@ -36,3 +38,13 @@ func registerStatic(mux *http.ServeMux) {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
// cacheMiddleware adds Cache-Control headers to the response.
|
||||
func cacheMiddleware(maxAge time.Duration) func(next http.Handler) http.Handler {
|
||||
return func(next http.Handler) http.Handler {
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Cache-Control", fmt.Sprintf("public, max-age=%.0f", maxAge.Seconds()))
|
||||
next.ServeHTTP(w, r)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -4,7 +4,7 @@ templ ImageTile(src string) {
|
||||
<div class="grid grid-cols-1 grid-rows-1">
|
||||
<img
|
||||
src={ src }
|
||||
loading="lazy"
|
||||
fetchpriority="high"
|
||||
class="row-start-1 col-start-1 pointer-events-none w-full h-96 object-cover"
|
||||
/>
|
||||
<div class="row-start-1 col-start-1">
|
||||
|
||||
@@ -42,7 +42,7 @@ func ImageTile(src string) templ.Component {
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, "\" loading=\"lazy\" class=\"row-start-1 col-start-1 pointer-events-none w-full h-96 object-cover\"><div class=\"row-start-1 col-start-1\">")
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, "\" fetchpriority=\"high\" class=\"row-start-1 col-start-1 pointer-events-none w-full h-96 object-cover\"><div class=\"row-start-1 col-start-1\">")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
|
||||
@@ -12,14 +12,15 @@ templ Base(title string) {
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
|
||||
<title>{ title }</title>
|
||||
<link rel="icon" type="image/png" href="/favicon.png"/>
|
||||
<link href="/css/output.css" rel="stylesheet"/>
|
||||
<script src="/js/htmx.min.js"></script>
|
||||
<link fetchpriority="high" href="/css/output.css" rel="stylesheet"/>
|
||||
<script fetchpriority="low" src="/js/htmx.min.js"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/htmx-ext-preload@2.1.2" integrity="sha384-PRIcY6hH1Y5784C76/Y8SqLyTanY9rnI3B8F3+hKZFNED55hsEqMJyqWhp95lgfk" crossorigin="anonymous"></script>
|
||||
</head>
|
||||
<body class="bg-black dark" hx-boost="true" hx-target="main">
|
||||
<body class="bg-black dark" hx-boost="true" hx-target="main" hx-ext="preload">
|
||||
<header
|
||||
class="fixed z-50 mix-blend-difference p-1 w-full flex justify-between items-start"
|
||||
>
|
||||
<a class="text-white text-2xl" href="/">schreifuchs.ch</a>
|
||||
<a class="text-white text-2xl" href={ "/" + translate.Path(ctx, "") }>schreifuchs.ch</a>
|
||||
<nav class="flex gap-2 p-2">
|
||||
for _, lang := range translate.SupportedLanguages(ctx) {
|
||||
<a
|
||||
|
||||
+36
-23
@@ -59,56 +59,69 @@ func Base(title string) templ.Component {
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 3, "</title><link rel=\"icon\" type=\"image/png\" href=\"/favicon.png\"><link href=\"/css/output.css\" rel=\"stylesheet\"><script src=\"/js/htmx.min.js\"></script></head><body class=\"bg-black dark\" hx-boost=\"true\" hx-target=\"main\"><header class=\"fixed z-50 mix-blend-difference p-1 w-full flex justify-between items-start\"><a class=\"text-white text-2xl\" href=\"/\">schreifuchs.ch</a><nav class=\"flex gap-2 p-2\">")
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 3, "</title><link rel=\"icon\" type=\"image/png\" href=\"/favicon.png\"><link fetchpriority=\"high\" href=\"/css/output.css\" rel=\"stylesheet\"><script fetchpriority=\"low\" src=\"/js/htmx.min.js\"></script><script src=\"https://cdn.jsdelivr.net/npm/htmx-ext-preload@2.1.2\" integrity=\"sha384-PRIcY6hH1Y5784C76/Y8SqLyTanY9rnI3B8F3+hKZFNED55hsEqMJyqWhp95lgfk\" crossorigin=\"anonymous\"></script></head><body class=\"bg-black dark\" hx-boost=\"true\" hx-target=\"main\" hx-ext=\"preload\"><header class=\"fixed z-50 mix-blend-difference p-1 w-full flex justify-between items-start\"><a class=\"text-white text-2xl\" href=\"")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var4 templ.SafeURL
|
||||
templ_7745c5c3_Var4, templ_7745c5c3_Err = templ.JoinURLErrs("/" + translate.Path(ctx, ""))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `layouts/base.templ`, Line: 23, Col: 71}
|
||||
}
|
||||
_, 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, "\">schreifuchs.ch</a><nav class=\"flex gap-2 p-2\">")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
for _, lang := range translate.SupportedLanguages(ctx) {
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 4, "<a href=\"")
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 5, "<a href=\"")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var4 templ.SafeURL
|
||||
templ_7745c5c3_Var4, templ_7745c5c3_Err = templ.JoinURLErrs("/" + translate.PathForLang(ctx, lang, strings.Split(templer.Path(ctx), "/")...))
|
||||
var templ_7745c5c3_Var5 templ.SafeURL
|
||||
templ_7745c5c3_Var5, templ_7745c5c3_Err = templ.JoinURLErrs("/" + translate.PathForLang(ctx, lang, strings.Split(templer.Path(ctx), "/")...))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `layouts/base.templ`, Line: 26, Col: 94}
|
||||
}
|
||||
_, 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, 5, "\" hreflang=\"")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var5 string
|
||||
templ_7745c5c3_Var5, templ_7745c5c3_Err = templ.JoinStringErrs(lang)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `layouts/base.templ`, Line: 27, Col: 22}
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `layouts/base.templ`, Line: 27, Col: 94}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var5))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 6, "\" data-no-translate class=\"text-white hover:underline uppercase\">")
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 6, "\" hreflang=\"")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var6 string
|
||||
templ_7745c5c3_Var6, templ_7745c5c3_Err = templ.JoinStringErrs(lang)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `layouts/base.templ`, Line: 31, Col: 13}
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `layouts/base.templ`, Line: 28, Col: 22}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var6))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 7, "</a>")
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 7, "\" data-no-translate class=\"text-white hover:underline uppercase\">")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var7 string
|
||||
templ_7745c5c3_Var7, templ_7745c5c3_Err = templ.JoinStringErrs(lang)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `layouts/base.templ`, Line: 32, Col: 13}
|
||||
}
|
||||
_, 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, 8, "</a>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 8, "</nav></header><main class=\"text-white\">")
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 9, "</nav></header><main class=\"text-white\">")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
@@ -116,7 +129,7 @@ func Base(title string) templ.Component {
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 9, "</main></body></html>")
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 10, "</main></body></html>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
|
||||
@@ -7,8 +7,8 @@ import (
|
||||
|
||||
templ Home(pages []page.PageHeader) {
|
||||
for _, page := range pages {
|
||||
@components.ImageTile("https://picsum.photos/1000/500") {
|
||||
<a class="flex items-center justify-center h-full " href={ "/" + page.UID }>
|
||||
@components.ImageTile("https://picsum.photos/" + page.CoverImageUID) {
|
||||
<a class="flex items-center justify-center h-full " href={ "/" + page.UID } preload="mouseover">
|
||||
<h2
|
||||
class="text-3xl font-bold text-white hover:underline text-shadow-lg"
|
||||
>
|
||||
|
||||
@@ -60,7 +60,7 @@ func Home(pages []page.PageHeader) templ.Component {
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, "\"><h2 class=\"text-3xl font-bold text-white hover:underline text-shadow-lg\">")
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, "\" preload=\"mouseover\"><h2 class=\"text-3xl font-bold text-white hover:underline text-shadow-lg\">")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
@@ -79,7 +79,7 @@ func Home(pages []page.PageHeader) templ.Component {
|
||||
}
|
||||
return nil
|
||||
})
|
||||
templ_7745c5c3_Err = components.ImageTile("https://picsum.photos/1000/500").Render(templ.WithChildren(ctx, templ_7745c5c3_Var2), templ_7745c5c3_Buffer)
|
||||
templ_7745c5c3_Err = components.ImageTile("https://picsum.photos/"+page.CoverImageUID).Render(templ.WithChildren(ctx, templ_7745c5c3_Var2), templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
|
||||
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user