working on landing page

This commit is contained in:
maddalax 2024-09-20 11:45:23 -05:00
parent 279a3c7163
commit f036fae5e7
48 changed files with 574 additions and 26 deletions

View file

@ -1,4 +1,4 @@
package main
package htmgo
import (
"sync"

View file

@ -1,4 +1,4 @@
module github.com/maddalax/htmgo/cli
module github.com/maddalax/htmgo/cli/htmgo
go 1.23.0

View file

@ -1,4 +1,4 @@
package main
package htmgo
import (
"log/slog"

View file

@ -20,7 +20,7 @@ func main() {
done := RegisterSignals()
commandMap := make(map[string]*flag.FlagSet)
commands := []string{"template", "run", "watch", "build", "setup", "css", "schema"}
commands := []string{"template", "run", "watch", "build", "setup", "css", "schema", "generate"}
for _, command := range commands {
commandMap[command] = flag.NewFlagSet(command, flag.ExitOnError)
@ -100,6 +100,8 @@ func main() {
downloadtemplate.DownloadTemplate(fmt.Sprintf("./%s", text))
} else if taskName == "build" {
run.Build()
} else if taskName == "generate" {
astgen.GenAst(process.ExitOnError)
} else {
fmt.Println(fmt.Sprintf("Usage: htmgo [%s]", strings.Join(commands, " | ")))
}

View file

@ -1,4 +1,4 @@
package main
package htmgo
import (
"fmt"

View file

@ -56,7 +56,7 @@ func sliceCommonPrefix(dir1, dir2 string) string {
return slicedDir2
}
func findPublicFuncsReturningHPartial(dir string) ([]Partial, error) {
func findPublicFuncsReturningHPartial(dir string, predicate func(partial Partial) bool) ([]Partial, error) {
var partials []Partial
cwd := process.GetWorkingDir()
@ -93,11 +93,14 @@ func findPublicFuncsReturningHPartial(dir string) ([]Partial, error) {
// Check if the package name is 'h' and type is 'Partial'.
if ident, ok := selectorExpr.X.(*ast.Ident); ok && ident.Name == "h" {
if selectorExpr.Sel.Name == "Partial" {
partials = append(partials, Partial{
p := Partial{
Package: node.Name.Name,
Import: sliceCommonPrefix(cwd, filepath.Dir(path)),
FuncName: funcDecl.Name.Name,
})
}
if predicate(p) {
partials = append(partials, p)
}
break
}
}
@ -191,6 +194,10 @@ func buildGetPartialFromContext(builder *CodeBuilder, partials []Partial) {
path := ctx.Request().URL.Path
`
if len(partials) == 0 {
body = ""
}
moduleName := GetModuleName()
for _, f := range partials {
if f.FuncName == fName {
@ -240,16 +247,15 @@ func buildGetPartialFromContext(builder *CodeBuilder, partials []Partial) {
func writePartialsFile() {
cwd := process.GetWorkingDir()
partialPath := filepath.Join(cwd, "partials")
partials, err := findPublicFuncsReturningHPartial(partialPath)
partials, err := findPublicFuncsReturningHPartial(partialPath, func(partial Partial) bool {
return partial.FuncName != "GetPartialFromContext"
})
if err != nil {
fmt.Println(err)
return
}
if len(partials) == 0 {
return
}
builder := NewCodeBuilder(nil)
builder.AppendLine(`// Package partials THIS FILE IS GENERATED. DO NOT EDIT.`)
builder.AppendLine("package load")
@ -296,12 +302,11 @@ func writePagesFile() {
builder.AppendLine(`// Package pages THIS FILE IS GENERATED. DO NOT EDIT.`)
builder.AppendLine("package pages")
builder.AddImport("github.com/labstack/echo/v4")
builder.AddImport("github.com/maddalax/htmgo/framework/h")
pages, _ := findPublicFuncsReturningHPage("pages")
if len(pages) == 0 {
return
if len(pages) > 0 {
builder.AddImport("github.com/maddalax/htmgo/framework/h")
}
for _, page := range pages {

View file

@ -58,7 +58,7 @@ func copyFile(src, dst string) error {
}
// copyDir copies a directory recursively from src to dst.
func copyDir(srcDir, dstDir string) error {
func copyDir(srcDir, dstDir string, skip func(path string) bool) error {
// Walk the source directory tree.
return filepath.Walk(srcDir, func(srcPath string, info os.FileInfo, err error) error {
if err != nil {
@ -77,6 +77,9 @@ func copyDir(srcDir, dstDir string) error {
return fmt.Errorf("failed to create directory: %v", err)
}
} else {
if skip != nil && skip(srcPath) {
return nil
}
// If it's a file, copy the file.
err := copyFile(srcPath, dstPath)
if err != nil {
@ -116,8 +119,15 @@ func CopyAssets() {
destDirDist := fmt.Sprintf("%s/dist", destDir)
destDirCss := fmt.Sprintf("%s/css", destDir)
err := copyDir(assetDistDir, destDirDist)
err = copyDir(assetCssDir, destDirCss)
err := copyDir(assetDistDir, destDirDist, func(path string) bool {
return false
})
err = copyDir(assetCssDir, destDirCss, func(path string) bool {
if strings.HasSuffix(path, "tailwind.config.js") {
return true
}
return false
})
if err != nil {
log.Fatalf("Error: %v", err)

View file

@ -84,6 +84,10 @@ func OnFileChange(events []*fsnotify.Event) {
tasks.Run = true
}
if c.HasAnySuffix(".md") {
tasks.Run = true
}
if c.HasAnySuffix("tailwind.config.js", ".css") {
tasks.Run = true
}

View file

@ -1,4 +1,4 @@
package main
package htmgo
import (
"github.com/fsnotify/fsnotify"

View file

@ -244,6 +244,17 @@ func Body(children ...Ren) *Element {
return Tag("body", children...)
}
func Meta(name string, content string) Ren {
return &Element{
tag: "meta",
attributes: map[string]string{
"name": name,
"content": content,
},
children: make([]Ren, 0),
}
}
func Link(href string, rel string) Ren {
attributeMap := AttributeMap{
"href": href,
@ -291,6 +302,10 @@ func Div(children ...Ren) *Element {
return Tag("div", children...)
}
func Article(children ...Ren) *Element {
return Tag("article", children...)
}
func ReplaceUrlHeader(url string) *Headers {
return NewHeaders("HX-Replace-Url", url)
}
@ -363,11 +378,8 @@ func List[T any](items []T, mapper func(item T, index int) *Element) *Element {
return node
}
func Fragment(children ...Ren) *Element {
return &Element{
tag: "",
children: children,
}
func Fragment(children ...Ren) *ChildList {
return Children(children...)
}
func AttributeList(children ...*AttributeMap) *AttributeMap {

16
htmgo-site/Taskfile.yml Normal file
View file

@ -0,0 +1,16 @@
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

View file

@ -0,0 +1,3 @@
@tailwind base;
@tailwind components;
@tailwind utilities;

View file

@ -0,0 +1,11 @@
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],
plugins: [ require('@tailwindcss/typography')],
};

BIN
htmgo-site/assets/css/tailwindcss Executable file

Binary file not shown.

26
htmgo-site/go.mod Normal file
View file

@ -0,0 +1,26 @@
module htmgo-site
go 1.23.0
require (
github.com/google/uuid v1.6.0
github.com/labstack/echo/v4 v4.12.0
github.com/maddalax/htmgo/framework v0.0.0-20240920021308-279a3c716342
github.com/mattn/go-sqlite3 v1.14.16
)
require (
github.com/alecthomas/chroma/v2 v2.2.0 // indirect
github.com/dlclark/regexp2 v1.7.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
github.com/yuin/goldmark v1.7.4 // indirect
github.com/yuin/goldmark-highlighting/v2 v2.0.0-20230729083705-37449abec8cc // 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
)

53
htmgo-site/go.sum Normal file
View file

@ -0,0 +1,53 @@
github.com/alecthomas/chroma/v2 v2.2.0 h1:Aten8jfQwUqEdadVFFjNyjx7HTexhKP0XuqBG67mRDY=
github.com/alecthomas/chroma/v2 v2.2.0/go.mod h1:vf4zrexSH54oEjJ7EdB65tGNHmH3pGZmVkgTP5RHvAs=
github.com/alecthomas/repr v0.0.0-20220113201626-b1b626ac65ae/go.mod h1:2kn6fqh/zIyPLmm3ugklbEi5hg5wS435eygvNfaDQL8=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/dlclark/regexp2 v1.4.0/go.mod h1:2pZnwuY/m+8K6iRw6wQdMtk+rH5tNGR1i55kozfMjCc=
github.com/dlclark/regexp2 v1.7.0 h1:7lJfhqlPssTb1WQx4yvTHN0uElPEv52sbaECrAQxjAo=
github.com/dlclark/regexp2 v1.7.0/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8=
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/labstack/echo/v4 v4.12.0 h1:IKpw49IMryVB2p1a4dzwlhP1O2Tf2E0Ir/450lH+kI0=
github.com/labstack/echo/v4 v4.12.0/go.mod h1:UP9Cr2DJXbOK3Kr9ONYzNowSh7HP0aG0ShAyycHSJvM=
github.com/labstack/gommon v0.4.2 h1:F8qTUNXgG1+6WQmqoUWnz8WiEU60mXVVw0P4ht1WRA0=
github.com/labstack/gommon v0.4.2/go.mod h1:QlUFxVM+SNXhDL/Z7YhocGIBYOiwB0mXm1+1bAPHPyU=
github.com/maddalax/htmgo/framework v0.0.0-20240920021308-279a3c716342 h1:r7Gr/9jj+vAqhgMAnWt96mNA9rXYsiyCwrqn9FcWryE=
github.com/maddalax/htmgo/framework v0.0.0-20240920021308-279a3c716342/go.mod h1:WRIlLlHJG/xB+RR84LgNFq3hwYFKXvLfEEG8RzTUH50=
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-sqlite3 v1.14.16 h1:yOQRA0RpS5PFz/oikGwBEqvAWhWg5ufRz4ETLjwpU1Y=
github.com/mattn/go-sqlite3 v1.14.16/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
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/fasttemplate v1.2.2 h1:lxLXG0uE3Qnshl9QyaK6XJxMXlQZELvChBOCmQD0Loo=
github.com/valyala/fasttemplate v1.2.2/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ=
github.com/yuin/goldmark v1.4.15/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
github.com/yuin/goldmark v1.7.4 h1:BDXOHExt+A7gwPCJgPIIq7ENvceR7we7rOS9TNoLZeg=
github.com/yuin/goldmark v1.7.4/go.mod h1:uzxRWxtg69N339t3louHJ7+O03ezfj6PlliRlaOzY1E=
github.com/yuin/goldmark-highlighting/v2 v2.0.0-20230729083705-37449abec8cc h1:+IAOyRda+RLrxa1WC7umKOZRsGq4QrFFMYApOeHzQwQ=
github.com/yuin/goldmark-highlighting/v2 v2.0.0-20230729083705-37449abec8cc/go.mod h1:ovIvrum6DQJA4QsJSovrkC4saKHQVs7TvcaeO8AIl5I=
golang.org/x/crypto v0.27.0 h1:GXm2NjJrPaiv/h1tb2UH8QfgC/hOf/+z0p6PT8o1w7A=
golang.org/x/crypto v0.27.0/go.mod h1:1Xngt8kV6Dvbssa53Ziq6Eqn0HqbZi5Z6R0ZpwQzt70=
golang.org/x/net v0.29.0 h1:5ORfpBpCs4HzDYoodCDBbwHzdR5UrLBZ3sOnUJmFoHo=
golang.org/x/net v0.29.0/go.mod h1:gLkgy8jTGERgjzMic6DS9+SP0ajcu6Xu3Orq/SpETg0=
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=
golang.org/x/text v0.18.0 h1:XvMDiNzPAl0jr17s6W9lcaIhGUfUORdGCNsuLmPG224=
golang.org/x/text v0.18.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

View file

@ -0,0 +1,37 @@
package dirwalk
import (
"github.com/maddalax/htmgo/framework/h"
"os"
"path/filepath"
"strings"
)
type Page struct {
RoutePath string
FilePath string
Parts []string
}
func WalkPages(dir string) []Page {
pages := make([]Page, 0)
filepath.Walk(dir, func(path string, info os.FileInfo, err error) error {
if err != nil {
return err
}
name := info.Name()
if !info.IsDir() && (strings.HasSuffix(name, ".md") || strings.HasSuffix(name, ".go")) {
fullPath := strings.Replace(path, dir, "", 1)
fullPath = strings.TrimSuffix(fullPath, ".md")
pages = append(pages, Page{
RoutePath: fullPath,
FilePath: path,
Parts: h.Filter(strings.Split(fullPath, string(os.PathSeparator)), func(item string) bool {
return item != ""
}),
})
}
return nil
})
return pages
}

View file

@ -0,0 +1,66 @@
package markdown
import (
"bytes"
"github.com/yuin/goldmark"
highlighting "github.com/yuin/goldmark-highlighting/v2"
"github.com/yuin/goldmark/extension"
"github.com/yuin/goldmark/parser"
"github.com/yuin/goldmark/renderer/html"
"io"
"os"
)
type Renderer struct {
cache map[string]string
}
func NewRenderer() *Renderer {
return &Renderer{cache: make(map[string]string)}
}
func (r *Renderer) RenderFile(source string) string {
if val, ok := r.cache[source]; ok {
return val
}
o, err := os.Open(source)
defer func(o *os.File) {
_ = o.Close()
}(o)
if err != nil {
return ""
}
buf := RenderMarkdown(o)
r.cache[source] = buf.String()
return r.cache[source]
}
func RenderMarkdown(reader io.Reader) bytes.Buffer {
md := goldmark.New(
goldmark.WithExtensions(extension.GFM),
goldmark.WithParserOptions(
parser.WithAutoHeadingID(),
),
goldmark.WithRendererOptions(
html.WithHardWraps(),
html.WithXHTML(),
html.WithUnsafe(),
),
goldmark.WithExtensions(
highlighting.NewHighlighting(
highlighting.WithStyle("github"),
),
),
)
source, _ := io.ReadAll(reader)
var buf bytes.Buffer
if err := md.Convert(source, &buf); err != nil {
panic(err)
}
return buf
}

30
htmgo-site/main.go Normal file
View file

@ -0,0 +1,30 @@
package main
import (
"github.com/labstack/echo/v4"
"github.com/maddalax/htmgo/framework/h"
"github.com/maddalax/htmgo/framework/htmgo/service"
_ "github.com/mattn/go-sqlite3"
"htmgo-site/internal/markdown"
"htmgo-site/pages"
"htmgo-site/partials/load"
)
func main() {
locator := service.NewLocator()
service.Set(locator, service.Singleton, markdown.NewRenderer)
h.Start(h.AppOpts{
ServiceLocator: locator,
LiveReload: true,
Register: func(e *echo.Echo) {
e.Static("/public", "./assets/dist")
load.RegisterPartials(e)
pages.RegisterPages(e)
pages.RegisterMarkdown(e, "md", func(ctx echo.Context, path string) error {
return pages.MarkdownHandler(ctx.(*h.RequestContext), path)
})
},
})
}

View file

View file

@ -0,0 +1,6 @@
### **Installation Instructions**
```bash
go install github.com/maddalax/htmgo@latest
go run htmgo template
```

36
htmgo-site/md/index.md Normal file
View file

@ -0,0 +1,36 @@
## **htmgo**
### build simple and scalable systems with go + htmx
-------
**introduction:**
htmgo is a lightweight pure go way to build interactive websites / web applications using go & htmx.
By combining the speed & simplicity of go + hypermedia attributes ([htmx](https://htmx.org)) to add interactivity to websites, all conveniently wrapped in pure go, you can build simple, fast, interactive websites without touching javascript. All compiled to a **single deployable binary**.
```go
func IndexPage(ctx *h.RequestContext) *h.Page {
now := time.Now()
return h.NewPage(
h.Div(
h.Class("flex gap-2"),
h.TextF("the current time is %s", now.String())
)
)
}
```
**core features:**
1. deployable single binary
2. live reload (rebuilds css, go, ent schema, and routes upon change)
3. automatic page and partial registration based on file path
4. built in tailwindcss support, no need to configure anything by default
5. plugin architecture to include optional plugins to streamline development, such as http://entgo.io
6. custom [htmx extensions](https://github.com/maddalax/htmgo/tree/b610aefa36e648b98a13823a6f8d87566120cfcc/framework/assets/js/htmxextensions) to reduce boilerplate with common tasks

View file

@ -0,0 +1,32 @@
package base
import (
"github.com/maddalax/htmgo/framework/h"
"htmgo-site/partials"
"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.Element {
return h.Html(
h.HxExtension(Extensions()),
h.Head(
h.Meta("viewport", "width=device-width, initial-scale=1"),
h.Link("/public/main.css", "stylesheet"),
h.Script("/public/htmgo.js"),
h.Raw(`
<script async defer src="https://buttons.github.io/buttons.js"></script>
`),
),
h.Class("bg-neutral-50 min-h-screen"),
partials.NavBar(),
h.Fragment(children...),
)
}

24
htmgo-site/pages/docs.go Normal file
View file

@ -0,0 +1,24 @@
package pages
import (
"github.com/maddalax/htmgo/framework/h"
"htmgo-site/internal/dirwalk"
"htmgo-site/pages/base"
)
func DocsPage(ctx *h.RequestContext) *h.Page {
pages := dirwalk.WalkPages("md/docs")
return h.NewPage(base.RootPage(
h.Div(
h.Class("flex flex-col p-4 justify-center items-center"),
h.List(pages, func(page dirwalk.Page, index int) *h.Element {
return MarkdownContent(ctx, page.FilePath)
}),
),
h.Div(
h.Class("min-h-12"),
),
),
)
}

View file

@ -0,0 +1,16 @@
// Package pages THIS FILE IS GENERATED. DO NOT EDIT.
package pages
import "github.com/labstack/echo/v4"
import "github.com/maddalax/htmgo/framework/h"
func RegisterPages(f *echo.Echo) {
f.GET("/docs", func(ctx echo.Context) error {
cc := ctx.(*h.RequestContext)
return h.HtmlView(ctx, DocsPage(cc))
})
f.GET("/", func(ctx echo.Context) error {
cc := ctx.(*h.RequestContext)
return h.HtmlView(ctx, IndexPage(cc))
})
}

View file

@ -0,0 +1,9 @@
package pages
import (
"github.com/maddalax/htmgo/framework/h"
)
func IndexPage(ctx *h.RequestContext) *h.Page {
return h.NewPage(MarkdownPage(ctx, "md/index.md"))
}

View file

@ -0,0 +1,34 @@
package pages
import (
"github.com/maddalax/htmgo/framework/h"
"github.com/maddalax/htmgo/framework/htmgo/service"
"htmgo-site/internal/markdown"
"htmgo-site/pages/base"
)
func MarkdownHandler(ctx *h.RequestContext, path string) error {
return h.HtmlView(ctx, h.NewPage(MarkdownPage(ctx, path)))
}
func MarkdownPage(ctx *h.RequestContext, path string) *h.Element {
return base.RootPage(
h.Div(
h.Class("flex flex-col p-4 justify-center items-center"),
MarkdownContent(ctx, path),
h.Div(
h.Class("min-h-12"),
),
),
)
}
func MarkdownContent(ctx *h.RequestContext, path string) *h.Element {
renderer := service.Get[markdown.Renderer](ctx.ServiceLocator())
return h.Div(
h.Article(
h.Class("prose max-w-[95%] pt-3 md:p-4 md:max-w-2xl prose-code:text-black"),
h.Raw(renderer.RenderFile(path)),
),
)
}

14
htmgo-site/pages/setup.go Normal file
View file

@ -0,0 +1,14 @@
package pages
import (
"github.com/labstack/echo/v4"
"htmgo-site/internal/dirwalk"
)
func RegisterMarkdown(app *echo.Echo, dir string, handler func(ctx echo.Context, path string) error) {
for _, page := range dirwalk.WalkPages(dir) {
app.GET(page.RoutePath, func(ctx echo.Context) error {
return handler(ctx, page.FilePath)
})
}
}

View file

@ -0,0 +1,19 @@
// Package partials THIS FILE IS GENERATED. DO NOT EDIT.
package load
import "github.com/maddalax/htmgo/framework/h"
import "github.com/labstack/echo/v4"
func GetPartialFromContext(ctx echo.Context) *h.Partial {
return nil
}
func RegisterPartials(f *echo.Echo) {
f.Any("htmgo-site/partials*", func(ctx echo.Context) error {
partial := GetPartialFromContext(ctx)
if partial == nil {
return ctx.NoContent(404)
}
return h.PartialView(ctx, partial)
})
}

View file

@ -0,0 +1,60 @@
package partials
import "github.com/maddalax/htmgo/framework/h"
type NavItem struct {
Name string
Url string
}
func NavBar() *h.Element {
star := h.Raw(`
<a
class="github-button"
href="https://github.com/maddalax/htmgo"
data-color-scheme="no-preference: light; light: light; dark: dark;"
data-icon="octicon-star"
data-size="large"
data-show-count="true"
aria-label="Star maddalax/htmgo on GitHub">Star</a>
`)
navItems := []NavItem{
{Name: "Docs", Url: "/docs"},
{Name: "Examples", Url: "/examples"},
}
return h.Nav(
h.Class("bg-neutral-100 border border-b-slate-300 p-4 md:p-3"),
h.Div(
h.Class("max-w-[95%] md:max-w-prose mx-auto"),
h.Div(
h.Class("flex justify-between items-center"),
h.Div(
h.Class("flex items-center"),
h.A(
h.Boost(),
h.Class("text-2xl"),
h.Href("/"),
h.Text("htmgo"),
)),
h.Div(
h.Class("flex gap-4 items-center"),
h.List(navItems, func(item NavItem, index int) *h.Element {
return h.Div(
h.Class("flex items-center"),
h.A(
h.Boost(),
h.Class(""),
h.Href(item.Url),
h.Text(item.Name),
),
)
}),
h.Div(h.Class("ml-2"), star),
),
),
),
)
}

View file

@ -0,0 +1,23 @@
package partials
import "github.com/maddalax/htmgo/framework/h"
func SideBar() *h.Element {
return h.Div(
h.Class("w-40 top-[57px] absolute min-h-screen bg-neutral-50 border border-r-slate-300 p-3"),
h.Div(
h.Class("max-w-prose mx-auto"),
h.Div(
h.Class("flex flex-col gap-4"),
h.A(
h.Href("/docs"),
h.Text("Docs"),
),
h.A(
h.Href("/examples"),
h.Text("Examples"),
),
),
),
)
}

View file

@ -39,7 +39,7 @@
"experimental": {
"configFile": null,
"classRegex": [[
"tailwind|Class|h.Class\\(([^)]*)\\)",
"Class|h.Class\\(([^)]*)\\)",
"[\"'`]([^\"'`]*).*?[\"'`]"
]]
}