render the code from github since we wont have it locally
This commit is contained in:
parent
f1f173715e
commit
1ca8bbf6e0
5 changed files with 103 additions and 55 deletions
|
|
@ -1,38 +1,45 @@
|
||||||
package snippets
|
package snippets
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/maddalax/htmgo/framework/h"
|
"github.com/maddalax/htmgo/framework/h"
|
||||||
"htmgo-site/ui"
|
"htmgo-site/ui"
|
||||||
"os"
|
"io"
|
||||||
"reflect"
|
"log/slog"
|
||||||
"runtime"
|
"net/http"
|
||||||
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
func getFunctionFilePath(fn interface{}) string {
|
|
||||||
// Get the function pointer using reflection
|
|
||||||
ptr := reflect.ValueOf(fn).Pointer()
|
|
||||||
// Get the file path and line number using runtime
|
|
||||||
fnInfo := runtime.FuncForPC(ptr)
|
|
||||||
if fnInfo == nil {
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
file, _ := fnInfo.FileLine(ptr)
|
|
||||||
return file
|
|
||||||
}
|
|
||||||
|
|
||||||
func GetGithubPath(path string) string {
|
func GetGithubPath(path string) string {
|
||||||
return fmt.Sprintf("https://github.com/maddalax/htmgo/tree/master/htmgo-site/partials%s.go", path)
|
return fmt.Sprintf("https://github.com/maddalax/htmgo/tree/master/htmgo-site/partials%s.go", path)
|
||||||
}
|
}
|
||||||
|
|
||||||
func RenderCodeToString(partial h.PartialFunc) *h.Element {
|
func GetGithubRawPath(path string) string {
|
||||||
path := getFunctionFilePath(partial)
|
return fmt.Sprintf("https://raw.githubusercontent.com/maddalax/htmgo/master/htmgo-site/partials%s.go", path)
|
||||||
if path == "" {
|
}
|
||||||
return h.Empty()
|
|
||||||
|
var RenderCodeToStringCached = h.CachedPerKeyT(time.Minute*30, func(snippet *Snippet) (string, h.GetElementFunc) {
|
||||||
|
return snippet.path, func() *h.Element {
|
||||||
|
return renderCodeToString(snippet)
|
||||||
}
|
}
|
||||||
bytes, err := os.ReadFile(path)
|
})
|
||||||
|
|
||||||
|
func renderCodeToString(snippet *Snippet) *h.Element {
|
||||||
|
url := GetGithubRawPath(snippet.path)
|
||||||
|
slog.Info("getting snippet source code", slog.String("url", url))
|
||||||
|
resp, err := http.Get(url)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return h.Empty()
|
return h.Empty()
|
||||||
}
|
}
|
||||||
return ui.CodeSnippet(string(bytes), "border-radius: 0.5rem;")
|
defer resp.Body.Close()
|
||||||
|
if resp.StatusCode != http.StatusOK {
|
||||||
|
return h.Empty()
|
||||||
|
}
|
||||||
|
out := bytes.NewBuffer(nil)
|
||||||
|
_, err = io.Copy(out, resp.Body)
|
||||||
|
if err != nil {
|
||||||
|
return h.Empty()
|
||||||
|
}
|
||||||
|
return ui.CodeSnippet(out.String(), "border-radius: 0.5rem;")
|
||||||
}
|
}
|
||||||
|
|
|
||||||
8
htmgo-site/pages/snippets/hackernews.go
Normal file
8
htmgo-site/pages/snippets/hackernews.go
Normal file
|
|
@ -0,0 +1,8 @@
|
||||||
|
package snippets
|
||||||
|
|
||||||
|
import "github.com/maddalax/htmgo/framework/h"
|
||||||
|
|
||||||
|
func HackerNewsExample(ctx *h.RequestContext) *h.Page {
|
||||||
|
SetSnippet(ctx, &HackerNewsSnippet)
|
||||||
|
return Index(ctx)
|
||||||
|
}
|
||||||
|
|
@ -36,7 +36,7 @@ func Index(ctx *h.RequestContext) *h.Page {
|
||||||
h.IfElseLazy(
|
h.IfElseLazy(
|
||||||
snippet != nil,
|
snippet != nil,
|
||||||
func() *h.Element {
|
func() *h.Element {
|
||||||
return snippetView(snippet)
|
return snippetView(ctx, snippet)
|
||||||
},
|
},
|
||||||
emptyState,
|
emptyState,
|
||||||
),
|
),
|
||||||
|
|
@ -47,7 +47,33 @@ func Index(ctx *h.RequestContext) *h.Page {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
func snippetView(snippet *Snippet) *h.Element {
|
func viewSourceButton(snippet *Snippet) *h.Element {
|
||||||
|
return h.Div(
|
||||||
|
h.Class("flex gap-2 items-center"),
|
||||||
|
h.A(
|
||||||
|
h.Fragment(
|
||||||
|
githubLogo(),
|
||||||
|
h.If(
|
||||||
|
snippet.externalRoute != "",
|
||||||
|
h.Text("View source"),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
h.Href(
|
||||||
|
h.Ternary(snippet.sourceCodePath == "", GetGithubPath(snippet.path), snippet.sourceCodePath),
|
||||||
|
),
|
||||||
|
h.Class("flex gap-2 items-center font-sm text-blue-500 hover:text-blue-400"),
|
||||||
|
),
|
||||||
|
h.If(
|
||||||
|
snippet.externalRoute == "",
|
||||||
|
h.H3(
|
||||||
|
h.Text("Source Code"),
|
||||||
|
h.Class("text-lg font-bold"),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
func snippetView(ctx *h.RequestContext, snippet *Snippet) *h.Element {
|
||||||
return h.Div(
|
return h.Div(
|
||||||
h.Class("flex flex-col mx-auto items-center gap-6 max-w-[90vw] md:max-w-[75vw] xl:max-w-4xl px-8"),
|
h.Class("flex flex-col mx-auto items-center gap-6 max-w-[90vw] md:max-w-[75vw] xl:max-w-4xl px-8"),
|
||||||
h.Div(
|
h.Div(
|
||||||
|
|
@ -63,6 +89,13 @@ func snippetView(snippet *Snippet) *h.Element {
|
||||||
h.Class("text-slate-900"),
|
h.Class("text-slate-900"),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
h.If(
|
||||||
|
snippet.externalRoute != "",
|
||||||
|
h.Div(
|
||||||
|
h.Class("mt-3"),
|
||||||
|
viewSourceButton(snippet),
|
||||||
|
),
|
||||||
|
),
|
||||||
),
|
),
|
||||||
h.Div(
|
h.Div(
|
||||||
h.ClassX("border px-8 py-4 rounded-md shadow-sm border-slate-200 w-full", map[string]bool{
|
h.ClassX("border px-8 py-4 rounded-md shadow-sm border-slate-200 w-full", map[string]bool{
|
||||||
|
|
@ -70,44 +103,34 @@ func snippetView(snippet *Snippet) *h.Element {
|
||||||
}),
|
}),
|
||||||
h.IfElse(
|
h.IfElse(
|
||||||
snippet.externalRoute != "",
|
snippet.externalRoute != "",
|
||||||
h.IFrame(
|
h.Div(
|
||||||
snippet.externalRoute,
|
h.Class("relative"),
|
||||||
h.Class("h-full min-h-[800px] w-[50vw]"),
|
h.IFrame(
|
||||||
|
snippet.externalRoute,
|
||||||
|
h.Class("h-full min-h-[800px] w-[50vw]"),
|
||||||
|
),
|
||||||
|
h.A(
|
||||||
|
h.Class("absolute top-0 left-0 w-full h-full bg-transparent cursor-pointer"),
|
||||||
|
h.Href(
|
||||||
|
snippet.externalRoute,
|
||||||
|
),
|
||||||
|
h.Target("_blank"),
|
||||||
|
),
|
||||||
),
|
),
|
||||||
h.Div(
|
h.Div(
|
||||||
h.Get(
|
h.IfElseLazy(snippet.partial != nil, func() *h.Element {
|
||||||
h.GetPartialPath(snippet.partial),
|
return snippet.partial(ctx).Root
|
||||||
"load",
|
}, h.Empty),
|
||||||
),
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
h.Div(
|
h.If(
|
||||||
h.Class("flex flex-col gap-2 justify-center"),
|
snippet.externalRoute == "",
|
||||||
h.Div(
|
h.Div(
|
||||||
h.Class("flex gap-2 items-center"),
|
h.Class("flex flex-col gap-2 justify-center"),
|
||||||
h.A(
|
viewSourceButton(snippet),
|
||||||
h.Fragment(
|
RenderCodeToStringCached(snippet),
|
||||||
githubLogo(),
|
|
||||||
h.If(
|
|
||||||
snippet.externalRoute != "",
|
|
||||||
h.Text("View source"),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
h.Href(
|
|
||||||
h.Ternary(snippet.sourceCodePath == "", GetGithubPath(snippet.path), snippet.sourceCodePath),
|
|
||||||
),
|
|
||||||
h.Class("flex gap-1 items-center font-sm text-blue-500 hover:text-blue-400"),
|
|
||||||
),
|
|
||||||
h.If(
|
|
||||||
snippet.externalRoute == "",
|
|
||||||
h.H3(
|
|
||||||
h.Text("Source Code"),
|
|
||||||
h.Class("text-lg font-bold"),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
h.If(snippet.externalRoute == "", RenderCodeToString(snippet.partial)),
|
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,7 @@ func SnippetSidebar() *h.Element {
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
h.Div(
|
h.Div(
|
||||||
h.Class("flex flex-col gap-4"),
|
h.Class("flex flex-col gap-2"),
|
||||||
h.List(Snippets, func(entry Snippet, index int) *h.Element {
|
h.List(Snippets, func(entry Snippet, index int) *h.Element {
|
||||||
return h.A(
|
return h.A(
|
||||||
h.Href(entry.path),
|
h.Href(entry.path),
|
||||||
|
|
|
||||||
|
|
@ -30,8 +30,18 @@ var ChatSnippet = Snippet{
|
||||||
sourceCodePath: "https://github.com/maddalax/htmgo/tree/master/examples/chat",
|
sourceCodePath: "https://github.com/maddalax/htmgo/tree/master/examples/chat",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var HackerNewsSnippet = Snippet{
|
||||||
|
name: "Hacker News Clone",
|
||||||
|
description: "A hacker news reader clone built with htmgo",
|
||||||
|
sidebarName: "Hacker News Clone",
|
||||||
|
path: "/snippets/hackernews",
|
||||||
|
externalRoute: "https://hn.htmgo.dev",
|
||||||
|
sourceCodePath: "https://github.com/maddalax/htmgo/tree/master/examples/hackernews",
|
||||||
|
}
|
||||||
|
|
||||||
var Snippets = []Snippet{
|
var Snippets = []Snippet{
|
||||||
FormWithLoadingStateSnippet,
|
FormWithLoadingStateSnippet,
|
||||||
UserAuthSnippet,
|
UserAuthSnippet,
|
||||||
ChatSnippet,
|
ChatSnippet,
|
||||||
|
HackerNewsSnippet,
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue