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
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"github.com/maddalax/htmgo/framework/h"
|
||||
"htmgo-site/ui"
|
||||
"os"
|
||||
"reflect"
|
||||
"runtime"
|
||||
"io"
|
||||
"log/slog"
|
||||
"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 {
|
||||
return fmt.Sprintf("https://github.com/maddalax/htmgo/tree/master/htmgo-site/partials%s.go", path)
|
||||
}
|
||||
|
||||
func RenderCodeToString(partial h.PartialFunc) *h.Element {
|
||||
path := getFunctionFilePath(partial)
|
||||
if path == "" {
|
||||
return h.Empty()
|
||||
func GetGithubRawPath(path string) string {
|
||||
return fmt.Sprintf("https://raw.githubusercontent.com/maddalax/htmgo/master/htmgo-site/partials%s.go", path)
|
||||
}
|
||||
bytes, err := os.ReadFile(path)
|
||||
|
||||
var RenderCodeToStringCached = h.CachedPerKeyT(time.Minute*30, func(snippet *Snippet) (string, h.GetElementFunc) {
|
||||
return snippet.path, func() *h.Element {
|
||||
return renderCodeToString(snippet)
|
||||
}
|
||||
})
|
||||
|
||||
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 {
|
||||
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(
|
||||
snippet != nil,
|
||||
func() *h.Element {
|
||||
return snippetView(snippet)
|
||||
return snippetView(ctx, snippet)
|
||||
},
|
||||
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(
|
||||
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(
|
||||
|
|
@ -63,6 +89,13 @@ func snippetView(snippet *Snippet) *h.Element {
|
|||
h.Class("text-slate-900"),
|
||||
),
|
||||
),
|
||||
h.If(
|
||||
snippet.externalRoute != "",
|
||||
h.Div(
|
||||
h.Class("mt-3"),
|
||||
viewSourceButton(snippet),
|
||||
),
|
||||
),
|
||||
),
|
||||
h.Div(
|
||||
h.ClassX("border px-8 py-4 rounded-md shadow-sm border-slate-200 w-full", map[string]bool{
|
||||
|
|
@ -70,45 +103,35 @@ func snippetView(snippet *Snippet) *h.Element {
|
|||
}),
|
||||
h.IfElse(
|
||||
snippet.externalRoute != "",
|
||||
h.Div(
|
||||
h.Class("relative"),
|
||||
h.IFrame(
|
||||
snippet.externalRoute,
|
||||
h.Class("h-full min-h-[800px] w-[50vw]"),
|
||||
),
|
||||
h.Div(
|
||||
h.Get(
|
||||
h.GetPartialPath(snippet.partial),
|
||||
"load",
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
h.Div(
|
||||
h.Class("flex flex-col gap-2 justify-center"),
|
||||
h.Div(
|
||||
h.Class("flex gap-2 items-center"),
|
||||
h.A(
|
||||
h.Fragment(
|
||||
githubLogo(),
|
||||
h.If(
|
||||
snippet.externalRoute != "",
|
||||
h.Text("View source"),
|
||||
),
|
||||
),
|
||||
h.Class("absolute top-0 left-0 w-full h-full bg-transparent cursor-pointer"),
|
||||
h.Href(
|
||||
h.Ternary(snippet.sourceCodePath == "", GetGithubPath(snippet.path), snippet.sourceCodePath),
|
||||
snippet.externalRoute,
|
||||
),
|
||||
h.Target("_blank"),
|
||||
),
|
||||
),
|
||||
h.Div(
|
||||
h.IfElseLazy(snippet.partial != nil, func() *h.Element {
|
||||
return snippet.partial(ctx).Root
|
||||
}, h.Empty),
|
||||
),
|
||||
),
|
||||
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.Div(
|
||||
h.Class("flex flex-col gap-2 justify-center"),
|
||||
viewSourceButton(snippet),
|
||||
RenderCodeToStringCached(snippet),
|
||||
),
|
||||
),
|
||||
),
|
||||
h.If(snippet.externalRoute == "", RenderCodeToString(snippet.partial)),
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ func SnippetSidebar() *h.Element {
|
|||
),
|
||||
),
|
||||
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 {
|
||||
return h.A(
|
||||
h.Href(entry.path),
|
||||
|
|
|
|||
|
|
@ -30,8 +30,18 @@ var ChatSnippet = Snippet{
|
|||
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{
|
||||
FormWithLoadingStateSnippet,
|
||||
UserAuthSnippet,
|
||||
ChatSnippet,
|
||||
HackerNewsSnippet,
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue