1
0
mirror of https://github.com/axzilla/templui.git synced 2025-02-21 00:12:48 +00:00

chore: make some changes on current pr, remove unused middleware

This commit is contained in:
axzilla 2025-02-09 08:29:56 +07:00
parent 2c0fefe972
commit 78a3cf066f
11 changed files with 42 additions and 103 deletions

View File

@ -1583,6 +1583,11 @@ body {
background-color: rgb(234 179 8 / var(--tw-bg-opacity, 1)); background-color: rgb(234 179 8 / var(--tw-bg-opacity, 1));
} }
.bg-gray-100 {
--tw-bg-opacity: 1;
background-color: rgb(243 244 246 / var(--tw-bg-opacity, 1));
}
.bg-opacity-50 { .bg-opacity-50 {
--tw-bg-opacity: 0.5; --tw-bg-opacity: 0.5;
} }
@ -2408,6 +2413,11 @@ body {
opacity: 0.5; opacity: 0.5;
} }
.dark\:bg-gray-700:is(.dark *) {
--tw-bg-opacity: 1;
background-color: rgb(55 65 81 / var(--tw-bg-opacity, 1));
}
.dark\:text-gray-200:is(.dark *) { .dark\:text-gray-200:is(.dark *) {
--tw-text-opacity: 1; --tw-text-opacity: 1;
color: rgb(229 231 235 / var(--tw-text-opacity, 1)); color: rgb(229 231 235 / var(--tw-text-opacity, 1));

View File

@ -47,15 +47,13 @@ func main() {
wrappedMux := middleware.WithURLPathValue( wrappedMux := middleware.WithURLPathValue(
middleware.CacheControlMiddleware( middleware.CacheControlMiddleware(
middleware.WithPreviewCheck(
mw.WithCSP(cspConfig)(mux), mw.WithCSP(cspConfig)(mux),
), ),
),
) )
mux.Handle("GET /", templ.Handler(pages.Landing())) mux.Handle("GET /", templ.Handler(pages.Landing()))
mux.Handle("GET /docs/components", http.RedirectHandler("/docs/components/accordion", http.StatusSeeOther))
mux.Handle("GET /docs/getting-started", http.RedirectHandler("/docs/introduction", http.StatusSeeOther)) mux.Handle("GET /docs/getting-started", http.RedirectHandler("/docs/introduction", http.StatusSeeOther))
mux.Handle("GET /docs/components", http.RedirectHandler("/docs/components/accordion", http.StatusSeeOther))
mux.Handle("GET /docs/introduction", templ.Handler(pages.Introduction())) mux.Handle("GET /docs/introduction", templ.Handler(pages.Introduction()))
mux.Handle("GET /docs/how-to-use", templ.Handler(pages.HowToUse())) mux.Handle("GET /docs/how-to-use", templ.Handler(pages.HowToUse()))
mux.Handle("GET /docs/themes", templ.Handler(pages.Themes())) mux.Handle("GET /docs/themes", templ.Handler(pages.Themes()))
@ -112,4 +110,3 @@ func SetupAssetsRoutes(mux *http.ServeMux) {
mux.Handle("GET /assets/", http.StripPrefix("/assets/", assetHandler)) mux.Handle("GET /assets/", http.StripPrefix("/assets/", assetHandler))
} }

View File

@ -1,7 +1,6 @@
package config package config
import ( import (
"context"
"fmt" "fmt"
"log" "log"
"os" "os"
@ -27,14 +26,3 @@ func LoadConfig() {
GoEnv: os.Getenv("GO_ENV"), GoEnv: os.Getenv("GO_ENV"),
} }
} }
type contextKey string
var PreviewContextKey = contextKey("preview")
func IsPreview(ctx context.Context) bool {
if preview, ok := ctx.Value(PreviewContextKey).(bool); ok {
return preview
}
return false
}

View File

@ -0,0 +1,7 @@
package ctxkeys
type contextKey string
const (
URLPathValue = contextKey("url_path_value")
)

View File

@ -3,26 +3,15 @@ package middleware
import ( import (
"context" "context"
"net/http" "net/http"
"strings"
"github.com/axzilla/templui/internal/config" "github.com/axzilla/templui/internal/ctxkeys"
"github.com/axzilla/templui/internal/utils"
) )
func WithPreviewCheck(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
isPreview := strings.HasPrefix(r.Host, "preview.")
ctx := context.WithValue(r.Context(), config.PreviewContextKey, isPreview)
next.ServeHTTP(w, r.WithContext(ctx))
})
}
func CacheControlMiddleware(next http.Handler) http.Handler { func CacheControlMiddleware(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Cache-Control", "max-age=0, must-revalidate, no-cache, no-store, private") w.Header().Set("Cache-Control", "max-age=0, must-revalidate, no-cache, no-store, private")
w.Header().Set("Pragma", "no-cache") w.Header().Set("Pragma", "no-cache")
w.Header().Set("Expires", "0") w.Header().Set("Expires", "0")
next.ServeHTTP(w, r) next.ServeHTTP(w, r)
}) })
} }
@ -32,11 +21,9 @@ func WithURLPathValue(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
ctx := context.WithValue( ctx := context.WithValue(
r.Context(), r.Context(),
utils.CtxURLPathValueKey, ctxkeys.URLPathValue,
r.URL.Path, r.URL.Path,
) )
next.ServeHTTP(w, r.WithContext(ctx)) next.ServeHTTP(w, r.WithContext(ctx))
}) })
} }

View File

@ -2,7 +2,6 @@ package layouts
import ( import (
"github.com/axzilla/templui/internal/config" "github.com/axzilla/templui/internal/config"
"github.com/axzilla/templui/internal/ui/modules"
"github.com/axzilla/templui/pkg/helpers" "github.com/axzilla/templui/pkg/helpers"
) )
@ -74,9 +73,6 @@ templ BaseLayout() {
> >
<div class="flex flex-col min-h-screen"> <div class="flex flex-col min-h-screen">
{ children... } { children... }
if config.IsPreview(ctx) {
@modules.PreviewIndicator()
}
</div> </div>
</body> </body>
</html> </html>

View File

@ -3,9 +3,9 @@ package modules
import ( import (
"github.com/axzilla/templui/internal/shared" "github.com/axzilla/templui/internal/shared"
wrappedicons "github.com/axzilla/templui/internal/ui/icons" wrappedicons "github.com/axzilla/templui/internal/ui/icons"
"github.com/axzilla/templui/internal/utils"
"github.com/axzilla/templui/pkg/components" "github.com/axzilla/templui/pkg/components"
"github.com/axzilla/templui/pkg/icons" "github.com/axzilla/templui/pkg/icons"
"github.com/axzilla/templui/internal/ctxkeys"
) )
templ Navbar() { templ Navbar() {
@ -51,19 +51,17 @@ templ NavbarMobileMenu() {
<ul class="mt-2 space-y-1"> <ul class="mt-2 space-y-1">
for _, link := range section.Links { for _, link := range section.Links {
<li> <li>
if link.Href == ctx.Value(utils.CtxURLPathValueKey) { if link.Href == ctx.Value(ctxkeys.URLPathValue) {
<a <a
href={ templ.SafeURL(link.Href) } href={ templ.SafeURL(link.Href) }
class={ "text-sm flex items-center px-4 py-2 rounded-md text-gray-700 dark:text-gray-200", class={ "text-sm flex items-center px-4 py-2 rounded-md text-gray-700 dark:text-gray-200 bg-gray-100 dark:bg-gray-700" }
"bg-gray-100 dark:bg-gray-700" }
> >
<span>{ link.Text }</span> <span>{ link.Text }</span>
</a> </a>
} else { } else {
<a <a
href={ templ.SafeURL(link.Href) } href={ templ.SafeURL(link.Href) }
class={ "text-sm flex items-center px-4 py-2 rounded-md text-gray-700 dark:text-gray-200", class={ "text-sm flex items-center px-4 py-2 rounded-md text-gray-700 dark:text-gray-200 hover:bg-gray-100 dark:hover:bg-gray-700" }
"hover:bg-gray-100 dark:hover:bg-gray-700" }
> >
<span>{ link.Text }</span> <span>{ link.Text }</span>
</a> </a>
@ -79,9 +77,7 @@ templ NavbarMobileMenu() {
class="mr-2 lg:hidden p-2 rounded-md text-gray-400 hover:text-gray-500 hover:bg-gray-100 focus:outline-none focus:ring-2 focus:ring-inset focus:ring-indigo-500" class="mr-2 lg:hidden p-2 rounded-md text-gray-400 hover:text-gray-500 hover:bg-gray-100 focus:outline-none focus:ring-2 focus:ring-inset focus:ring-indigo-500"
> >
@icons.SquareLibrary(icons.IconProps{}) @icons.SquareLibrary(icons.IconProps{})
// @Icon(IconProps{Name: "square-library"})
</button> </button>
} }
} }
} }

View File

@ -1,36 +0,0 @@
package modules
import "github.com/axzilla/templui/pkg/icons"
templ PreviewIndicator() {
<div
class="fixed bottom-4 left-4 z-50"
x-data="{ expanded: false }"
>
<div
class="relative bg-purple-500 text-white rounded-lg shadow-lg overflow-hidden"
@mouseenter="expanded = true"
@mouseleave="expanded = false"
>
// Base layout - always visible
<div class="flex items-center h-9 px-3">
<div class="flex items-center gap-2">
@icons.Sparkles(icons.IconProps{Size: "16", Class: "animate-pulse"})
<span class="text-sm font-medium">Preview Mode</span>
</div>
// Extra content - slides in/out
<div
class="flex items-center gap-3 overflow-hidden transition-all duration-300 ease-in-out"
:class="expanded ? 'ml-3 max-w-[200px] opacity-100' : 'max-w-0 opacity-0'"
>
<div class="border-l pl-3 whitespace-nowrap">
<a href="https://templui.io" class="text-sm hover:underline flex items-center gap-1">
Production Site
@icons.ArrowRight(icons.IconProps{Size: "14"})
</a>
</div>
</div>
</div>
</div>
</div>
}

View File

@ -1,7 +1,7 @@
package modules package modules
import "github.com/axzilla/templui/internal/shared" import "github.com/axzilla/templui/internal/shared"
import "github.com/axzilla/templui/internal/utils" import "github.com/axzilla/templui/internal/ctxkeys"
templ Sidebar() { templ Sidebar() {
<aside class="h-full"> <aside class="h-full">
@ -14,7 +14,7 @@ templ Sidebar() {
<ul class="mt-2 space-y-1"> <ul class="mt-2 space-y-1">
for _, link := range section.Links { for _, link := range section.Links {
<li> <li>
if link.Href == ctx.Value(utils.CtxURLPathValueKey) { if link.Href == ctx.Value(ctxkeys.URLPathValue) {
<a href={ templ.SafeURL(link.Href) } class="text-sm flex items-center px-4 py-2 rounded-md text-gray-700 dark:text-gray-200 bg-gray-100 dark:bg-gray-700"> <a href={ templ.SafeURL(link.Href) } class="text-sm flex items-center px-4 py-2 rounded-md text-gray-700 dark:text-gray-200 bg-gray-100 dark:bg-gray-700">
<span>{ link.Text }</span> <span>{ link.Text }</span>
</a> </a>
@ -33,4 +33,3 @@ templ Sidebar() {
</div> </div>
</aside> </aside>
} }

View File

@ -3,26 +3,14 @@ package utils
import ( import (
"crypto/rand" "crypto/rand"
"encoding/base64" "encoding/base64"
"fmt"
) )
type CtxKey string func GenerateNonce() (string, error) {
const CtxURLPathValueKey = CtxKey("url_value")
func GenerateNonce() string {
try := 0
Retry:
try++
nonceBytes := make([]byte, 16) nonceBytes := make([]byte, 16)
_, err := rand.Read(nonceBytes) _, err := rand.Read(nonceBytes)
if err != nil { if err != nil {
if try < 2 { return "", fmt.Errorf("failed to generate nonce: %w", err)
goto Retry
} }
return base64.StdEncoding.EncodeToString(nonceBytes), nil
return ""
}
return base64.StdEncoding.EncodeToString(nonceBytes)
} }

View File

@ -2,6 +2,7 @@ package middleware
import ( import (
"fmt" "fmt"
"log"
"net/http" "net/http"
"strings" "strings"
@ -16,7 +17,13 @@ type CSPConfig struct {
func WithCSP(config CSPConfig) func(http.Handler) http.Handler { func WithCSP(config CSPConfig) func(http.Handler) http.Handler {
return func(next http.Handler) http.Handler { return func(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
nonce := utils.GenerateNonce() nonce, err := utils.GenerateNonce()
if err != nil {
log.Printf("failed to generate nonce: %v", err)
w.Header().Set("Content-Security-Policy", "script-src 'self'")
http.Error(w, "Internal Server Error", http.StatusInternalServerError)
return
}
// Combine all script sources // Combine all script sources
scriptSources := append( scriptSources := append(