cleanup starter template, add watch command
This commit is contained in:
parent
9423171ef8
commit
6762a22a5d
33 changed files with 415 additions and 180 deletions
51
.air.toml
51
.air.toml
|
|
@ -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
|
||||
|
|
@ -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}}'
|
||||
|
|
@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
3
sandbox/assets/css/input.css
Normal file
3
sandbox/assets/css/input.css
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
@tailwind base;
|
||||
@tailwind components;
|
||||
@tailwind utilities;
|
||||
36
sandbox/assets/css/tailwind.config.js
Normal file
36
sandbox/assets/css/tailwind.config.js
Normal file
|
|
@ -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: [],
|
||||
};
|
||||
BIN
sandbox/assets/css/tailwindcss
Executable file
BIN
sandbox/assets/css/tailwindcss
Executable file
Binary file not shown.
26
sandbox/go.mod
Normal file
26
sandbox/go.mod
Normal file
|
|
@ -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
|
||||
)
|
||||
31
sandbox/go.sum
Normal file
31
sandbox/go.sum
Normal file
|
|
@ -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=
|
||||
50
sandbox/main.go
Normal file
50
sandbox/main.go
Normal file
|
|
@ -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,
|
||||
})
|
||||
}
|
||||
25
sandbox/pages/base/root.go
Normal file
25
sandbox/pages/base/root.go
Normal file
|
|
@ -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...),
|
||||
),
|
||||
),
|
||||
)
|
||||
}
|
||||
20
sandbox/pages/generated.go
Normal file
20
sandbox/pages/generated.go
Normal file
|
|
@ -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))
|
||||
})
|
||||
}
|
||||
89
sandbox/pages/index.go
Normal file
89
sandbox/pages/index.go
Normal file
|
|
@ -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 type="module">
|
||||
%s
|
||||
</script>
|
||||
`, script),
|
||||
)
|
||||
}
|
||||
44
sandbox/partials/load/generated.go
Normal file
44
sandbox/partials/load/generated.go
Normal file
|
|
@ -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)
|
||||
})
|
||||
}
|
||||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
|
|
|
|||
|
|
@ -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...),
|
||||
|
|
|
|||
|
|
@ -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))
|
||||
})
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 type="module">
|
||||
%s
|
||||
</script>
|
||||
`, script),
|
||||
)
|
||||
}
|
||||
|
|
|
|||
14
starter-template/partials/index.go
Normal file
14
starter-template/partials/index.go
Normal file
|
|
@ -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."))))
|
||||
}
|
||||
|
|
@ -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
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue