From f15d6b2163eda5fe0f6ab4eedb5d37fd2e53b12d Mon Sep 17 00:00:00 2001 From: Jan Eitzinger Date: Sat, 3 Aug 2024 08:51:30 +0200 Subject: [PATCH] Initial checkin of templ skeleton HTML based on Jason Knight HTML template code --- Makefile | 18 + cmd/site/main.go | 41 + go.mod | 33 + go.sum | 68 ++ internal/repository/dbConn.go | 231 ++++++ internal/util/egctx.go | 67 ++ web/components/base.templ | 34 + web/components/errors.templ | 5 + web/components/footer.templ | 37 + web/components/header.templ | 29 + web/components/index.templ | 16 + web/routes.go | 22 + web/server.go | 36 + web/static/apple-touch-icon.png | Bin 0 -> 12136 bytes web/static/css/fonts.css | 51 ++ web/static/css/fonts/interface-Regular.woff | Bin 0 -> 3152 bytes web/static/css/fonts/interface-Regular.woff2 | Bin 0 -> 2488 bytes .../css/fonts/poppins-western-bold.woff | Bin 0 -> 15648 bytes .../css/fonts/poppins-western-bold.woff2 | Bin 0 -> 11364 bytes web/static/css/fonts/poppins-western.woff | Bin 0 -> 15912 bytes web/static/css/fonts/poppins-western.woff2 | Bin 0 -> 11540 bytes web/static/css/site.print.css | 138 ++++ web/static/css/site.screen.css | 763 ++++++++++++++++++ web/static/favicon.ico | Bin 0 -> 38037 bytes web/static/favicon.svg | 1 + 25 files changed, 1590 insertions(+) create mode 100644 Makefile create mode 100644 cmd/site/main.go create mode 100644 go.mod create mode 100644 go.sum create mode 100644 internal/repository/dbConn.go create mode 100644 internal/util/egctx.go create mode 100644 web/components/base.templ create mode 100644 web/components/errors.templ create mode 100644 web/components/footer.templ create mode 100644 web/components/header.templ create mode 100644 web/components/index.templ create mode 100644 web/routes.go create mode 100644 web/server.go create mode 100644 web/static/apple-touch-icon.png create mode 100644 web/static/css/fonts.css create mode 100644 web/static/css/fonts/interface-Regular.woff create mode 100644 web/static/css/fonts/interface-Regular.woff2 create mode 100644 web/static/css/fonts/poppins-western-bold.woff create mode 100644 web/static/css/fonts/poppins-western-bold.woff2 create mode 100644 web/static/css/fonts/poppins-western.woff create mode 100644 web/static/css/fonts/poppins-western.woff2 create mode 100644 web/static/css/site.print.css create mode 100644 web/static/css/site.screen.css create mode 100644 web/static/favicon.ico create mode 100644 web/static/favicon.svg diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..81f2ca6 --- /dev/null +++ b/Makefile @@ -0,0 +1,18 @@ +TARGET = ./site + +.PHONY: clean distclean test components $(TARGET) + +.NOTPARALLEL: + +$(TARGET): components + $(info ===> BUILD site) + @go build ./cmd/site + +components: + $(info ===> BUILD templates) + cd web/components && templ generate + +clean: + $(info ===> CLEAN) + @go clean + @rm -f $(TARGET) diff --git a/cmd/site/main.go b/cmd/site/main.go new file mode 100644 index 0000000..366ca22 --- /dev/null +++ b/cmd/site/main.go @@ -0,0 +1,41 @@ +package main + +import ( + "context" + "fmt" + "log/slog" + "os" + "os/signal" + + "git.clustercockpit.org/moebiusband/go-http-skeleton/internal/util" + "git.clustercockpit.org/moebiusband/go-http-skeleton/web" + "github.com/joho/godotenv" +) + +func main() { + godotenv.Load() + + logger := slog.New(slog.NewJSONHandler(os.Stdout, nil)) + logger.Info("Starting http server") + defer logger.Info("Stopping http server") + + ctx, stop := signal.NotifyContext(context.Background(), os.Interrupt) + defer stop() + + if err := run(ctx); err != nil { + logger.Error("Error running http server", slog.Any("err", err)) + os.Exit(1) + } +} + +func run(ctx context.Context) error { + eg := util.NewErrGroupSharedCtx( + ctx, + web.RunBlocking(8080), + ) + if err := eg.Wait(); err != nil { + return fmt.Errorf("error running http server: %w", err) + } + + return nil +} diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..843eee3 --- /dev/null +++ b/go.mod @@ -0,0 +1,33 @@ +module git.clustercockpit.org/moebiusband/go-http-skeleton + +go 1.22.5 + +require ( + github.com/a-h/templ v0.2.747 // indirect + github.com/benbjohnson/hashfs v0.2.2 // indirect + github.com/delaneyj/datastar v0.16.2 // indirect + github.com/delaneyj/gostar v0.7.3 // indirect + github.com/dustin/go-humanize v1.0.1 // indirect + github.com/go-sanitize/sanitize v1.1.0 // indirect + github.com/goccy/go-json v0.10.3 // indirect + github.com/google/uuid v1.6.0 // indirect + github.com/gorilla/securecookie v1.1.2 // indirect + github.com/gorilla/sessions v1.3.0 // indirect + github.com/igrmk/treemap/v2 v2.0.1 // indirect + github.com/joho/godotenv v1.5.1 // indirect + github.com/mattn/go-isatty v0.0.20 // indirect + github.com/ncruces/go-strftime v0.1.9 // indirect + github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect + github.com/samber/lo v1.44.0 // indirect + github.com/valyala/bytebufferpool v1.0.0 // indirect + golang.org/x/exp v0.0.0-20240613232115-7f521ea00fb8 // indirect + golang.org/x/sync v0.7.0 // indirect + golang.org/x/sys v0.22.0 // indirect + golang.org/x/text v0.16.0 // indirect + google.golang.org/protobuf v1.34.2 // indirect + modernc.org/libc v1.54.2 // indirect + modernc.org/mathutil v1.6.0 // indirect + modernc.org/memory v1.8.0 // indirect + modernc.org/sqlite v1.30.1 // indirect + zombiezen.com/go/sqlite v1.3.0 // indirect +) diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..2145716 --- /dev/null +++ b/go.sum @@ -0,0 +1,68 @@ +github.com/a-h/templ v0.2.747 h1:D0dQ2lxC3W7Dxl6fxQ/1zZHBQslSkTSvl5FxP/CfdKg= +github.com/a-h/templ v0.2.747/go.mod h1:69ObQIbrcuwPCU32ohNaWce3Cb7qM5GMiqN1K+2yop4= +github.com/benbjohnson/hashfs v0.2.2 h1:vFZtksphM5LcnMRFctj49jCUkCc7wp3NP6INyfjkse4= +github.com/benbjohnson/hashfs v0.2.2/go.mod h1:7OMXaMVo1YkfiIPxKrl7OXkUTUgWjmsAKyR+E6xDIRM= +github.com/delaneyj/datastar v0.16.2 h1:gFvuVZE1Ze95YcfyrxLb+wAlaMYDCx/k24hxObRYU+s= +github.com/delaneyj/datastar v0.16.2/go.mod h1:+h1DvxZr7kOxWhjOxMgYTz17pfVR+fQ2me//3pqNm9I= +github.com/delaneyj/gostar v0.7.3 h1:+7vEN7T9Y6HESGMHwlXzsTC/apgVwQy1bR4NQ7IKYfo= +github.com/delaneyj/gostar v0.7.3/go.mod h1:mlxRWAVbntRR2VWlpXAzt7y9HY+bQtEm/lsyFnGLx/w= +github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY= +github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto= +github.com/go-sanitize/sanitize v1.1.0 h1:wq9tl5+VfkyCacCZIVQf6ksegRpfWl3N2vAyyYD0F1I= +github.com/go-sanitize/sanitize v1.1.0/go.mod h1:r+anm3xp/Y1+pTNvPSgHMznwb0VVZgszoMQs3naOf0A= +github.com/goccy/go-json v0.10.3 h1:KZ5WoDbxAIgm2HNbYckL0se1fHD6rz5j4ywS6ebzDqA= +github.com/goccy/go-json v0.10.3/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M= +github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= +github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= +github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/gorilla/securecookie v1.1.2 h1:YCIWL56dvtr73r6715mJs5ZvhtnY73hBvEF8kXD8ePA= +github.com/gorilla/securecookie v1.1.2/go.mod h1:NfCASbcHqRSY+3a8tlWJwsQap2VX5pwzwo4h3eOamfo= +github.com/gorilla/sessions v1.3.0 h1:XYlkq7KcpOB2ZhHBPv5WpjMIxrQosiZanfoy1HLZFzg= +github.com/gorilla/sessions v1.3.0/go.mod h1:ePLdVu+jbEgHH+KWw8I1z2wqd0BAdAQh/8LRvBeoNcQ= +github.com/igrmk/treemap/v2 v2.0.1 h1:Jhy4z3yhATvYZMWCmxsnHO5NnNZBdueSzvxh6353l+0= +github.com/igrmk/treemap/v2 v2.0.1/go.mod h1:PkTPvx+8OHS8/41jnnyVY+oVsfkaOUZGcr+sfonosd4= +github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0= +github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4= +github.com/mattn/go-isatty v0.0.16 h1:bq3VjFmv/sOjHtdEhmkEV4x1AJtvUvOJ2PFAZ5+peKQ= +github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= +github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= +github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= +github.com/ncruces/go-strftime v0.1.9 h1:bY0MQC28UADQmHmaF5dgpLmImcShSi2kHU9XLdhx/f4= +github.com/ncruces/go-strftime v0.1.9/go.mod h1:Fwc5htZGVVkseilnfgOVb9mKy6w1naJmn9CehxcKcls= +github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec h1:W09IVJc94icq4NjY3clb7Lk8O1qJ8BdBEF8z0ibU0rE= +github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo= +github.com/samber/lo v1.44.0 h1:5il56KxRE+GHsm1IR+sZ/6J42NODigFiqCWpSc2dybA= +github.com/samber/lo v1.44.0/go.mod h1:RmDH9Ct32Qy3gduHQuKJ3gW1fMHAnE/fAzQuf6He5cU= +github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw= +github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= +golang.org/x/exp v0.0.0-20240613232115-7f521ea00fb8 h1:yixxcjnhBmY0nkL253HFVIm0JsFHwrHdT3Yh6szTnfY= +golang.org/x/exp v0.0.0-20240613232115-7f521ea00fb8/go.mod h1:jj3sYF3dwk5D+ghuXyeI3r5MFf+NT2An6/9dOA95KSI= +golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= +golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.16.0 h1:xWw16ngr6ZMtmxDyKyIgsE93KNKz5HKmMa3b8ALHidU= +golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI= +golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= +golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= +google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= +google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= +modernc.org/libc v1.41.0 h1:g9YAc6BkKlgORsUWj+JwqoB1wU3o4DE3bM3yvA3k+Gk= +modernc.org/libc v1.41.0/go.mod h1:w0eszPsiXoOnoMJgrXjglgLuDy/bt5RR4y3QzUUeodY= +modernc.org/libc v1.54.2 h1:9ymAodb+3v85YfBIZqn62BGgO4L9zF2Hx4LNb6dSU/Q= +modernc.org/libc v1.54.2/go.mod h1:B0D6klDmSmnq26T1iocn9kzyX6NtbzjuI3+oX/xfvng= +modernc.org/mathutil v1.6.0 h1:fRe9+AmYlaej+64JsEEhoWuAYBkOtQiMEU7n/XgfYi4= +modernc.org/mathutil v1.6.0/go.mod h1:Ui5Q9q1TR2gFm0AQRqQUaBWFLAhQpCwNcuhBOSedWPo= +modernc.org/memory v1.7.2 h1:Klh90S215mmH8c9gO98QxQFsY+W451E8AnzjoE2ee1E= +modernc.org/memory v1.7.2/go.mod h1:NO4NVCQy0N7ln+T9ngWqOQfi7ley4vpwvARR+Hjw95E= +modernc.org/memory v1.8.0 h1:IqGTL6eFMaDZZhEWwcREgeMXYwmW83LYW8cROZYkg+E= +modernc.org/memory v1.8.0/go.mod h1:XPZ936zp5OMKGWPqbD3JShgd/ZoQ7899TUuQqxY+peU= +modernc.org/sqlite v1.29.1 h1:19GY2qvWB4VPw0HppFlZCPAbmxFU41r+qjKZQdQ1ryA= +modernc.org/sqlite v1.29.1/go.mod h1:hG41jCYxOAOoO6BRK66AdRlmOcDzXf7qnwlwjUIOqa0= +modernc.org/sqlite v1.30.1 h1:YFhPVfu2iIgUf9kuA1CR7iiHdcEEsI2i+yjRYHscyxk= +modernc.org/sqlite v1.30.1/go.mod h1:DUmsiWQDaAvU4abhc/N+djlom/L2o8f7gZ95RCvyoLU= +zombiezen.com/go/sqlite v1.3.0 h1:98g1gnCm+CNz6AuQHu0gqyw7gR2WU3O3PJufDOStpUs= +zombiezen.com/go/sqlite v1.3.0/go.mod h1:yRl27//s/9aXU3RWs8uFQwjkTG9gYNGEls6+6SvrclY= diff --git a/internal/repository/dbConn.go b/internal/repository/dbConn.go new file mode 100644 index 0000000..0be6a85 --- /dev/null +++ b/internal/repository/dbConn.go @@ -0,0 +1,231 @@ +package repository + +import ( + "context" + "errors" + "fmt" + "os" + "path/filepath" + "runtime" + "time" + + "google.golang.org/protobuf/types/known/timestamppb" + "zombiezen.com/go/sqlite" + "zombiezen.com/go/sqlite/sqlitemigration" + "zombiezen.com/go/sqlite/sqlitex" +) + +type Database struct { + filename string + migrations []string + writePool *sqlitex.Pool + readPool *sqlitex.Pool +} + +type TxFn func(tx *sqlite.Conn) error + +func NewDatabase(ctx context.Context, dbFilename string, migrations []string) (*Database, error) { + if dbFilename == "" { + return nil, fmt.Errorf("database filename is required") + } + + db := &Database{ + filename: dbFilename, + migrations: migrations, + } + + if err := db.Reset(ctx, false); err != nil { + return nil, fmt.Errorf("failed to reset database: %w", err) + } + + return db, nil +} + +func (db *Database) WriteWithoutTx(ctx context.Context, fn TxFn) error { + conn, err := db.writePool.Take(ctx) + if err != nil { + return fmt.Errorf("failed to take write connection: %w", err) + } + if conn == nil { + return fmt.Errorf("could not get write connection from pool") + } + defer db.writePool.Put(conn) + + if err := fn(conn); err != nil { + return fmt.Errorf("could not execute write transaction: %w", err) + } + + return nil +} + +func (db *Database) Reset(ctx context.Context, shouldClear bool) (err error) { + if err := db.Close(); err != nil { + return fmt.Errorf("could not close database: %w", err) + } + + if shouldClear { + if err := os.RemoveAll(db.filename + "*"); err != nil { + return fmt.Errorf("could not remove database file: %w", err) + } + } + if err := os.MkdirAll(filepath.Dir(db.filename), 0755); err != nil { + return fmt.Errorf("could not create database directory: %w", err) + } + + uri := fmt.Sprintf("file:%s?_journal_mode=WAL&_synchronous=NORMAL", db.filename) + + db.writePool, err = sqlitex.NewPool(uri, sqlitex.PoolOptions{ + PoolSize: 1, + }) + if err != nil { + return fmt.Errorf("could not open write pool: %w", err) + } + + db.readPool, err = sqlitex.NewPool(uri, sqlitex.PoolOptions{ + PoolSize: runtime.NumCPU(), + }) + + if err := db.WriteTX(ctx, func(tx *sqlite.Conn) error { + foreignKeysStmt := tx.Prep("PRAGMA foreign_keys = ON") + defer foreignKeysStmt.Finalize() + if _, err := foreignKeysStmt.Step(); err != nil { + return fmt.Errorf("failed to enable foreign keys: %w", err) + } + + return nil + }); err != nil { + return fmt.Errorf("failed to initialize database: %w", err) + } + + schema := sqlitemigration.Schema{Migrations: db.migrations} + conn, err := db.writePool.Take(ctx) + if err != nil { + return fmt.Errorf("failed to take write connection: %w", err) + } + defer db.writePool.Put(conn) + + if err := sqlitemigration.Migrate(ctx, conn, schema); err != nil { + db.writePool.Put(conn) + return fmt.Errorf("failed to migrate database: %w", err) + } + + return nil +} + +func (db *Database) Close() error { + errs := []error{} + if db.writePool != nil { + errs = append(errs, db.writePool.Close()) + } + + if db.readPool != nil { + errs = append(errs, db.readPool.Close()) + } + + return errors.Join(errs...) +} + +func (db *Database) WriteTX(ctx context.Context, fn TxFn) (err error) { + conn, err := db.writePool.Take(ctx) + if err != nil { + return fmt.Errorf("failed to take write connection: %w", err) + } + if conn == nil { + return fmt.Errorf("could not get write connection from pool") + } + defer db.writePool.Put(conn) + + endFn, err := sqlitex.ImmediateTransaction(conn) + if err != nil { + return fmt.Errorf("could not start transaction: %w", err) + } + defer endFn(&err) + + if err := fn(conn); err != nil { + return fmt.Errorf("could not execute write transaction: %w", err) + } + + return nil +} + +func (db *Database) ReadTX(ctx context.Context, fn TxFn) (err error) { + conn, err := db.readPool.Take(ctx) + if err != nil { + return fmt.Errorf("failed to take read connection: %w", err) + } + if conn == nil { + return fmt.Errorf("could not get read connection from pool") + } + defer db.readPool.Put(conn) + + endFn := sqlitex.Transaction(conn) + defer endFn(&err) + + if err := fn(conn); err != nil { + return fmt.Errorf("could not execute read transaction: %w", err) + } + + return nil +} + +const ( + secondsInADay = 86400 + UnixEpochJulianDay = 2440587.5 +) + +var JulianZeroTime = JulianDayToTime(0) + +// TimeToJulianDay converts a time.Time into a Julian day. +func TimeToJulianDay(t time.Time) float64 { + return float64(t.UTC().Unix())/secondsInADay + UnixEpochJulianDay +} + +// JulianDayToTime converts a Julian day into a time.Time. +func JulianDayToTime(d float64) time.Time { + return time.Unix(int64((d-UnixEpochJulianDay)*secondsInADay), 0).UTC() +} + +func JulianNow() float64 { + return TimeToJulianDay(time.Now()) +} + +func TimestampJulian(ts *timestamppb.Timestamp) float64 { + return TimeToJulianDay(ts.AsTime()) +} + +func JulianDayToTimestamp(f float64) *timestamppb.Timestamp { + t := JulianDayToTime(f) + return timestamppb.New(t) +} + +func StmtJulianToTimestamp(stmt *sqlite.Stmt, colName string) *timestamppb.Timestamp { + julianDays := stmt.GetFloat(colName) + return JulianDayToTimestamp(julianDays) +} + +func StmtJulianToTime(stmt *sqlite.Stmt, colName string) time.Time { + julianDays := stmt.GetFloat(colName) + return JulianDayToTime(julianDays) +} + +func DurationToMilliseconds(d time.Duration) int64 { + return int64(d / time.Millisecond) +} + +func MillisecondsToDuration(ms int64) time.Duration { + return time.Duration(ms) * time.Millisecond +} + +func StmtBytes(stmt *sqlite.Stmt, colName string) []byte { + bl := stmt.GetLen(colName) + if bl == 0 { + return nil + } + + buf := make([]byte, bl) + if writtent := stmt.GetBytes(colName, buf); writtent != bl { + return nil + } + + return buf +} diff --git a/internal/util/egctx.go b/internal/util/egctx.go new file mode 100644 index 0000000..d89d742 --- /dev/null +++ b/internal/util/egctx.go @@ -0,0 +1,67 @@ +package util + +import ( + "context" + + "golang.org/x/sync/errgroup" +) + +type ErrGroupSharedCtx struct { + eg *errgroup.Group + ctx context.Context +} + +type CtxErrFunc func(ctx context.Context) error + +func NewErrGroupSharedCtx(ctx context.Context, funcs ...CtxErrFunc) *ErrGroupSharedCtx { + eg, ctx := errgroup.WithContext(ctx) + + egCtx := &ErrGroupSharedCtx{ + eg: eg, + ctx: ctx, + } + + egCtx.Go(funcs...) + + return egCtx +} + +func (egc *ErrGroupSharedCtx) Go(funcs ...CtxErrFunc) { + for _, f := range funcs { + fn := f + egc.eg.Go(func() error { + return fn(egc.ctx) + }) + } +} + +func (egc *ErrGroupSharedCtx) Wait() error { + return egc.eg.Wait() +} + +type ErrGroupSeparateCtx struct { + eg *errgroup.Group +} + +func NewErrGroupSeparateCtx() *ErrGroupSeparateCtx { + eg := &errgroup.Group{} + + egCtx := &ErrGroupSeparateCtx{ + eg: eg, + } + + return egCtx +} + +func (egc *ErrGroupSeparateCtx) Go(ctx context.Context, funcs ...CtxErrFunc) { + for _, f := range funcs { + fn := f + egc.eg.Go(func() error { + return fn(ctx) + }) + } +} + +func (egc *ErrGroupSeparateCtx) Wait() error { + return egc.eg.Wait() +} diff --git a/web/components/base.templ b/web/components/base.templ new file mode 100644 index 0000000..b039107 --- /dev/null +++ b/web/components/base.templ @@ -0,0 +1,34 @@ +package components + +templ Page(content templ.Component) { + + + + + + + + + + + + + + + + + + Awesome content + + +
+ @Header() +
+ @content +
+ Back To Top + @Footer() +
+ + +} diff --git a/web/components/errors.templ b/web/components/errors.templ new file mode 100644 index 0000000..3bf7ed2 --- /dev/null +++ b/web/components/errors.templ @@ -0,0 +1,5 @@ +package components + +templ Page404() { +
Page not found
+} diff --git a/web/components/footer.templ b/web/components/footer.templ new file mode 100644 index 0000000..273f547 --- /dev/null +++ b/web/components/footer.templ @@ -0,0 +1,37 @@ +package components + +templ Footer() { + +} diff --git a/web/components/header.templ b/web/components/header.templ new file mode 100644 index 0000000..bbb8421 --- /dev/null +++ b/web/components/header.templ @@ -0,0 +1,29 @@ +package components + +templ Header() { +
+ +

Website template

+

A Golang Templ based skeleton

+
+ + +
+} diff --git a/web/components/index.templ b/web/components/index.templ new file mode 100644 index 0000000..c4feb5d --- /dev/null +++ b/web/components/index.templ @@ -0,0 +1,16 @@ +package components + +templ IndexPage() { +
+
+
+

Semantic Accessible Markup Is Easy

+

Stop Making It Hard

+
+

+ I have spent the past decade and a half helping site owners out of deep legal troubles for accessibility woes, improve workplace conditions, gain essential leadership skills, by way of promoting good practices. I can help you learn to leverage caching models, write accessibible HTML, keep your style within guidelines such as the WCAG, and aid in lawsuits involving the US ADA, UQ EQA, and a plethora of other accessibility laws from around the globe. +

+ Learn More +
+
+} diff --git a/web/routes.go b/web/routes.go new file mode 100644 index 0000000..23cfc7a --- /dev/null +++ b/web/routes.go @@ -0,0 +1,22 @@ +package web + +import ( + "net/http" + "time" + + "git.clustercockpit.org/moebiusband/go-http-skeleton/web/components" + "github.com/a-h/templ" + "github.com/benbjohnson/hashfs" + "github.com/gorilla/sessions" +) + +func setupRoutes(r *http.ServeMux) error { + r.Handle("GET /static/", hashfs.FileServer(staticSys)) + r.Handle("GET /{$}", templ.Handler(components.Page(components.IndexPage()))) + r.Handle("GET /404", templ.Handler(components.Page(components.Page404()), templ.WithStatus(http.StatusNotFound))) + + sessionStore := sessions.NewCookieStore([]byte("datastar-session-secret")) + sessionStore.MaxAge(int(24 * time.Hour / time.Second)) + + return nil +} diff --git a/web/server.go b/web/server.go new file mode 100644 index 0000000..95e7e1e --- /dev/null +++ b/web/server.go @@ -0,0 +1,36 @@ +package web + +import ( + "context" + "embed" + "fmt" + "net/http" + + "git.clustercockpit.org/moebiusband/go-http-skeleton/internal/util" + "github.com/benbjohnson/hashfs" +) + +//go:embed static/* +var staticFS embed.FS + +var staticSys = hashfs.NewFS(staticFS) + +func RunBlocking(port int) util.CtxErrFunc { + return func(ctx context.Context) error { + r := http.NewServeMux() + + setupRoutes(r) + + srv := &http.Server{ + Addr: fmt.Sprintf(":%d", port), + Handler: r, + } + + go func() { + <-ctx.Done() + srv.Shutdown(context.Background()) + }() + + return srv.ListenAndServe() + } +} diff --git a/web/static/apple-touch-icon.png b/web/static/apple-touch-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..9926ea024a8bc74a860c1f2fa318c8e47ca05327 GIT binary patch literal 12136 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 gV%rOtU74)`KneXe*09l`AdjJ3c literal 0 HcmV?d00001 diff --git a/web/static/css/fonts/interface-Regular.woff2 b/web/static/css/fonts/interface-Regular.woff2 new file mode 100644 index 0000000000000000000000000000000000000000..2c007435f34349243bdd0ad804b38868db2fae95 GIT binary patch literal 2488 zcmV;p2}kyKPew8T0RR91013DN4gdfE01tQo010CN0RR9100000000000000000000 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 z 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 XnLcy=-3JH6pK#p$0?}qeVg&gghB!;A literal 0 HcmV?d00001 diff --git a/web/static/css/fonts/poppins-western.woff2 b/web/static/css/fonts/poppins-western.woff2 new file mode 100644 index 0000000000000000000000000000000000000000..a9753046d4e1dcfa00332e7fb9cd7612e82f13c4 GIT binary patch literal 11540 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 section { + padding-bottom:1.75rem; +} + +main > section header p { + font-size:14pt; +} + +.hero header p { + margin-top:0; +} + +.hasPlate, +.cards { + display:flex; + flex-wrap:wrap; + justify-content:center; + gap:1rem 2rem; +} + +.hasPlate > figure { + flex-grow:0; + width:min(12rem, 100%); + text-align:center; +} + +.hasPlate > figure img { + width:100%; + height:auto; + border-radius:1rem; +} + +.hasPlate > div { + width:1%; + flex-grow:1; +} + +.cards > * { + width:calc(50% - 1rem); + break-inside:avoid; +} + +.cards > * > *:last-child { + margin-bottom:0; + padding-bottom:0; +} + +#whatIDo h3[class*="icon_"]:before { + font-size:36pt; + margin-right:0.5rem; +} + +#testimonials figcaption { + font-size:14pt; + margin-bottom:0.5rem; +} + +#testimonials figcaption img { + display:inline-block; + vertical-align:middle; + width:3rem; + height:3rem; + margin-right:0.25rem; + border-radius:50%; +} + +#whatIDo ul, +#testimonials blockquote { + font-size:10pt; +} + +.note { + text-align:center; +} + +#fauxBody > footer { + text-align:center; +} \ No newline at end of file diff --git a/web/static/css/site.screen.css b/web/static/css/site.screen.css new file mode 100644 index 0000000..135b44a --- /dev/null +++ b/web/static/css/site.screen.css @@ -0,0 +1,763 @@ +:root { + + --flowColor:#024; + --flowBg:#FFF; + --flowAltBg:#CDF; + --flowAltBorder:0.0625rem solid #04F; + --flowAnchorNormal:#04F; + --flowAnchorVisited:#000; + --flowAnchorHover:#069; + --flowMarker:#080; + + --flyoutColor:#36C; + --flyoutBgColor:#ACE; + + --chromeColor:#000; + --chromeBg:var(--flowBg); + --chromeAnchorNormal:var(--chromeColor); + --chromeAnchorVisited:var(--chromeColor); + --chromeAnchorHover:#369; + + --mainHeadingColor:#356; + + --modalOuterBg:#ACEC; + --modalOuterShadow:inset 0 0 16em #68A; + --modalInnerBg:#DEF; + --modalInputBg:#FFF; + --modalInputBorder:0.125rem solid #048; + --modalHeadingBg:#ACE; + --modalButtonColor:#FFF; + --modalButtonBg:#048; + --modalShadow:0.5rem 0.5rem 2rem #0247; + + --actionColor:#039; + --actionBg:#FFF; + --actionBorder:0.125rem solid var(--actionColor); + --actionHoverColor:#FFF; + --actionHoverBg:#05A; + + --heroColor:#FFF; + --heroBgColor:#05A; + --heroBg:linear-gradient(20deg, #05A, #012); + --heroTextShadow: + 0 0 2rem #000, + 0.25rem 0.25rem 1rem #000; + + --heroActionColor:#FFF; + --heroActionBg:transparent; + --heroActionHoverColor:#036; + --heroActionHoverBg:#8CF; + + --borderColor:#048; + --standardBorder:0.125rem solid var(--borderColor); + + + --horzPad:clamp(0.5rem, 4vw, 2rem); + --vertPad:clamp(1rem, min(8vw, 10vh), 4rem); + --standardPad:var(--vertPad) var(--horzPad); + --chromePad:1rem var(--horzPad); + --heroPad:clamp(1rem, 3vh, 6rem) var(--horzPad); + +} + +html,body,div,p,h1,h2,h3,h4,h5,h6,figure, +ul,ol,li,dl,dt,dd,form,fieldset,caption,legend, +table,tr,td,th,address,blockquote,img { + margin:0; + padding:0; +} + +img, fieldset { + border:none; +} + +blockquote, q { + quotes:none; +} + +body *, *:after, *:before { + box-sizing:border-box; +} + +legend { + -webkit-appearance: none; + -moz-appearance: none; + appearance: none; + display:block; +} + +button, label, summary { + cursor:pointer; +} + +html, body { + height:100%; +} + +body, button, input, table, textarea, select { + font-size:1rem; + line-height:1.75; + font-family:flowtext,sans-serif; + color:var(--flowColor); + background:var(--flowBg); +} + +a { + color:var(--flowAnchorNormal); + transition:color 0.3s, background 0.3s, scale 0.3s; +} + +a:visited { + color:var(--flowAnchorVisited); +} + +a:active, +a:focus, +a:hover { + color:var(--flowAnchorHover); +} + +input, +select, +textarea { + padding:0.25rem 0.5rem; +} + +#fauxBody, +.modal, +.modal > .modalClose { + position:fixed; + top:0; + left:0; + width:100%; + height:100%; + overflow:auto; + scroll-behavior:smooth; +} + +.modal, +#top, +.cards, +.hasPlate, +#fauxBody > footer { + position:relative; + display:flex; + flex-wrap:wrap; + align-items:center; + justify-content:center; +} + +.modalClose span, +.mainMenuOpen span, +#fauxBody > footer h2.optional { + position:fixed; + right:999em; + top:0; + opacity:0; +} + +.modal { + left:-200vw; + background:var(--modalOuterBg); + box-shadow:var(--modalOuterShadow); + opacity:0; + transition:left 0s 0.5s, opacity 0.5s; +} + +.modal:target { + left:0; + opacity:1; + transition:opacity 0.5s; +} + +.modal > div { + /* + depth sort over outer .modalClose + */ + position:relative; + /* + if you don't auto margin, scrolling at small screen heights is messed. + */ + margin:auto 1rem; + overflow:hidden; + background:var(--modalInnerBg); + color:var(--flowColor); + box-shadow:var(--modalShadow); + border:var(--standardBorder); + border-radius:1rem; + scale:0; + transition:scale 0.5s; +} + +.modal:target > div { + scale:1; +} + +.modal .modalClose, +#mainMenu .modalClose { + position:absolute; + text-decoration:none; +} + +.modal:target .modalClose { + display:block; +} + +.modal > * > .modalClose, +#mainMenu > * > .modalClose { + top:0.5rem; + right:1rem; + font-size:2rem; + line-height:1; + color:var(--flowColor); +} + +.modal > * > .modalClose:focus, +.modal > * > .modalClose:hover { + scale:1.2; +} + +.modal h2 { + font-size:1.25rem; + padding:0.5rem 4rem 0.5rem 1rem; + margin-bottom:1rem; + background:var(--modalHeadingBg); + border-bottom:var(--standardBorder); +} + +.modal h2 ~ * { + margin:1rem; +} + +#top, +#fauxBody > footer { + max-width:72rem; + margin:0 auto; + padding:var(--chromePad); + background:var(--chromeBgColor); + color:var(--chromeColor); +} + +#fauxBody > footer { + z-index:800; +} + +#fauxBody > footer p span { + display:inline-block; +} + +#top { + justify-content:space-between; + gap:2rem; + z-index:900; +} + +#top a, +#fauxBody > footer a { + color:var(--chromeAnchorNormal); + text-decoration:none; +} + +#top > a:first-child { + display:block; + overflow:hidden; + flex-grow:0; + font-size:0.875rem; + line-height:1.1; +} + +h1 { + font-size:2rem; + text-transform:uppercase; + transform-origin:center left; + letter-spacing:0.125rem; + scale:1.15 1; + color:var(--mainHeadingColor); +} + +#mainMenu { + flex-grow:1; + text-align:right; +} + +#mainMenu li { + list-style:none; + display:inline; + margin-right:1.5rem; +} + +#mainMenu li a { + display:inline-block; + font-size:1.125rem; +} + +#mainMenu li a:focus, +#mainMenu li a:hover, +.socialMenu a:focus, +.socialMenu a:hover, +.mainMenuOpen:focus, +.mainMenuOpen:hover { + color:var(--chromeAnchorHover); + scale:1.2; +} + +#fauxBody > footer > section:first-child { + width:1%; + flex-grow:1; +} + +.socialMenu { + list-style:none; + display:flex; + gap:1.5rem; +} + +.socialMenu a { + position:relative; + display:block; +} + +.socialMenu a:before { + font-size:2.5rem; + transition:color 0.3s, scale 0.3s; +} + +.socialMenu a:focus:before, +.socialMenu a:hover:before { + scale:1.375; +} + +.socialMenu a span, +#backToTop span { + position:absolute; + font-size:0.875rem; + color:var(--flyoutColor); + background:var(--flyoutBgColor); + border:0.125rem solid var(--flyoutColor); +} + +.socialMenu a span { + bottom:3.5rem; + right:999em; + padding:0.25rem 0.75rem; + white-space:nowrap; + border-radius:1rem; + transition:right 0s 0.3s, opacity 0.3s; + opacity:0; +} + +.socialMenu a span:after { + content:""; + position:absolute; + bottom:-0.5625rem; + right:1rem; + width:1rem; + height:1rem; + background:var(--flyoutBgColor); + border:solid var(--flyoutColor); + border-width:0 0.125rem 0.125rem 0; + rotate:45deg; +} + +.socialMenu a:focus span, +.socialMenu a:hover span { + right:-0.5rem; + opacity:1; + transition:opacity 0.3s; +} + +main > section:not(.hero), +.hero > div, +.hasCards > header, +.hasPlate { + max-width:56rem; + margin:0 auto; +} + +main > section:not(.hero), +.hero > div, +.hasPlate { + padding:var(--standardPad); +} + +.hasPlate { + padding-top:0; +} + +main > section:not(.hero) { + border-bottom:var(--flowAltBorder); +} + +main > section > header:not(.hasPlate) { + text-align:center; +} + +main > section:not(.hero):nth-child(odd) { + background:var(--flowAltBg); +} + +main h2 { + font-size:clamp(1.75rem, 5vw, 2.5rem); + font-weight:normal; +} + +main h2 span { + display:inline-block; /* soft keep-together */ +} + +main h3 { + font-size:clamp(1.25rem, 3vw, 2rem); + font-weight:normal; +} + +main p { + max-width:40em; + margin:1em 0; +} + +main section > header p { + font-size:1.125rem; +} + +main > section > header:not(.hasPlate) p { + margin:1em auto; +} + +main > section.hasCards { + max-width:100%; +} + +.cards, +.hasPlate { + gap:2rem; +} + +.cards { + margin:2rem auto 0; + align-items:stretch; + gap:2rem 4rem; +} + +#whatIDo .cards { + max-width:68em; +} + +.cards > * { + flex-grow:1; + width:1%; + min-width:min(20rem, 100%); + max-width:24rem; +} + +#whatIDo .cards > * { + min-width:min(24rem, 100%); + max-width:40rem; +} + +.cards h3[class*="icon_"]:before { + font-size:4rem; + margin-right:1rem; +} + +.cards li { + list-style:none; + position:Relative; + margin-bottom:0.5rem; + padding-left:2rem; +} + +.cards li:before { + content:"\F058"; + position:absolute; + top:0; + left:0.5rem; + color:var(--flowMarker); + font-family:interface; +} + +.hasPlate > div { + flex-grow:1; + width:1%; + min-width:min(20rem, 100%); +} + +.hasPlate.trailing > figure, +.hasPlate.trailing > picture { + position:relative; + flex-grow:0; + width:30%; + max-width:16rem; + text-align:center; +} + +figure img, +figure picture { + width:100%; + height:auto; + border-radius:1rem; +} + +.note { + text-align:center; +} + +.action { + display:inline-block; + position:relative; + overflow:hidden; + margin-top:1rem; + z-index:1; + text-decoration:none; + padding:0.75rem 1.5rem; + color:var(--actionColor); + background:var(--actionBg); + border:var(--actionBorder); + border-radius:0.5em; + transition:color 0.3s, text-shadow 0.3s; +} + +.action:focus, +.action:hover { + color:var(--actionHoverColor); + text-shadow:none; +} + +.action:after { + content:""; + position:absolute; + z-index:-1; + top:50%; + left:50%; + width:100%; + height:100%; + border-radius:0.5rem; + translate:-50% -50%; + scale:0; + opacity:0; + background:var(--actionHoverBg); + transition:scale 0.3s, opacity 0.3s; +} + +.action:focus:after, +.action:hover:after { + scale:1.1; + opacity:1; +} + +.hero { + padding:var(--heroPad); + background-color:var(--heroBgColor); + color:var(--heroColor); + text-shadow:var(--heroTextShadow); +} + +.hero .action { + color:var(--heroActionColor); + background:var(--heroActionBg); + border-color:var(--heroActionColor); +} + +.hero .action:focus, +.hero .action:hover { + color:var(--heroActionHoverColor); +} + +.hero .action:after { + background:var(--heroActionHoverBg); +} + +.hero header { + margin-bottom:1.5rem; + line-height:1.2; +} + +.hero header p { + margin:0.25rem 0 1.5rem; + font-size:1.5rem; +} + +#semanticEasy { + background-image:url(images/heroBg.avif), var(--heroBg); + background-position:center; + background-size:cover; +} + +section:not(.hero) h2, +section:not(.hero) h3 { + color:var(--mainHeadingColor); +} + +#testimonials > header { + margin-bottom:var(--vertPad); +} + +#testimonials > .cards { + max-width:76rem; + margin:0 auto; +} + +#testimonials figcaption { + font-size:1.25rem; + font-style:italic; +} + +#testimonials figcaption img { + display:inline-block; + vertical-align:middle; + width:4rem; + height:4rem; + margin-right:0.5rem; + border-radius:50%; +} + +#backToTop { + display:block; + position:sticky; + z-index:600; + bottom:0; + width:2.5rem; + height:3.5rem; + padding-bottom:1rem; + margin:-3.5rem 1rem 0 auto; + opacity:0.6; + transition:opacity 0.3s; +} + +#backToTop.hide { + opacity:0; +} + +#backToTop:not(.hide):focus, +#backToTop:not(.hide):hover { + opacity:1; +} + +#backToTop span { + right:1.5rem; + top:0.25rem; + padding:0.125rem 2rem 0.125rem 1rem; + white-space:nowrap; + border-radius:1.5rem 0 0 1.5rem; + transform-origin:center right; + transition:scale 0.3s; + scale:0 1; +} + +#backToTop:focus span, +#backToTop:hover span { + scale:1; +} + +#backToTop:after { + content:"\F102"; + position:relative; + display:block; + width:2.5rem; + height:2.5rem; + text-align:center; + font-family:interface; + font-size:1.5rem; + line-height:2rem; + border:0.25rem solid var(--flyoutColor); + border-radius:50%; + background:var(--heroBgColor); + color:var(--heroColor); +} + +@media (max-width:56rem) { + + /* + It sucks to have to repeat all this, + one of the few cases where native mixins + would be a godsend. + */ + + #mainMenu, + #mainMenu > .modalClose { + top:0; + left:0; + width:100%; + height:100%; + overflow:auto; + scroll-behavior:smooth; + } + + #mainMenu { + position:fixed; + display:flex; + flex-wrap:wrap; + align-items:center; + justify-content:center; + left:-200vw; + background:var(--modalOuterBg); + box-shadow:var(--modalOuterShadow); + opacity:0; + transition:left 0s 0.5s, opacity 0.5s; + } + + #mainMenu:target { + left:0; + opacity:1; + transition:opacity 0.5s; + } + + #mainMenu > div { + position:relative; + margin:auto 1rem; + overflow:hidden; + background:var(--modalInnerBg); + color:var(--flowColor); + box-shadow:var(--modalShadow); + border:var(--standardBorder); + border-radius:1rem; + scale:0; + transition:scale 0.5s; + } + + #mainMenu:target > div { + scale:1; + } + + #mainMenu:target .modalClose { + display:block; + } + + #mainMenu > * > .modalClose:focus, + #mainMenu > * > .modalClose:hover { + scale:1.2; + } + + #mainMenu > div:before { + content:attr(data-modalTitle); + display:block; + font-size:1.25rem; + padding:0.5rem 4rem 0.5rem 1rem; + margin-bottom:1rem; + background:var(--modalHeadingBg); + border-bottom:var(--standardBorder); + } + + #mainMenu ul { + margin:1rem; + } + + #mainMenu li { + display:block; + text-align:center; + margin:0.5rem 0; + } + + .mainMenuOpen { + display:block; + width:2.5rem; + height:2rem; + background:linear-gradient( + #000 20%, + transparent 20% 40%, + #000 40% 60%, + transparent 60% 80%, + #000 80% + ); + } + +} /* max-width:56rem */ diff --git a/web/static/favicon.ico b/web/static/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..92cf612e8aa71f5300cccd40ddf1002d07dde463 GIT binary patch literal 38037 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 literal 0 HcmV?d00001 diff --git a/web/static/favicon.svg b/web/static/favicon.svg new file mode 100644 index 0000000..695b119 --- /dev/null +++ b/web/static/favicon.svg @@ -0,0 +1 @@ +