diff --git a/.air.toml b/.air.toml
deleted file mode 100644
index 8a840b4..0000000
--- a/.air.toml
+++ /dev/null
@@ -1,51 +0,0 @@
-root = "."
-testdata_dir = "testdata"
-tmp_dir = "tmp"
-
-[build]
- args_bin = []
- bin = "./tmp/main"
- cmd = "go build -o ./tmp/main ."
- delay = 1000
- exclude_dir = ["assets", "tmp", "vendor", "testdata", "node_modules", "js"]
- exclude_file = []
- exclude_regex = ["_test.go"]
- exclude_unchanged = false
- follow_symlink = false
- full_bin = ""
- include_dir = []
- include_ext = ["go", "tpl", "tmpl", "html"]
- include_file = []
- kill_delay = "0s"
- log = "build-errors.log"
- poll = false
- poll_interval = 0
- post_cmd = []
- pre_cmd = []
- rerun = false
- rerun_delay = 500
- send_interrupt = false
- stop_on_error = false
-
-[color]
- app = ""
- build = "yellow"
- main = "magenta"
- runner = "green"
- watcher = "cyan"
-
-[log]
- main_only = false
- time = false
-
-[misc]
- clean_on_exit = false
-
-[proxy]
- app_port = 0
- enabled = false
- proxy_port = 0
-
-[screen]
- clear_on_rebuild = false
- keep_scroll = true
diff --git a/framework/tooling/htmgo/Taskfile.yml b/framework/tooling/htmgo/Taskfile.yml
index 4f21af0..b61c5a3 100644
--- a/framework/tooling/htmgo/Taskfile.yml
+++ b/framework/tooling/htmgo/Taskfile.yml
@@ -57,6 +57,26 @@ tasks:
- chmod +x ./assets/css/tailwindcss
- ./assets/css/tailwindcss -i ./assets/css/input.css -o ./assets/dist/main.css -c ./assets/css/tailwind.config.js
+ go-watch:
+ deps: [setup]
+ dir: '{{.USER_WORKING_DIR}}'
+ desc: Run the project and watch for changes
+ cmds:
+ - air -build.exclude_dir "dist"
+
+ css-watch:
+ dir: '{{.USER_WORKING_DIR}}'
+ desc: Generate CSS from source code and watch for changes
+ watch: true
+ generates:
+ - '**/main.css'
+ sources:
+ - '**/*.css'
+ - '**/*.go'
+ cmds:
+ - task: css
+ dir: '{{.USER_WORKING_DIR}}'
+
ast:
dir: '{{.USER_WORKING_DIR}}'
desc: Generate AST from source code
@@ -72,7 +92,8 @@ tasks:
generates:
- '**/generated.go'
sources:
- - '**/*.go'
+ - 'pages/**/*.go'
+ - 'partials/**/*.go'
cmds:
- task: ast
dir: '{{.USER_WORKING_DIR}}'
\ No newline at end of file
diff --git a/framework/tooling/htmgo/runner.go b/framework/tooling/htmgo/runner.go
index bf77949..7d3ea8c 100644
--- a/framework/tooling/htmgo/runner.go
+++ b/framework/tooling/htmgo/runner.go
@@ -7,6 +7,7 @@ import (
"os"
"os/exec"
"strings"
+ "sync"
)
//go:embed Taskfile.yml
@@ -14,7 +15,7 @@ var taskFile string
func main() {
commandMap := make(map[string]*flag.FlagSet)
- commands := []string{"template", "run", "build", "setup", "css"}
+ commands := []string{"template", "run", "build", "setup", "css", "css-watch", "ast-watch", "watch", "go-watch", "watch"}
for _, command := range commands {
commandMap[command] = flag.NewFlagSet(command, flag.ExitOnError)
@@ -58,15 +59,36 @@ func main() {
os.WriteFile(temp.Name(), []byte(taskFile), 0644)
- // Define the command and arguments
- cmd := exec.Command("task", "-t", temp.Name(), os.Args[1])
- // Set the standard output and error to be the same as the Go program
- cmd.Stdout = os.Stdout
- cmd.Stderr = os.Stderr
- // Run the command
- err = cmd.Run()
- if err != nil {
- fmt.Printf("Error running task command: %v\n", err)
- return
+ taskName := os.Args[1]
+
+ if taskName == "watch" {
+ tasks := []string{"css-watch", "ast-watch", "go-watch"}
+ wg := sync.WaitGroup{}
+ for _, task := range tasks {
+ wg.Add(1)
+ go func() {
+ cmd := exec.Command("task", "-t", temp.Name(), task)
+ cmd.Stdout = os.Stdout
+ cmd.Stderr = os.Stderr
+ err := cmd.Run()
+ if err != nil {
+ fmt.Printf("Error running task command: %v\n", err)
+ }
+ wg.Done()
+ }()
+ }
+ wg.Wait()
+ } else {
+ // Define the command and arguments
+ cmd := exec.Command("task", "-t", temp.Name(), os.Args[1])
+ // Set the standard output and error to be the same as the Go program
+ cmd.Stdout = os.Stdout
+ cmd.Stderr = os.Stderr
+ // Run the command
+ err = cmd.Run()
+ if err != nil {
+ fmt.Printf("Error running task command: %v\n", err)
+ return
+ }
}
}
diff --git a/sandbox/assets/css/input.css b/sandbox/assets/css/input.css
new file mode 100644
index 0000000..bd6213e
--- /dev/null
+++ b/sandbox/assets/css/input.css
@@ -0,0 +1,3 @@
+@tailwind base;
+@tailwind components;
+@tailwind utilities;
\ No newline at end of file
diff --git a/sandbox/assets/css/tailwind.config.js b/sandbox/assets/css/tailwind.config.js
new file mode 100644
index 0000000..07d3a7b
--- /dev/null
+++ b/sandbox/assets/css/tailwind.config.js
@@ -0,0 +1,36 @@
+const {join} = require("node:path");
+/** @type {import('tailwindcss').Config} */
+const root = join(__dirname, "../../");
+const contentGo = join(root, "**/*.go");
+const contentJs = join(root, "**/pages/**/*.js");
+
+
+module.exports = {
+ content: [contentGo, contentJs],
+ theme: {
+ extend: {
+ colors: {
+ background: 'hsl(224, 71.4%, 4.1%)',
+ foreground: 'hsl(0, 0%, 89%)',
+ card: 'hsl(224, 71.4%, 4.1%)',
+ cardForeground: 'hsl(0, 0%, 89%)',
+ popover: 'hsl(224, 71.4%, 4.1%)',
+ popoverForeground: 'hsl(0, 0%, 89%)',
+ primary: 'hsl(0, 0%, 89%)',
+ primaryForeground: 'hsl(220.9, 39.3%, 11%)',
+ secondary: 'hsl(215, 27.9%, 16.9%)',
+ secondaryForeground: 'hsl(0, 0%, 89%)',
+ muted: 'hsl(215, 27.9%, 16.9%)',
+ mutedForeground: 'hsl(217.9, 10.6%, 64.9%)',
+ accent: 'hsl(215, 27.9%, 16.9%)',
+ accentForeground: 'hsl(0, 0%, 89%)',
+ destructive: 'hsl(0, 62.8%, 30.6%)',
+ destructiveForeground: 'hsl(0, 0%, 89%)',
+ border: 'hsl(215, 27.9%, 16.9%)',
+ input: 'hsl(215, 27.9%, 16.9%)',
+ ring: 'hsl(216, 12.2%, 83.9%)',
+ },
+ },
+ },
+ plugins: [],
+};
diff --git a/sandbox/assets/css/tailwindcss b/sandbox/assets/css/tailwindcss
new file mode 100755
index 0000000..f012497
Binary files /dev/null and b/sandbox/assets/css/tailwindcss differ
diff --git a/starter-template/database/database.go b/sandbox/database/database.go
similarity index 100%
rename from starter-template/database/database.go
rename to sandbox/database/database.go
diff --git a/starter-template/features/patient/patient-service.go b/sandbox/features/patient/patient-service.go
similarity index 100%
rename from starter-template/features/patient/patient-service.go
rename to sandbox/features/patient/patient-service.go
diff --git a/sandbox/go.mod b/sandbox/go.mod
new file mode 100644
index 0000000..b3b4319
--- /dev/null
+++ b/sandbox/go.mod
@@ -0,0 +1,26 @@
+module sandbox
+
+go 1.23.0
+
+require (
+ github.com/gofiber/fiber/v2 v2.52.5
+ github.com/google/uuid v1.6.0
+ github.com/maddalax/htmgo/framework v0.0.0-20240914010415-2397bf9fb057
+ github.com/maddalax/htmgo/framework-ui v0.0.0-20240914003619-c256552b2143
+ github.com/redis/go-redis/v9 v9.6.1
+)
+
+require (
+ github.com/andybalholm/brotli v1.0.5 // indirect
+ github.com/cespare/xxhash/v2 v2.2.0 // indirect
+ github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect
+ github.com/klauspost/compress v1.17.0 // indirect
+ github.com/mattn/go-colorable v0.1.13 // indirect
+ github.com/mattn/go-isatty v0.0.20 // indirect
+ github.com/mattn/go-runewidth v0.0.15 // indirect
+ github.com/rivo/uniseg v0.2.0 // indirect
+ github.com/valyala/bytebufferpool v1.0.0 // indirect
+ github.com/valyala/fasthttp v1.51.0 // indirect
+ github.com/valyala/tcplisten v1.0.0 // indirect
+ golang.org/x/sys v0.25.0 // indirect
+)
diff --git a/sandbox/go.sum b/sandbox/go.sum
new file mode 100644
index 0000000..7297dd0
--- /dev/null
+++ b/sandbox/go.sum
@@ -0,0 +1,31 @@
+github.com/andybalholm/brotli v1.0.5 h1:8uQZIdzKmjc/iuPu7O2ioW48L81FgatrcpfFmiq/cCs=
+github.com/andybalholm/brotli v1.0.5/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig=
+github.com/gofiber/fiber/v2 v2.52.5 h1:tWoP1MJQjGEe4GB5TUGOi7P2E0ZMMRx5ZTG4rT+yGMo=
+github.com/gofiber/fiber/v2 v2.52.5/go.mod h1:KEOE+cXMhXG0zHc9d8+E38hoX+ZN7bhOtgeF2oT6jrQ=
+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/klauspost/compress v1.17.0 h1:Rnbp4K9EjcDuVuHtd0dgA4qNuv9yKDYKK1ulpJwgrqM=
+github.com/klauspost/compress v1.17.0/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE=
+github.com/maddalax/htmgo/framework v0.0.0-20240914010415-2397bf9fb057 h1:DTc3qPMvwrh6wPIusGmQ1jPxngy7T6maUDh5RwYf6H0=
+github.com/maddalax/htmgo/framework v0.0.0-20240914010415-2397bf9fb057/go.mod h1:O8ogYQjCn5iD9CzjdRgfrJfP9uMpx8rrx6YD5N4AecY=
+github.com/maddalax/htmgo/framework-ui v0.0.0-20240914003619-c256552b2143 h1:aGpoab8N9rzXJAHIP8WiW5CsHjpSCrGlnbd0bQCRS3g=
+github.com/maddalax/htmgo/framework-ui v0.0.0-20240914003619-c256552b2143/go.mod h1:Z8Mym1vqAMNcgtu1sHbWwQIwTvtNr6VqRZhKBweiCNE=
+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=
+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/mattn/go-runewidth v0.0.15 h1:UNAjwbU9l54TA3KzvqLGxwWjHmMgBUVhBiTjelZgg3U=
+github.com/mattn/go-runewidth v0.0.15/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
+github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY=
+github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
+github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw=
+github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
+github.com/valyala/fasthttp v1.51.0 h1:8b30A5JlZ6C7AS81RsWjYMQmrZG6feChmgAolCl1SqA=
+github.com/valyala/fasthttp v1.51.0/go.mod h1:oI2XroL+lI7vdXyYoQk03bXBThfFl2cVdIA3Xl7cH8g=
+github.com/valyala/tcplisten v1.0.0 h1:rBHj/Xf+E1tRGZyWIWwJDiRY0zc1Js+CV5DqwacVSA8=
+github.com/valyala/tcplisten v1.0.0/go.mod h1:T0xQ8SeCZGxckz9qRXTfG43PvQ/mcWh7FwZEA7Ioqkc=
+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.25.0 h1:r+8e+loiHxRqhXVl6ML1nO3l1+oFoWbnlu2Ehimmi34=
+golang.org/x/sys v0.25.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
diff --git a/sandbox/main.go b/sandbox/main.go
new file mode 100644
index 0000000..b0e8038
--- /dev/null
+++ b/sandbox/main.go
@@ -0,0 +1,50 @@
+package main
+
+import (
+ "github.com/gofiber/fiber/v2"
+ "github.com/google/uuid"
+ "github.com/maddalax/htmgo/framework/h"
+ "log"
+ "starter-template/pages"
+ "starter-template/partials/load"
+ "time"
+)
+
+func main() {
+ f := fiber.New()
+
+ f.Static("/public", "./assets/dist")
+
+ f.Use(func(ctx *fiber.Ctx) error {
+ if ctx.Cookies("htmgo-session") != "" {
+ return ctx.Next()
+ }
+ id := ctx.IP() + uuid.NewString()
+ ctx.Cookie(&fiber.Cookie{
+ Name: "htmgo-session",
+ Value: id,
+ SessionOnly: true,
+ })
+ return ctx.Next()
+ })
+
+ f.Use(func(ctx *fiber.Ctx) error {
+ if ctx.Path() == "/livereload" {
+ return ctx.Next()
+ }
+ now := time.Now()
+ err := ctx.Next()
+ duration := time.Since(now)
+ ctx.Set("X-Response-Time", duration.String())
+ // Log or print the request method, URL, and duration
+ log.Printf("Request: %s %s took %dms", ctx.Method(), ctx.OriginalURL(), duration.Milliseconds())
+ return err
+ })
+
+ load.RegisterPartials(f)
+ pages.RegisterPages(f)
+
+ h.Start(f, h.App{
+ LiveReload: true,
+ })
+}
diff --git a/starter-template/news/posts.go b/sandbox/news/posts.go
similarity index 100%
rename from starter-template/news/posts.go
rename to sandbox/news/posts.go
diff --git a/starter-template/news/views.go b/sandbox/news/views.go
similarity index 100%
rename from starter-template/news/views.go
rename to sandbox/news/views.go
diff --git a/sandbox/pages/base/root.go b/sandbox/pages/base/root.go
new file mode 100644
index 0000000..8000eb9
--- /dev/null
+++ b/sandbox/pages/base/root.go
@@ -0,0 +1,25 @@
+package base
+
+import (
+ "github.com/maddalax/htmgo/framework/h"
+ "starter-template/partials"
+ "starter-template/partials/sheet"
+)
+
+func RootPage(children ...h.Renderable) h.Renderable {
+ return h.Html(
+ h.HxExtension("path-deps, response-targets, mutation-error"),
+ h.Head(
+ h.Link("/public/main.css", "stylesheet"),
+ h.Script("/public/htmgo.js"),
+ ),
+ h.Body(
+ partials.NavBar(),
+ sheet.Closed(),
+ h.Div(
+ h.Class("flex flex-col gap-2 bg-white h-full"),
+ h.Fragment(children...),
+ ),
+ ),
+ )
+}
diff --git a/sandbox/pages/generated.go b/sandbox/pages/generated.go
new file mode 100644
index 0000000..5fa743a
--- /dev/null
+++ b/sandbox/pages/generated.go
@@ -0,0 +1,20 @@
+// Package pages THIS FILE IS GENERATED. DO NOT EDIT.
+package pages
+
+import "github.com/gofiber/fiber/v2"
+import "github.com/maddalax/htmgo/framework/h"
+
+func RegisterPages(f *fiber.App) {
+ f.Get("/", func(ctx *fiber.Ctx) error {
+ return h.HtmlView(ctx, IndexPage(ctx))
+ })
+ f.Get("/news/:id", func(ctx *fiber.Ctx) error {
+ return h.HtmlView(ctx, Test(ctx))
+ })
+ f.Get("/news", func(ctx *fiber.Ctx) error {
+ return h.HtmlView(ctx, ListPage(ctx))
+ })
+ f.Get("/patients", func(ctx *fiber.Ctx) error {
+ return h.HtmlView(ctx, PatientsIndex(ctx))
+ })
+}
diff --git a/sandbox/pages/index.go b/sandbox/pages/index.go
new file mode 100644
index 0000000..56d01e1
--- /dev/null
+++ b/sandbox/pages/index.go
@@ -0,0 +1,89 @@
+package pages
+
+import (
+ "fmt"
+ "github.com/gofiber/fiber/v2"
+ "github.com/maddalax/htmgo/framework/h"
+ "os"
+ "time"
+)
+
+func IndexPage(c *fiber.Ctx) *h.Page {
+ return h.NewPage(h.Html(
+ h.Class("bg-background flex flex-col items-center"),
+ h.Head(
+ h.Link("/public/main.css", "stylesheet"),
+ h.Script("/public/htmgo.js"),
+ h.Script("/public/scripts/shiki.js"),
+ ),
+ h.Body(
+ h.Class("flex flex-col gap-3"),
+ // Navbar
+ h.Div(
+ h.Class("flex justify-between items-center w-full p-6"),
+ h.Div(
+ h.Class("text-white text-xl font-bold"),
+ h.Text("htmgo"),
+ ),
+ h.Div(
+ h.Class("flex gap-4"),
+ h.A(h.Href("/pricing"), h.Class("text-white"), h.Text("Pricing")),
+ h.A(h.Href("/docs"), h.Class("text-white"), h.Text("Docs")),
+ h.A(h.Href("/app"), h.Class("text-white"), h.Text("App")),
+ ),
+ ),
+
+ // Hero Section
+ h.Div(
+ h.Class("flex flex-col items-center justify-center gap-6 p-12 bg-background text-center"),
+ h.H1(
+ h.Class("text-white text-4xl sm:text-5xl font-bold max-w-3xl"),
+ h.Text("Go and HTMX: The Simple Stack"),
+ ),
+ h.P(
+ h.Class("text-white text-lg sm:text-xl max-w-2xl"),
+ h.Text("Combine the simplicity of Go with the power of HTMX for dynamic, JavaScript-light web development."),
+ ),
+ h.A(h.Href("/get-started"),
+ h.Class("bg-white text-background px-6 py-3 rounded-md font-semibold mt-4"),
+ h.Text("Join the waitlist"),
+ ),
+ ),
+
+ // Explore Section
+ h.Div(
+ h.Class("w-full max-w-4xl"),
+ CodeExample(),
+ ),
+
+ // Footer Section
+ h.Div(
+ h.Class("flex justify-center items-center py-6"),
+ h.Text(fmt.Sprintf("© %d htmgo", time.Now().Year())),
+ ),
+ ),
+ ))
+}
+
+func CodeExample() h.Renderable {
+ code, err := os.ReadFile("pages/assets/_example.go")
+ scriptSrc, err := os.ReadFile("pages/assets/shiki.js")
+
+ if err != nil {
+ return h.Pf("Error loading code example")
+ }
+
+ fmt.Printf("%s\n", code)
+
+ script := fmt.Sprintf(string(scriptSrc), string(code))
+
+ return h.Div(
+ h.Class("text-white rounded-lg"),
+ h.Pre(h.Id("foo")),
+ h.RawF(`
+
+ `, script),
+ )
+}
diff --git a/starter-template/pages/news.$id.go b/sandbox/pages/news.$id.go
similarity index 100%
rename from starter-template/pages/news.$id.go
rename to sandbox/pages/news.$id.go
diff --git a/starter-template/pages/news.index.go b/sandbox/pages/news.index.go
similarity index 100%
rename from starter-template/pages/news.index.go
rename to sandbox/pages/news.index.go
diff --git a/starter-template/pages/patients.index.go b/sandbox/pages/patients.index.go
similarity index 100%
rename from starter-template/pages/patients.index.go
rename to sandbox/pages/patients.index.go
diff --git a/starter-template/partials/button.go b/sandbox/partials/button.go
similarity index 100%
rename from starter-template/partials/button.go
rename to sandbox/partials/button.go
diff --git a/sandbox/partials/load/generated.go b/sandbox/partials/load/generated.go
new file mode 100644
index 0000000..eb982c4
--- /dev/null
+++ b/sandbox/partials/load/generated.go
@@ -0,0 +1,44 @@
+// Package partials THIS FILE IS GENERATED. DO NOT EDIT.
+package load
+
+import "github.com/maddalax/htmgo/framework/h"
+import "github.com/gofiber/fiber/v2"
+import "starter-template/partials"
+import "starter-template/partials/patient"
+import "starter-template/partials/sheet"
+
+func GetPartialFromContext(ctx *fiber.Ctx) *h.Partial {
+ path := ctx.Path()
+ if path == "NewsSheet" || path == "/starter-template/partials.NewsSheet" {
+ return partials.NewsSheet(ctx)
+ }
+ if path == "NewsSheetOpenCount" || path == "/starter-template/partials.NewsSheetOpenCount" {
+ return partials.NewsSheetOpenCount(ctx)
+ }
+ if path == "Create" || path == "/starter-template/partials/patient.Create" {
+ return patient.Create(ctx)
+ }
+ if path == "List" || path == "/starter-template/partials/patient.List" {
+ return patient.List(ctx)
+ }
+ if path == "AddPatientSheetPartial" || path == "/starter-template/partials/patient.AddPatientSheetPartial" {
+ return patient.AddPatientSheetPartial(ctx)
+ }
+ if path == "ValidateForm" || path == "/starter-template/partials/patient.ValidateForm" {
+ return patient.ValidateForm(ctx)
+ }
+ if path == "Close" || path == "/starter-template/partials/sheet.Close" {
+ return sheet.Close(ctx)
+ }
+ return nil
+}
+
+func RegisterPartials(f *fiber.App) {
+ f.All("starter-template/partials*", func(ctx *fiber.Ctx) error {
+ partial := GetPartialFromContext(ctx)
+ if partial == nil {
+ return ctx.SendStatus(404)
+ }
+ return h.PartialView(ctx, partial)
+ })
+}
diff --git a/starter-template/partials/nav.go b/sandbox/partials/nav.go
similarity index 100%
rename from starter-template/partials/nav.go
rename to sandbox/partials/nav.go
diff --git a/starter-template/partials/news.go b/sandbox/partials/news.go
similarity index 100%
rename from starter-template/partials/news.go
rename to sandbox/partials/news.go
diff --git a/starter-template/partials/patient/create.go b/sandbox/partials/patient/create.go
similarity index 100%
rename from starter-template/partials/patient/create.go
rename to sandbox/partials/patient/create.go
diff --git a/starter-template/partials/patient/patient.go b/sandbox/partials/patient/patient.go
similarity index 100%
rename from starter-template/partials/patient/patient.go
rename to sandbox/partials/patient/patient.go
diff --git a/starter-template/partials/sheet/sheet.go b/sandbox/partials/sheet/sheet.go
similarity index 100%
rename from starter-template/partials/sheet/sheet.go
rename to sandbox/partials/sheet/sheet.go
diff --git a/starter-template/go.mod b/starter-template/go.mod
index 0159586..2e5a6fa 100644
--- a/starter-template/go.mod
+++ b/starter-template/go.mod
@@ -4,16 +4,12 @@ go 1.23.0
require (
github.com/gofiber/fiber/v2 v2.52.5
- github.com/google/uuid v1.6.0
github.com/maddalax/htmgo/framework v0.0.0-20240914010415-2397bf9fb057
- github.com/maddalax/htmgo/framework-ui v0.0.0-20240914003619-c256552b2143
- github.com/redis/go-redis/v9 v9.6.1
)
require (
github.com/andybalholm/brotli v1.0.5 // indirect
- github.com/cespare/xxhash/v2 v2.2.0 // indirect
- github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect
+ github.com/google/uuid v1.6.0 // indirect
github.com/klauspost/compress v1.17.0 // indirect
github.com/mattn/go-colorable v0.1.13 // indirect
github.com/mattn/go-isatty v0.0.20 // indirect
diff --git a/starter-template/main.go b/starter-template/main.go
index b0e8038..505ab53 100644
--- a/starter-template/main.go
+++ b/starter-template/main.go
@@ -2,7 +2,6 @@ package main
import (
"github.com/gofiber/fiber/v2"
- "github.com/google/uuid"
"github.com/maddalax/htmgo/framework/h"
"log"
"starter-template/pages"
@@ -15,19 +14,6 @@ func main() {
f.Static("/public", "./assets/dist")
- f.Use(func(ctx *fiber.Ctx) error {
- if ctx.Cookies("htmgo-session") != "" {
- return ctx.Next()
- }
- id := ctx.IP() + uuid.NewString()
- ctx.Cookie(&fiber.Cookie{
- Name: "htmgo-session",
- Value: id,
- SessionOnly: true,
- })
- return ctx.Next()
- })
-
f.Use(func(ctx *fiber.Ctx) error {
if ctx.Path() == "/livereload" {
return ctx.Next()
diff --git a/starter-template/pages/base/root.go b/starter-template/pages/base/root.go
index 8000eb9..c97875c 100644
--- a/starter-template/pages/base/root.go
+++ b/starter-template/pages/base/root.go
@@ -2,20 +2,21 @@ package base
import (
"github.com/maddalax/htmgo/framework/h"
- "starter-template/partials"
- "starter-template/partials/sheet"
+ "strings"
)
+func Extensions() string {
+ return strings.Join([]string{"path-deps", "response-targets", "mutation-error"}, ", ")
+}
+
func RootPage(children ...h.Renderable) h.Renderable {
return h.Html(
- h.HxExtension("path-deps, response-targets, mutation-error"),
+ h.HxExtension(Extensions()),
h.Head(
h.Link("/public/main.css", "stylesheet"),
h.Script("/public/htmgo.js"),
),
h.Body(
- partials.NavBar(),
- sheet.Closed(),
h.Div(
h.Class("flex flex-col gap-2 bg-white h-full"),
h.Fragment(children...),
diff --git a/starter-template/pages/generated.go b/starter-template/pages/generated.go
index 5fa743a..6500330 100644
--- a/starter-template/pages/generated.go
+++ b/starter-template/pages/generated.go
@@ -8,13 +8,4 @@ func RegisterPages(f *fiber.App) {
f.Get("/", func(ctx *fiber.Ctx) error {
return h.HtmlView(ctx, IndexPage(ctx))
})
- f.Get("/news/:id", func(ctx *fiber.Ctx) error {
- return h.HtmlView(ctx, Test(ctx))
- })
- f.Get("/news", func(ctx *fiber.Ctx) error {
- return h.HtmlView(ctx, ListPage(ctx))
- })
- f.Get("/patients", func(ctx *fiber.Ctx) error {
- return h.HtmlView(ctx, PatientsIndex(ctx))
- })
}
diff --git a/starter-template/pages/index.go b/starter-template/pages/index.go
index 56d01e1..2ad53fe 100644
--- a/starter-template/pages/index.go
+++ b/starter-template/pages/index.go
@@ -1,89 +1,37 @@
package pages
import (
- "fmt"
"github.com/gofiber/fiber/v2"
"github.com/maddalax/htmgo/framework/h"
- "os"
- "time"
+ "starter-template/partials"
)
func IndexPage(c *fiber.Ctx) *h.Page {
return h.NewPage(h.Html(
- h.Class("bg-background flex flex-col items-center"),
+ h.Class("bg-slate-400 flex flex-col items-center h-full w-full"),
h.Head(
h.Link("/public/main.css", "stylesheet"),
h.Script("/public/htmgo.js"),
- h.Script("/public/scripts/shiki.js"),
),
h.Body(
h.Class("flex flex-col gap-3"),
- // Navbar
h.Div(
- h.Class("flex justify-between items-center w-full p-6"),
- h.Div(
- h.Class("text-white text-xl font-bold"),
- h.Text("htmgo"),
- ),
- h.Div(
- h.Class("flex gap-4"),
- h.A(h.Href("/pricing"), h.Class("text-white"), h.Text("Pricing")),
- h.A(h.Href("/docs"), h.Class("text-white"), h.Text("Docs")),
- h.A(h.Href("/app"), h.Class("text-white"), h.Text("App")),
- ),
- ),
-
- // Hero Section
- h.Div(
- h.Class("flex flex-col items-center justify-center gap-6 p-12 bg-background text-center"),
+ h.Class("flex flex-col items-center justify-center gap-6 p-12 text-center"),
h.H1(
- h.Class("text-white text-4xl sm:text-5xl font-bold max-w-3xl"),
- h.Text("Go and HTMX: The Simple Stack"),
+ h.Class("text-4xl sm:text-5xl font-bold max-w-3xl"),
+ h.Text("Welcome to htmgo"),
),
h.P(
- h.Class("text-white text-lg sm:text-xl max-w-2xl"),
+ h.Class("text-lg sm:text-xl max-w-2xl"),
h.Text("Combine the simplicity of Go with the power of HTMX for dynamic, JavaScript-light web development."),
),
- h.A(h.Href("/get-started"),
- h.Class("bg-white text-background px-6 py-3 rounded-md font-semibold mt-4"),
- h.Text("Join the waitlist"),
+ h.Div(
+ h.Button(h.Class("btn bg-blue-500 p-4 rounded text-white"),
+ h.Text("Click here to load a partial"),
+ h.GetPartial(partials.SamplePartial),
+ ),
),
),
-
- // Explore Section
- h.Div(
- h.Class("w-full max-w-4xl"),
- CodeExample(),
- ),
-
- // Footer Section
- h.Div(
- h.Class("flex justify-center items-center py-6"),
- h.Text(fmt.Sprintf("© %d htmgo", time.Now().Year())),
- ),
),
))
}
-
-func CodeExample() h.Renderable {
- code, err := os.ReadFile("pages/assets/_example.go")
- scriptSrc, err := os.ReadFile("pages/assets/shiki.js")
-
- if err != nil {
- return h.Pf("Error loading code example")
- }
-
- fmt.Printf("%s\n", code)
-
- script := fmt.Sprintf(string(scriptSrc), string(code))
-
- return h.Div(
- h.Class("text-white rounded-lg"),
- h.Pre(h.Id("foo")),
- h.RawF(`
-
- `, script),
- )
-}
diff --git a/starter-template/partials/index.go b/starter-template/partials/index.go
new file mode 100644
index 0000000..61a7407
--- /dev/null
+++ b/starter-template/partials/index.go
@@ -0,0 +1,14 @@
+package partials
+
+import (
+ "github.com/gofiber/fiber/v2"
+ "github.com/maddalax/htmgo/framework/h"
+)
+
+func SamplePartial(ctx *fiber.Ctx) *h.Partial {
+ return h.NewPartial(h.Div(h.P(h.Text("This is a sample partials."))))
+}
+
+func NewPartial(ctx *fiber.Ctx) *h.Partial {
+ return h.NewPartial(h.Div(h.P(h.Text("This is a new pardtiasl."))))
+}
diff --git a/starter-template/partials/load/generated.go b/starter-template/partials/load/generated.go
index eb982c4..880f802 100644
--- a/starter-template/partials/load/generated.go
+++ b/starter-template/partials/load/generated.go
@@ -4,31 +4,14 @@ package load
import "github.com/maddalax/htmgo/framework/h"
import "github.com/gofiber/fiber/v2"
import "starter-template/partials"
-import "starter-template/partials/patient"
-import "starter-template/partials/sheet"
func GetPartialFromContext(ctx *fiber.Ctx) *h.Partial {
path := ctx.Path()
- if path == "NewsSheet" || path == "/starter-template/partials.NewsSheet" {
- return partials.NewsSheet(ctx)
+ if path == "SamplePartial" || path == "/starter-template/partials.SamplePartial" {
+ return partials.SamplePartial(ctx)
}
- if path == "NewsSheetOpenCount" || path == "/starter-template/partials.NewsSheetOpenCount" {
- return partials.NewsSheetOpenCount(ctx)
- }
- if path == "Create" || path == "/starter-template/partials/patient.Create" {
- return patient.Create(ctx)
- }
- if path == "List" || path == "/starter-template/partials/patient.List" {
- return patient.List(ctx)
- }
- if path == "AddPatientSheetPartial" || path == "/starter-template/partials/patient.AddPatientSheetPartial" {
- return patient.AddPatientSheetPartial(ctx)
- }
- if path == "ValidateForm" || path == "/starter-template/partials/patient.ValidateForm" {
- return patient.ValidateForm(ctx)
- }
- if path == "Close" || path == "/starter-template/partials/sheet.Close" {
- return sheet.Close(ctx)
+ if path == "NewPartial" || path == "/starter-template/partials.NewPartial" {
+ return partials.NewPartial(ctx)
}
return nil
}