cleanup, get starter template working
This commit is contained in:
parent
939e80968f
commit
52786613dc
30 changed files with 277 additions and 4169 deletions
|
|
@ -3,12 +3,20 @@ package dirutil
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"github.com/maddalax/htmgo/cli/htmgo/tasks/process"
|
||||||
"io"
|
"io"
|
||||||
"log/slog"
|
"log/slog"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func HasFileFromRoot(file string) bool {
|
||||||
|
cwd := process.GetWorkingDir()
|
||||||
|
path := filepath.Join(cwd, file)
|
||||||
|
_, err := os.Stat(path)
|
||||||
|
return err == nil
|
||||||
|
}
|
||||||
|
|
||||||
func CopyDir(srcDir, dstDir string, predicate func(path string, exists bool) bool) error {
|
func CopyDir(srcDir, dstDir string, predicate func(path string, exists bool) bool) error {
|
||||||
// Walk the source directory tree.
|
// Walk the source directory tree.
|
||||||
return filepath.Walk(srcDir, func(srcPath string, info os.FileInfo, err error) error {
|
return filepath.Walk(srcDir, func(srcPath string, info os.FileInfo, err error) error {
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,7 @@ func main() {
|
||||||
done := RegisterSignals()
|
done := RegisterSignals()
|
||||||
|
|
||||||
commandMap := make(map[string]*flag.FlagSet)
|
commandMap := make(map[string]*flag.FlagSet)
|
||||||
commands := []string{"template", "run", "watch", "build", "setup", "css", "schema", "generate", "tailwind-cli"}
|
commands := []string{"template", "run", "watch", "build", "setup", "css", "schema", "generate"}
|
||||||
|
|
||||||
for _, command := range commands {
|
for _, command := range commands {
|
||||||
commandMap[command] = flag.NewFlagSet(command, flag.ExitOnError)
|
commandMap[command] = flag.NewFlagSet(command, flag.ExitOnError)
|
||||||
|
|
@ -69,9 +69,7 @@ func main() {
|
||||||
}()
|
}()
|
||||||
startWatcher(reloader.OnFileChange)
|
startWatcher(reloader.OnFileChange)
|
||||||
} else {
|
} else {
|
||||||
if taskName == "tailwind-cli" {
|
if taskName == "schema" {
|
||||||
css.DownloadTailwindCli()
|
|
||||||
} else if taskName == "schema" {
|
|
||||||
reader := bufio.NewReader(os.Stdin)
|
reader := bufio.NewReader(os.Stdin)
|
||||||
fmt.Print("Enter entity name:")
|
fmt.Print("Enter entity name:")
|
||||||
text, _ := reader.ReadString('\n')
|
text, _ := reader.ReadString('\n')
|
||||||
|
|
|
||||||
|
|
@ -7,8 +7,8 @@ import (
|
||||||
"github.com/maddalax/htmgo/cli/htmgo/tasks/process"
|
"github.com/maddalax/htmgo/cli/htmgo/tasks/process"
|
||||||
"golang.org/x/mod/modfile"
|
"golang.org/x/mod/modfile"
|
||||||
"log"
|
"log"
|
||||||
"log/slog"
|
|
||||||
"os"
|
"os"
|
||||||
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -67,8 +67,13 @@ func CopyAssets() {
|
||||||
err := dirutil.CopyDir(assetDistDir, destDirDist, func(path string, exists bool) bool {
|
err := dirutil.CopyDir(assetDistDir, destDirDist, func(path string, exists bool) bool {
|
||||||
return true
|
return true
|
||||||
})
|
})
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalf("Error: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
err = dirutil.CopyDir(assetCssDir, destDirCss, func(path string, exists bool) bool {
|
err = dirutil.CopyDir(assetCssDir, destDirCss, func(path string, exists bool) bool {
|
||||||
if exists {
|
if strings.HasSuffix(path, "tailwind.config.js") {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
|
|
@ -78,5 +83,14 @@ func CopyAssets() {
|
||||||
log.Fatalf("Error: %v", err)
|
log.Fatalf("Error: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
slog.Debug("successfully copied assets to %s\n", destDir)
|
err = dirutil.CopyFile(
|
||||||
|
filepath.Join(assetCssDir, "tailwind.config.js"),
|
||||||
|
filepath.Join(process.GetWorkingDir(), "tailwind.config.js"),
|
||||||
|
)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalf("Error: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
process.Run(fmt.Sprintf("cd %s && git add .", destDirCss))
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,25 +2,61 @@ package css
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"github.com/maddalax/htmgo/cli/htmgo/internal/dirutil"
|
||||||
|
"github.com/maddalax/htmgo/cli/htmgo/tasks/copyassets"
|
||||||
"github.com/maddalax/htmgo/cli/htmgo/tasks/process"
|
"github.com/maddalax/htmgo/cli/htmgo/tasks/process"
|
||||||
"log"
|
"log"
|
||||||
"log/slog"
|
"log/slog"
|
||||||
"runtime"
|
"runtime"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func IsTailwindEnabled() bool {
|
||||||
|
return dirutil.HasFileFromRoot("tailwind.config.js")
|
||||||
|
}
|
||||||
|
|
||||||
|
func Setup() bool {
|
||||||
|
if !IsTailwindEnabled() {
|
||||||
|
slog.Debug("Tailwind is not enabled. Skipping CSS generation.")
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
downloadTailwindCli()
|
||||||
|
|
||||||
|
if dirutil.HasFileFromRoot("assets/css/input.css") {
|
||||||
|
copyassets.CopyAssets()
|
||||||
|
}
|
||||||
|
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
func GenerateCss(flags ...process.RunFlag) error {
|
func GenerateCss(flags ...process.RunFlag) error {
|
||||||
|
if !Setup() {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
return process.RunMany([]string{
|
return process.RunMany([]string{
|
||||||
"./assets/css/tailwindcss -i ./assets/css/input.css -o ./assets/dist/main.css -c ./assets/css/tailwind.config.js",
|
"./__htmgo/tailwind -i ./assets/css/input.css -o ./assets/dist/main.css -c ./tailwind.config.js",
|
||||||
}, append(flags, process.Silent)...)
|
}, append(flags, process.Silent)...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func GenerateCssWatch(flags ...process.RunFlag) error {
|
func GenerateCssWatch(flags ...process.RunFlag) error {
|
||||||
|
if !Setup() {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
return process.RunMany([]string{
|
return process.RunMany([]string{
|
||||||
"./assets/css/tailwindcss -i ./assets/css/input.css -o ./assets/dist/main.css -c ./assets/css/tailwind.config.js --watch=always",
|
"./__htmgo/tailwind -i ./assets/css/input.css -o ./assets/dist/main.css -c ./tailwind.config.js --watch=always",
|
||||||
}, append(flags, process.KillOnlyOnExit, process.Silent)...)
|
}, append(flags, process.KillOnlyOnExit, process.Silent)...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func DownloadTailwindCli() {
|
func downloadTailwindCli() {
|
||||||
|
|
||||||
|
if dirutil.HasFileFromRoot("__htmgo/tailwind") {
|
||||||
|
slog.Debug("Tailwind CLI already exists. Skipping download.")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if !IsTailwindEnabled() {
|
||||||
|
slog.Debug("Tailwind is not enabled. Skipping tailwind cli download.")
|
||||||
|
return
|
||||||
|
}
|
||||||
distro := ""
|
distro := ""
|
||||||
os := runtime.GOOS
|
os := runtime.GOOS
|
||||||
arch := runtime.GOARCH
|
arch := runtime.GOARCH
|
||||||
|
|
@ -41,7 +77,7 @@ func DownloadTailwindCli() {
|
||||||
process.RunMany([]string{
|
process.RunMany([]string{
|
||||||
fmt.Sprintf(`curl -LO %s`, url),
|
fmt.Sprintf(`curl -LO %s`, url),
|
||||||
fmt.Sprintf(`chmod +x %s`, fileName),
|
fmt.Sprintf(`chmod +x %s`, fileName),
|
||||||
fmt.Sprintf(`mv %s ./assets/css/tailwindcss`, fileName),
|
fmt.Sprintf(`mv %s ./__htmgo/tailwind`, fileName),
|
||||||
}, process.ExitOnError)
|
}, process.ExitOnError)
|
||||||
|
|
||||||
slog.Debug("Successfully downloaded Tailwind CLI", slog.String("url", url))
|
slog.Debug("Successfully downloaded Tailwind CLI", slog.String("url", url))
|
||||||
|
|
|
||||||
|
|
@ -53,6 +53,7 @@ func DownloadTemplate(outPath string) {
|
||||||
}
|
}
|
||||||
|
|
||||||
templateName := "starter-template"
|
templateName := "starter-template"
|
||||||
|
templatePath := filepath.Join("templates", "starter")
|
||||||
|
|
||||||
re := regexp.MustCompile(`[^a-zA-Z]+`)
|
re := regexp.MustCompile(`[^a-zA-Z]+`)
|
||||||
// Replace all non-alphabetic characters with an empty string
|
// Replace all non-alphabetic characters with an empty string
|
||||||
|
|
@ -68,7 +69,7 @@ func DownloadTemplate(outPath string) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
deleteAllExceptTemplate(outPath, templateName)
|
deleteAllExceptTemplate(outPath, templatePath)
|
||||||
|
|
||||||
newDir := filepath.Join(cwd, outPath)
|
newDir := filepath.Join(cwd, outPath)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -6,26 +6,20 @@ import (
|
||||||
"github.com/maddalax/htmgo/cli/htmgo/tasks/copyassets"
|
"github.com/maddalax/htmgo/cli/htmgo/tasks/copyassets"
|
||||||
"github.com/maddalax/htmgo/cli/htmgo/tasks/css"
|
"github.com/maddalax/htmgo/cli/htmgo/tasks/css"
|
||||||
"github.com/maddalax/htmgo/cli/htmgo/tasks/process"
|
"github.com/maddalax/htmgo/cli/htmgo/tasks/process"
|
||||||
|
"os"
|
||||||
)
|
)
|
||||||
|
|
||||||
func Build() {
|
func Build() {
|
||||||
css.DownloadTailwindCli()
|
copyassets.CopyAssets()
|
||||||
|
|
||||||
astgen.GenAst(process.ExitOnError)
|
astgen.GenAst(process.ExitOnError)
|
||||||
css.GenerateCss(process.ExitOnError)
|
css.GenerateCss(process.ExitOnError)
|
||||||
|
|
||||||
copyassets.CopyAssets()
|
|
||||||
|
|
||||||
process.RunOrExit("rm -rf ./dist")
|
process.RunOrExit("rm -rf ./dist")
|
||||||
process.RunOrExit("mkdir -p ./dist")
|
process.RunOrExit("mkdir -p ./dist")
|
||||||
|
|
||||||
//flags := ""
|
if os.Getenv("SKIP_GO_BUILD") != "1" {
|
||||||
//if os.Getenv("CGO_ENABLED") == "1" {
|
process.RunOrExit(fmt.Sprintf("go build -o ./dist"))
|
||||||
// flags = `-a -ldflags '-linkmode external -extldflags "-static"' `
|
}
|
||||||
//}
|
|
||||||
//
|
|
||||||
//process.RunOrExit(fmt.Sprintf("go build -o ./dist %s.", flags))
|
|
||||||
//process.RunOrExit(fmt.Sprintf("go build -o ./dist/app %s .", flags))
|
|
||||||
|
|
||||||
fmt.Printf("Executable built at %s\n", process.GetPathRelativeToCwd("dist"))
|
fmt.Printf("Executable built at %s\n", process.GetPathRelativeToCwd("dist"))
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
package run
|
package run
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"github.com/maddalax/htmgo/cli/htmgo/internal/dirutil"
|
||||||
"github.com/maddalax/htmgo/cli/htmgo/tasks/astgen"
|
"github.com/maddalax/htmgo/cli/htmgo/tasks/astgen"
|
||||||
"github.com/maddalax/htmgo/cli/htmgo/tasks/copyassets"
|
"github.com/maddalax/htmgo/cli/htmgo/tasks/copyassets"
|
||||||
"github.com/maddalax/htmgo/cli/htmgo/tasks/css"
|
"github.com/maddalax/htmgo/cli/htmgo/tasks/css"
|
||||||
|
|
@ -10,8 +11,12 @@ import (
|
||||||
func Setup() {
|
func Setup() {
|
||||||
process.RunOrExit("go mod download")
|
process.RunOrExit("go mod download")
|
||||||
process.RunOrExit("go mod tidy")
|
process.RunOrExit("go mod tidy")
|
||||||
|
|
||||||
copyassets.CopyAssets()
|
copyassets.CopyAssets()
|
||||||
_ = astgen.GenAst(process.ExitOnError)
|
astgen.GenAst(process.ExitOnError)
|
||||||
_ = css.GenerateCss(process.ExitOnError)
|
css.GenerateCss(process.ExitOnError)
|
||||||
EntGenerate()
|
|
||||||
|
if dirutil.HasFileFromRoot("ent/schema") {
|
||||||
|
EntGenerate()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,16 +0,0 @@
|
||||||
version: '3'
|
|
||||||
|
|
||||||
tasks:
|
|
||||||
run:
|
|
||||||
cmds:
|
|
||||||
- go run github.com/maddalax/htmgo/cli@latest run
|
|
||||||
silent: true
|
|
||||||
|
|
||||||
build:
|
|
||||||
cmds:
|
|
||||||
- go run github.com/maddalax/htmgo/cli@latest build
|
|
||||||
|
|
||||||
watch:
|
|
||||||
cmds:
|
|
||||||
- go run github.com/maddalax/htmgo/cli@latest watch
|
|
||||||
silent: true
|
|
||||||
|
|
@ -1,3 +0,0 @@
|
||||||
package ent
|
|
||||||
|
|
||||||
//go:generate go run -mod=mod entgo.io/ent/cmd/ent generate ./schema
|
|
||||||
|
|
@ -1,42 +0,0 @@
|
||||||
package schema
|
|
||||||
|
|
||||||
import (
|
|
||||||
"entgo.io/ent"
|
|
||||||
"entgo.io/ent/dialect/entsql"
|
|
||||||
"entgo.io/ent/schema/field"
|
|
||||||
"time"
|
|
||||||
)
|
|
||||||
|
|
||||||
// User holds the schema definition for the User entity.
|
|
||||||
type User struct {
|
|
||||||
ent.Schema
|
|
||||||
}
|
|
||||||
|
|
||||||
// Fields of the User.
|
|
||||||
func (User) Fields() []ent.Field {
|
|
||||||
return []ent.Field{
|
|
||||||
field.Int("age").
|
|
||||||
Positive(),
|
|
||||||
field.String("name").
|
|
||||||
Default("unknown"),
|
|
||||||
field.String("occupation").Optional(),
|
|
||||||
field.String("email").Optional(),
|
|
||||||
field.String("password").Sensitive().Optional(),
|
|
||||||
field.String("test").Optional(),
|
|
||||||
field.String("test2").Optional(),
|
|
||||||
field.String("test4").Optional(),
|
|
||||||
field.Time("created_at").
|
|
||||||
Default(time.Now).Annotations(
|
|
||||||
entsql.Default("CURRENT_TIMESTAMP"),
|
|
||||||
),
|
|
||||||
field.Time("updated_at").
|
|
||||||
Default(time.Now).Annotations(
|
|
||||||
entsql.Default("CURRENT_TIMESTAMP"),
|
|
||||||
),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Edges of the User.
|
|
||||||
func (User) Edges() []ent.Edge {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
@ -1,39 +0,0 @@
|
||||||
module starter-template
|
|
||||||
|
|
||||||
go 1.23.0
|
|
||||||
|
|
||||||
require (
|
|
||||||
entgo.io/ent v0.14.1
|
|
||||||
github.com/maddalax/htmgo/framework v0.0.0-20240916224719-9e5d8edada65
|
|
||||||
)
|
|
||||||
|
|
||||||
require (
|
|
||||||
ariga.io/atlas v0.19.1-0.20240203083654-5948b60a8e43 // indirect
|
|
||||||
github.com/agext/levenshtein v1.2.1 // indirect
|
|
||||||
github.com/andybalholm/brotli v1.0.5 // indirect
|
|
||||||
github.com/apparentlymart/go-textseg/v13 v13.0.0 // indirect
|
|
||||||
github.com/go-openapi/inflect v0.19.0 // indirect
|
|
||||||
github.com/google/go-cmp v0.6.0 // indirect
|
|
||||||
github.com/google/uuid v1.6.0 // indirect
|
|
||||||
github.com/hashicorp/hcl/v2 v2.13.0 // indirect
|
|
||||||
github.com/inconshreveable/mousetrap v1.1.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
|
|
||||||
github.com/mattn/go-runewidth v0.0.15 // indirect
|
|
||||||
github.com/mattn/go-sqlite3 v1.14.16 // indirect
|
|
||||||
github.com/mitchellh/go-wordwrap v0.0.0-20150314170334-ad45545899c7 // indirect
|
|
||||||
github.com/olekukonko/tablewriter v0.0.5 // indirect
|
|
||||||
github.com/rivo/uniseg v0.2.0 // indirect
|
|
||||||
github.com/spf13/cobra v1.7.0 // indirect
|
|
||||||
github.com/spf13/pflag v1.0.5 // 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
|
|
||||||
github.com/zclconf/go-cty v1.8.0 // indirect
|
|
||||||
golang.org/x/mod v0.20.0 // indirect
|
|
||||||
golang.org/x/sync v0.8.0 // indirect
|
|
||||||
golang.org/x/sys v0.25.0 // indirect
|
|
||||||
golang.org/x/text v0.13.0 // indirect
|
|
||||||
golang.org/x/tools v0.24.0 // indirect
|
|
||||||
)
|
|
||||||
|
|
@ -1,26 +0,0 @@
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/labstack/echo/v4"
|
|
||||||
"github.com/maddalax/htmgo/framework/h"
|
|
||||||
_ "github.com/mattn/go-sqlite3"
|
|
||||||
"log"
|
|
||||||
"starter-template/pages"
|
|
||||||
"starter-template/partials/load"
|
|
||||||
"time"
|
|
||||||
)
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
var startTime = time.Now()
|
|
||||||
f := echo.New()
|
|
||||||
|
|
||||||
f.Static("/public", "./assets/dist")
|
|
||||||
|
|
||||||
load.RegisterPartials(f)
|
|
||||||
pages.RegisterPages(f)
|
|
||||||
|
|
||||||
log.Printf("main() ready in %s", time.Since(startTime))
|
|
||||||
h.Start(f, h.App{
|
|
||||||
LiveReload: true,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
@ -1,40 +0,0 @@
|
||||||
package pages
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/labstack/echo/v4"
|
|
||||||
"github.com/maddalax/htmgo/framework/h"
|
|
||||||
"starter-template/pages/base"
|
|
||||||
"starter-template/partials"
|
|
||||||
)
|
|
||||||
|
|
||||||
func IndexPage(c echo.Context) *h.Page {
|
|
||||||
return h.NewPage(h.Html(
|
|
||||||
h.HxExtension(base.Extensions()),
|
|
||||||
h.Class("bg-red-200 flex flex-col items-center h-full w-full"),
|
|
||||||
h.Head(
|
|
||||||
h.Link("/public/main.css", "stylesheet"),
|
|
||||||
h.Script("/public/htmgo.js"),
|
|
||||||
),
|
|
||||||
h.Body(
|
|
||||||
h.Class("flex flex-col gap-4"),
|
|
||||||
h.Div(h.Class("flex gap-2 mt-6"),
|
|
||||||
Button(),
|
|
||||||
Button(),
|
|
||||||
Button(),
|
|
||||||
Button(),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
))
|
|
||||||
}
|
|
||||||
|
|
||||||
func Button() h.Ren {
|
|
||||||
return h.Button(h.Class("btn bg-green-500 p-4 rounded text-white"),
|
|
||||||
h.Text("my button"),
|
|
||||||
h.HxAfterRequest(
|
|
||||||
h.SetDisabled(true),
|
|
||||||
h.RemoveClass("bg-red-600"),
|
|
||||||
h.AddClass("bg-gray-500"),
|
|
||||||
),
|
|
||||||
h.GetPartial(partials.SamplePartial),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
@ -1,18 +0,0 @@
|
||||||
package partials
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/labstack/echo/v4"
|
|
||||||
"github.com/maddalax/htmgo/framework/h"
|
|
||||||
)
|
|
||||||
|
|
||||||
func SamplePartial(ctx echo.Context) *h.Partial {
|
|
||||||
return h.NewPartial(h.Div(h.P(h.Text(" asdasasds"))))
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewPartial(ctx echo.Context) *h.Partial {
|
|
||||||
return h.NewPartial(h.Div(h.P(h.Text("This sadsl."))))
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewPartial2(ctx echo.Context) *h.Partial {
|
|
||||||
return h.NewPartial(h.Div(h.P(h.Text("This sasdsadasdwl."))))
|
|
||||||
}
|
|
||||||
|
|
@ -1,36 +1,5 @@
|
||||||
const {join} = require("node:path");
|
|
||||||
/** @type {import('tailwindcss').Config} */
|
/** @type {import('tailwindcss').Config} */
|
||||||
const root = join(__dirname, "../../");
|
|
||||||
const contentGo = join(root, "**/*.go");
|
|
||||||
const contentJs = join(root, "**/pages/**/*.js");
|
|
||||||
|
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
content: [contentGo, contentJs],
|
content: ["**/*.go", "**/*.js"],
|
||||||
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: [],
|
plugins: [],
|
||||||
};
|
};
|
||||||
|
|
|
||||||
3901
framework/assets/dist/htmgo.js
vendored
3901
framework/assets/dist/htmgo.js
vendored
File diff suppressed because one or more lines are too long
|
|
@ -16,7 +16,7 @@ export default defineConfig({
|
||||||
js: ".js",
|
js: ".js",
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
minify: false,
|
minify: true,
|
||||||
bundle: true,
|
bundle: true,
|
||||||
splitting: true,
|
splitting: true,
|
||||||
// https://github.com/egoist/tsup/issues/619
|
// https://github.com/egoist/tsup/issues/619
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,14 @@ func Ternary[T any](value bool, a T, b T) T {
|
||||||
return IfElse(value, a, b)
|
return IfElse(value, a, b)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func ElementIf(condition bool, element *Element) *Element {
|
||||||
|
if condition {
|
||||||
|
return element
|
||||||
|
} else {
|
||||||
|
return Empty()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func IfElse[T any](condition bool, node T, node2 T) T {
|
func IfElse[T any](condition bool, node T, node2 T) T {
|
||||||
if condition {
|
if condition {
|
||||||
return node
|
return node
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@ package h
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"strconv"
|
||||||
)
|
)
|
||||||
|
|
||||||
type ClassMap map[string]bool
|
type ClassMap map[string]bool
|
||||||
|
|
@ -117,6 +118,17 @@ func Checkbox(children ...Ren) Ren {
|
||||||
return Input("checkbox", children...)
|
return Input("checkbox", children...)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func Value(value any) Ren {
|
||||||
|
switch v := value.(type) {
|
||||||
|
case string:
|
||||||
|
return Attribute("value", v)
|
||||||
|
case int:
|
||||||
|
return Attribute("value", strconv.Itoa(v))
|
||||||
|
default:
|
||||||
|
return Attribute("value", fmt.Sprintf("%v", v))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func Input(inputType string, children ...Ren) Ren {
|
func Input(inputType string, children ...Ren) Ren {
|
||||||
attributeMap := AttributeMap{
|
attributeMap := AttributeMap{
|
||||||
"type": inputType,
|
"type": inputType,
|
||||||
|
|
|
||||||
16
templates/starter/Taskfile.yml
Normal file
16
templates/starter/Taskfile.yml
Normal file
|
|
@ -0,0 +1,16 @@
|
||||||
|
version: '3'
|
||||||
|
|
||||||
|
tasks:
|
||||||
|
run:
|
||||||
|
cmds:
|
||||||
|
- go run github.com/maddalax/htmgo/cli/htmgo@latest run
|
||||||
|
silent: true
|
||||||
|
|
||||||
|
build:
|
||||||
|
cmds:
|
||||||
|
- go run github.com/maddalax/htmgo/cli/htmgo@latest build
|
||||||
|
|
||||||
|
watch:
|
||||||
|
cmds:
|
||||||
|
- go run github.com/maddalax/htmgo/cli/htmgo@latest watch
|
||||||
|
silent: true
|
||||||
|
|
@ -1,12 +1,13 @@
|
||||||
// Package pages THIS FILE IS GENERATED. DO NOT EDIT.
|
// Package __htmgo THIS FILE IS GENERATED. DO NOT EDIT.
|
||||||
package pages
|
package __htmgo
|
||||||
|
|
||||||
import "github.com/labstack/echo/v4"
|
import "github.com/labstack/echo/v4"
|
||||||
import "github.com/maddalax/htmgo/framework/h"
|
import "github.com/maddalax/htmgo/framework/h"
|
||||||
|
import "starter-template/pages"
|
||||||
|
|
||||||
func RegisterPages(f *echo.Echo) {
|
func RegisterPages(f *echo.Echo) {
|
||||||
f.GET("/", func(ctx echo.Context) error {
|
f.GET("/", func(ctx echo.Context) error {
|
||||||
cc := ctx.(*h.RequestContext)
|
cc := ctx.(*h.RequestContext)
|
||||||
return h.HtmlView(ctx, IndexPage(cc))
|
return h.HtmlView(ctx, pages.IndexPage(cc))
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
// Package partials THIS FILE IS GENERATED. DO NOT EDIT.
|
// Package __htmgo THIS FILE IS GENERATED. DO NOT EDIT.
|
||||||
package load
|
package __htmgo
|
||||||
|
|
||||||
import "github.com/maddalax/htmgo/framework/h"
|
import "github.com/maddalax/htmgo/framework/h"
|
||||||
import "github.com/labstack/echo/v4"
|
import "github.com/labstack/echo/v4"
|
||||||
|
|
@ -7,17 +7,9 @@ import "starter-template/partials"
|
||||||
|
|
||||||
func GetPartialFromContext(ctx echo.Context) *h.Partial {
|
func GetPartialFromContext(ctx echo.Context) *h.Partial {
|
||||||
path := ctx.Request().URL.Path
|
path := ctx.Request().URL.Path
|
||||||
if path == "SamplePartial" || path == "/starter-template/partials.SamplePartial" {
|
if path == "CounterPartial" || path == "/starter-template/partials.CounterPartial" {
|
||||||
cc := ctx.(*h.RequestContext)
|
cc := ctx.(*h.RequestContext)
|
||||||
return partials.SamplePartial(cc)
|
return partials.CounterPartial(cc)
|
||||||
}
|
|
||||||
if path == "NewPartial" || path == "/starter-template/partials.NewPartial" {
|
|
||||||
cc := ctx.(*h.RequestContext)
|
|
||||||
return partials.NewPartial(cc)
|
|
||||||
}
|
|
||||||
if path == "NewPartial2" || path == "/starter-template/partials.NewPartial2" {
|
|
||||||
cc := ctx.(*h.RequestContext)
|
|
||||||
return partials.NewPartial2(cc)
|
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
11
templates/starter/__htmgo/setup-generated.go
Normal file
11
templates/starter/__htmgo/setup-generated.go
Normal file
|
|
@ -0,0 +1,11 @@
|
||||||
|
// Package __htmgo THIS FILE IS GENERATED. DO NOT EDIT.
|
||||||
|
package __htmgo
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/labstack/echo/v4"
|
||||||
|
)
|
||||||
|
|
||||||
|
func Register(e *echo.Echo) {
|
||||||
|
RegisterPartials(e)
|
||||||
|
RegisterPages(e)
|
||||||
|
}
|
||||||
22
templates/starter/go.mod
Normal file
22
templates/starter/go.mod
Normal file
|
|
@ -0,0 +1,22 @@
|
||||||
|
module starter-template
|
||||||
|
|
||||||
|
go 1.23.0
|
||||||
|
|
||||||
|
require (
|
||||||
|
github.com/labstack/echo/v4 v4.12.0
|
||||||
|
github.com/maddalax/htmgo/framework v0.0.0-20240923041212-939e80968f38
|
||||||
|
github.com/mattn/go-sqlite3 v1.14.16
|
||||||
|
)
|
||||||
|
|
||||||
|
require (
|
||||||
|
github.com/google/uuid v1.6.0 // indirect
|
||||||
|
github.com/labstack/gommon v0.4.2 // indirect
|
||||||
|
github.com/mattn/go-colorable v0.1.13 // indirect
|
||||||
|
github.com/mattn/go-isatty v0.0.20 // indirect
|
||||||
|
github.com/valyala/bytebufferpool v1.0.0 // indirect
|
||||||
|
github.com/valyala/fasttemplate v1.2.2 // indirect
|
||||||
|
golang.org/x/crypto v0.27.0 // indirect
|
||||||
|
golang.org/x/net v0.29.0 // indirect
|
||||||
|
golang.org/x/sys v0.25.0 // indirect
|
||||||
|
golang.org/x/text v0.18.0 // indirect
|
||||||
|
)
|
||||||
33
templates/starter/main.go
Normal file
33
templates/starter/main.go
Normal file
|
|
@ -0,0 +1,33 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"embed"
|
||||||
|
"github.com/labstack/echo/v4"
|
||||||
|
"github.com/maddalax/htmgo/framework/h"
|
||||||
|
"github.com/maddalax/htmgo/framework/service"
|
||||||
|
_ "github.com/mattn/go-sqlite3"
|
||||||
|
"io/fs"
|
||||||
|
"starter-template/__htmgo"
|
||||||
|
)
|
||||||
|
|
||||||
|
//go:embed assets/dist/*
|
||||||
|
var StaticAssets embed.FS
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
locator := service.NewLocator()
|
||||||
|
|
||||||
|
sub, err := fs.Sub(StaticAssets, "assets/dist")
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
h.Start(h.AppOpts{
|
||||||
|
ServiceLocator: locator,
|
||||||
|
LiveReload: true,
|
||||||
|
Register: func(e *echo.Echo) {
|
||||||
|
e.StaticFS("/public", sub)
|
||||||
|
__htmgo.Register(e)
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
21
templates/starter/pages/index.go
Normal file
21
templates/starter/pages/index.go
Normal file
|
|
@ -0,0 +1,21 @@
|
||||||
|
package pages
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/maddalax/htmgo/framework/h"
|
||||||
|
"starter-template/partials"
|
||||||
|
)
|
||||||
|
|
||||||
|
func IndexPage(ctx *h.RequestContext) *h.Page {
|
||||||
|
return h.NewPage(
|
||||||
|
RootPage(
|
||||||
|
h.Div(
|
||||||
|
h.Class("flex flex-col gap-4 items-center pt-24 min-h-screen bg-neutral-100"),
|
||||||
|
h.H3(h.Id("intro-text"), h.Text("hello htmgo"), h.Class("text-5xl")),
|
||||||
|
h.Div(
|
||||||
|
h.Class("mt-3"),
|
||||||
|
partials.CounterForm(0),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
@ -1,21 +1,12 @@
|
||||||
package base
|
package pages
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/maddalax/htmgo/framework/h"
|
"github.com/maddalax/htmgo/framework/h"
|
||||||
"strings"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func Extensions() string {
|
|
||||||
extensions := []string{"path-deps", "response-targets", "mutation-error"}
|
|
||||||
if h.IsDevelopment() {
|
|
||||||
extensions = append(extensions, "livereload")
|
|
||||||
}
|
|
||||||
return strings.Join(extensions, ", ")
|
|
||||||
}
|
|
||||||
|
|
||||||
func RootPage(children ...h.Ren) h.Ren {
|
func RootPage(children ...h.Ren) h.Ren {
|
||||||
return h.Html(
|
return h.Html(
|
||||||
h.HxExtension(Extensions()),
|
h.HxExtension(h.BaseExtensions()),
|
||||||
h.Head(
|
h.Head(
|
||||||
h.Link("/public/main.css", "stylesheet"),
|
h.Link("/public/main.css", "stylesheet"),
|
||||||
h.Script("/public/htmgo.js"),
|
h.Script("/public/htmgo.js"),
|
||||||
54
templates/starter/partials/index.go
Normal file
54
templates/starter/partials/index.go
Normal file
|
|
@ -0,0 +1,54 @@
|
||||||
|
package partials
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/maddalax/htmgo/framework/h"
|
||||||
|
"strconv"
|
||||||
|
)
|
||||||
|
|
||||||
|
func CounterPartial(ctx *h.RequestContext) *h.Partial {
|
||||||
|
count, err := strconv.ParseInt(ctx.FormValue("count"), 10, 64)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
count = 0
|
||||||
|
}
|
||||||
|
|
||||||
|
count++
|
||||||
|
|
||||||
|
return h.SwapManyPartial(
|
||||||
|
ctx,
|
||||||
|
CounterForm(int(count)),
|
||||||
|
h.ElementIf(count > 10, SubmitButton("New record!")),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
func CounterForm(count int) *h.Element {
|
||||||
|
return h.Form(
|
||||||
|
h.Class("flex flex-col gap-3 items-center"),
|
||||||
|
h.Id("counter-form"),
|
||||||
|
h.PostPartial(CounterPartial),
|
||||||
|
h.Input("text",
|
||||||
|
h.Class("hidden"),
|
||||||
|
h.Value(count),
|
||||||
|
h.Name("count"),
|
||||||
|
),
|
||||||
|
h.P(
|
||||||
|
h.AttributePairs(
|
||||||
|
"id", "counter",
|
||||||
|
"class", "text-xl",
|
||||||
|
"name", "count",
|
||||||
|
"text", "count",
|
||||||
|
),
|
||||||
|
h.TextF("Count: %d", count),
|
||||||
|
),
|
||||||
|
SubmitButton("Increment"),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
func SubmitButton(text string) *h.Element {
|
||||||
|
return h.Button(
|
||||||
|
h.Class("bg-rose-400 hover:bg-rose-500 text-white font-bold py-2 px-4 rounded"),
|
||||||
|
h.Id("swap-text"),
|
||||||
|
h.Type("submit"),
|
||||||
|
h.Text(text),
|
||||||
|
)
|
||||||
|
}
|
||||||
5
templates/starter/tailwind.config.js
Normal file
5
templates/starter/tailwind.config.js
Normal file
|
|
@ -0,0 +1,5 @@
|
||||||
|
/** @type {import('tailwindcss').Config} */
|
||||||
|
module.exports = {
|
||||||
|
content: ["**/*.go", "**/*.js"],
|
||||||
|
plugins: [],
|
||||||
|
};
|
||||||
Loading…
Reference in a new issue