### Minimal Production-Ready Xun Example Source: https://github.com/yaitoo/xun/blob/main/AGENTS.md This Go code snippet demonstrates how to set up a minimal, production-ready Xun application. It includes options for development mode with hot reloading and a production mode using embedded file system. It also configures a basic GET route and starts the HTTP server. ```go //go:embed app var fsys embed.FS func main(){ var dev bool flag.BoolVar(&dev, "dev", false, "dev") flag.Parse() var opts []xun.Option if dev { opts = []xun.Option{xun.WithFsys(os.DirFS("./app")), xun.WithWatch()} } else { v, _ := fs.Sub(fsys, "app"); opts = []xun.Option{xun.WithFsys(v)} } app := xun.New(opts..., xun.WithCompressor(&xun.GzipCompressor{})) app.Get("/{$}", func(c *xun.Context) error { return c.View(map[string]string{"hello":"xun"}) }) app.Start(); defer app.Close() http.ListenAndServe(":80", http.DefaultServeMux) } ``` -------------------------------- ### Create and Start Xun App Source: https://github.com/yaitoo/xun/blob/main/AGENTS.md Initializes a new Xun application with specified configurations like middleware, file system, hot-reloading, and compression. It then starts the app and ensures it's closed gracefully using defer. The application listens for HTTP requests on port 80. ```go app := xun.New( xun.WithMux(http.DefaultServeMux), xun.WithFsys(viewsFS), // fs root of components/layouts/pages/views/public/text xun.WithWatch(), // dev only xun.WithCompressor(&xun.GzipCompressor{}, &xun.DeflateCompressor{}), ) app.Start() def app.Close() http.ListenAndServe(":80", http.DefaultServeMux) ``` -------------------------------- ### Install Xun Web Framework (Go) Source: https://github.com/yaitoo/xun/blob/main/README.md Installs the Xun web framework using Go modules. Supports installation from the main branch or the latest release. ```go go get github.com/yaitoo/xun@main ``` ```go go get github.com/yaitoo/xun@latest ``` -------------------------------- ### Setup SSE Server with Go Source: https://context7.com/yaitoo/xun/llms.txt Implement a Server-Sent Events (SSE) server using the yaitoo/xun/ext/sse package for real-time push notifications. This setup includes creating an SSE server, handling client connections, sending messages to specific users, broadcasting messages to all clients, and managing server shutdown. It requires the `github.com/yaitoo/xun` and `github.com/yaitoo/xun/ext/sse` packages. ```go package main import ( "context" "net/http" "time" "github.com/yaitoo/xun" "github.com/yaitoo/xun/ext/sse" ) func main() { app := xun.New() // Create SSE server sseServer := sse.New() // Start keep-alive goroutine go sseServer.KeepAlive(context.Background()) // SSE endpoint app.Get("/events/{userID}", func(c *xun.Context) error { userID := c.Request.PathValue("userID") // Join SSE connection client, connID, isNew, err := sseServer.Join(userID, c.Response) if err != nil { c.WriteStatus(http.StatusBadRequest) return xun.ErrCancelled } // Send welcome message to new clients if isNew { client.Send(sse.TextEvent{ Name: "welcome", Data: "Connected to event stream", }) } // Wait for disconnect client.Wait() // Clean up sseServer.Leave(userID, connID) return nil }) // Send message to specific user app.Post("/notify/{userID}", func(c *xun.Context) error { userID := c.Request.PathValue("userID") client := sseServer.Get(userID) if client == nil { c.WriteStatus(http.StatusNotFound) return c.View(map[string]string{"error": "user not connected"}) } err := client.Send(sse.TextEvent{ Name: "notification", Data: "You have a new message", }) if err != nil { return err } return c.View(map[string]string{"status": "sent"}) }) // Broadcast to all connected users app.Post("/broadcast", func(c *xun.Context) error { ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) defer cancel() errors, err := sseServer.Broadcast(ctx, sse.TextEvent{ Name: "announcement", Data: "Server maintenance in 10 minutes", }) if err != nil { return err } return c.View(map[string]any{ "status": "broadcast complete", "errors": len(errors), }) }) // Shutdown endpoint app.Post("/shutdown", func(c *xun.Context) error { sseServer.Shutdown() return c.View(map[string]string{"status": "shutdown complete"}) }) app.Start() http.ListenAndServe(":8080", nil) } ``` -------------------------------- ### Serve HTTP with Proxy Protocol in Go Source: https://github.com/yaitoo/xun/blob/main/README.md This Go code snippet shows how to start an HTTP server that supports the PROXY protocol. It configures a new Xun application with a ServeMux, starts the app, and then uses proxyproto.ListenAndServe to serve traffic. ```go mux := http.NewServeMux() srv := &http.Server{ Addr: ":80", Handler: mux, } app := xun.New(WithMux(mux)) app.Start() defer app.Close() // srv.ListenAndServe() proxyproto.ListenAndServe(srv) ``` -------------------------------- ### Bash: Install Tailwind CSS Source: https://github.com/yaitoo/xun/blob/main/README.md This bash script demonstrates the initial steps for installing Tailwind CSS. It uses npm to install the tailwindcss package as a development dependency and then generates the tailwind.config.js configuration file. These commands are essential prerequisites for setting up Tailwind CSS in a project. ```bash npm install -D tailwindcss npx tailwindcss init ``` -------------------------------- ### ACL Configuration File Source: https://github.com/yaitoo/xun/blob/main/README.md An example INI-formatted configuration file for the ACL middleware in Xun. It demonstrates how to define rules for allowed/denied hosts, IP networks, countries, and host redirection settings. ```ini [allow_hosts] abc.com www.abc.com [allow_ipnets] 89.207.132.170/24 # ::1 ; 127.0.0.1 [deny_ipnets] * [allow_countries] [deny_countries] us [host_redirect] url=http://yaitoo.cn status_code=302 ``` -------------------------------- ### Create Group with Middleware and Route Source: https://github.com/yaitoo/xun/blob/main/AGENTS.md Creates a new route group '/admin' and applies a global authentication middleware ('authMiddleware') to all routes within this group. A GET route is then defined at '/{$}' within the admin group, which will be handled by the 'handler' function after the middleware. ```go admin := app.Group("/admin") admin.Use(authMiddleware) admin.Get("/{$}", handler) ``` -------------------------------- ### Serve HTTPS with Proxy Protocol and Auto TLS in Go Source: https://github.com/yaitoo/xun/blob/main/README.md This Go code snippet illustrates how to configure and start an HTTPS server that supports the PROXY protocol and automatic TLS certificate management. It sets up autotls, configures both HTTP and HTTPS servers, and uses proxyproto.ListenAndServeTLS. ```go httpsServer := &http.Server{ Addr: ":443", Handler: mux, } autotls.New(autotls.WithCache(autocert.DirCache("./certs")), autotls.WithHosts("yaitoo.cn", "www.yaitoo.cn")), Configure(srv, httpsServer) // httpsServer.ListenAndServeTLS( ", ") proxyproto.ListenAndServeTLS(httpsServer, "", "") ``` -------------------------------- ### Set and Get Cookie in Go Source: https://github.com/yaitoo/xun/blob/main/README.md These Go snippets show how to set, get, and delete cookies using the 'cookie' package. It covers basic cookie operations, URL encoding for values, and signed cookies with HMAC validation. ```go cookie.Set(ctx, http.Cookie{Name: "test", Value: "value"}) // Set-Cookie: test=dmFsdWU= ``` ```go v, err := cookie.Get(ctx,"test") fmt.Println(v) // value ``` ```go ts, err := cookie.SetSigned(ctx,http.Cookie{Name: "test", Value: "value"},[]byte("secret")) // ts is current timestamp v, ts, err := cookie.GetSigned(ctx, "test",[]byte("secret")) // v is value, ts is the timestamp that was signed ``` ```go cookie.Delete(ctx, http.Cookie{Name: "test", Value: "dmFsdWU="}) // Set-Cookie: test=; Expires=Thu, 01 Jan 1970 00:00:00 GMT; Max-Age=0 ``` -------------------------------- ### Xun Go Context Operations for Request/Response Handling Source: https://context7.com/yaitoo/xun/llms.txt Illustrates how to use the Xun Context object to access request data such as path parameters and headers, and manipulate responses by setting status codes, writing headers, and rendering views. Includes examples for redirects and retrieving referer URLs. ```go package main import ( "net/http" "github.com/yaitoo/xun" ) func main() { app := xun.New() app.Get("/profile", func(c *xun.Context) error { // Get path parameters id := c.Request.PathValue("id") // Get Accept header languages languages := c.AcceptLanguage() // Get Accept header MIME types acceptTypes := c.Accept() // Store temporary data in context c.Set("UserID", id) c.Set("Language", languages[0]) // Retrieve data from context userID := c.Get("UserID").(string) // Write custom headers c.WriteHeader("X-User-ID", userID) c.WriteHeader("X-Request-ID", "req-123") // Set status code c.WriteStatus(http.StatusOK) // Render view with data return c.View(map[string]any{ "ID": userID, "Language": languages[0], "Accept": acceptTypes[0].String(), }) }) // Redirect example app.Get("/old-path", func(c *xun.Context) error { c.Redirect("/new-path", http.StatusMovedPermanently) return xun.ErrCancelled }) // Get referer app.Post("/submit", func(c *xun.Context) error { referer := c.RequestReferer() c.Set("RefererURL", referer) return c.View(map[string]string{"status": "success"}) }) app.Start() http.ListenAndServe(":8080", nil) } ``` -------------------------------- ### Handle PROXY Protocol Headers with Go Source: https://context7.com/yaitoo/xun/llms.txt This Go code snippet demonstrates how to enable support for HAProxy PROXY protocol v1 and v2 within an HTTP server. It utilizes the `proxyproto` extension from the `github.com/yaitoo/xun/ext/proxyproto` package to preserve the real client IP address when behind a load balancer. The code configures a standard `http.Server` and then uses `proxyproto.ListenAndServe` to start it, ensuring that incoming requests are correctly parsed. ```go package main import ( "net/http" "github.com/yaitoo/xun" "github.com/yaitoo/xun/ext/proxyproto" ) func main() { mux := http.NewServeMux() app := xun.New(xun.WithMux(mux)) app.Get("/", func(c *xun.Context) error { // Real client IP is preserved through proxy clientIP := c.Request.RemoteAddr return c.View(map[string]string{ "client_ip": clientIP, "status": "ok", }) }) app.Start() defer app.Close() // HTTP server with PROXY protocol support httpServer := &http.Server{ Addr: ":80", Handler: mux, } // Use proxyproto.ListenAndServe instead of httpServer.ListenAndServe() proxyproto.ListenAndServe(httpServer) // For HTTPS with PROXY protocol // httpsServer := &http.Server{ // Addr: ":443", // Handler: mux, // } // proxyproto.ListenAndServeTLS(httpsServer, "cert.pem", "key.pem") } ``` -------------------------------- ### Define Route with Explicit Viewer Source: https://github.com/yaitoo/xun/blob/main/AGENTS.md Defines a GET route for the root path '/{$}'. The handler function returns a JSON view containing a map with a 'Name' field. An explicit HtmlViewer is provided as an option, allowing for content negotiation to render via HTML templates if configured. ```go app.Get("/{$}", func(c *xun.Context) error { return c.View(map[string]string{"Name":"xun"}) }, xun.WithViewer(&xun.HtmlViewer{/* render via views/... if you set it */})) ``` -------------------------------- ### Define Route with Dynamic Segment and View Response Source: https://github.com/yaitoo/xun/blob/main/AGENTS.md Defines a GET route with a dynamic segment '/users/{id}'. The handler extracts the 'id' from the request path parameters and renders a User view with the extracted ID. It returns an error, which Xun framework handles. ```go app.Get("/users/{id}", func(c *xun.Context) error { id := c.Request.PathValue("id") return c.View(User{Name: id}) }) ``` -------------------------------- ### Integrate HTMX for Dynamic Server-Side Rendering in Go Source: https://context7.com/yaitoo/xun/llms.txt This Go code snippet demonstrates how to integrate HTMX for dynamic server-side rendering using the Xun framework. It sets up an HTMX extension using `htmx.New()` and provides handlers for serving the HTMX extension JavaScript, handling login forms with validation, and performing redirects. The example showcases how to use `htmx.WriteHeader` to send custom HTMX triggers and `c.Redirect` for HTMX-aware redirects. ```go package main import ( "net/http" "github.com/yaitoo/xun" "github.com/yaitoo/xun/ext/form" "github.com/yaitoo/xun/ext/htmx" ) type LoginForm struct { Email string `form:"email" validate:"required,email" Password string `form:"password" validate:"required" } func main() { app := xun.New(xun.WithInterceptor(htmx.New())) // Serve HTMX extension JavaScript app.Get("/htmx-ext.js", htmx.HandleFunc()) app.Get("/login", func(c *xun.Context) error { return c.View(map[string]string{"title": "Login"}) }) app.Post("/login", func(c *xun.Context) error { loginForm, err := form.BindForm[LoginForm](c.Request) if err != nil { c.WriteStatus(http.StatusBadRequest) return xun.ErrCancelled } if !loginForm.Validate(c.AcceptLanguage()...){ c.WriteStatus(http.StatusBadRequest) return c.View(loginForm) } // Check credentials if loginForm.Data.Email != "user@example.com" || loginForm.Data.Password != "secret" { // Send custom HTMX trigger htmx.WriteHeader(c, htmx.HxTrigger, htmx.HxHeader[string]{ "showMessage": "Invalid email or password", }) c.WriteStatus(http.StatusBadRequest) return c.View(loginForm) } // Set session cookie http.SetCookie(c.Response, &http.Cookie{ Name: "session", Value: loginForm.Data.Email, Path: "/", MaxAge: 3600, HttpOnly: true, Secure: true, SameSite: http.SameSiteLaxMode, }) // Redirect via HTMX c.Redirect("/dashboard") return nil }) app.Get("/dashboard", func(c *xun.Context) error { session, err := c.Request.Cookie("session") if err != nil || session.Value == "" { c.Redirect("/login") return xun.ErrCancelled } return c.View(map[string]string{ "user": session.Value, }) }) app.Start() http.ListenAndServe(":8080", nil) } ``` -------------------------------- ### Register Route Handlers in Xun Go Application Source: https://context7.com/yaitoo/xun/llms.txt Shows how to register HTTP route handlers for different methods (GET, POST, PUT, DELETE) in a Xun application, including handling dynamic path parameters and rendering different response types. ```go package main import ( "net/http" "github.com/yaitoo/xun" ) type User struct { ID string `json:"id"` Name string `json:"name"` Email string `json:"email"` } func main() { app := xun.New() // GET route app.Get("/{$}", func(c *xun.Context) error { return c.View(map[string]string{ "Name": "go-xun", }) }) // POST route app.Post("/users", func(c *xun.Context) error { user := User{ ID: "123", Name: "John Doe", Email: "john@example.com", } return c.View(user) }) // Dynamic route with path parameter app.Get("/user/{id}", func(c *xun.Context) error { id := c.Request.PathValue("id") user := User{ ID: id, Name: "User " + id, } return c.View(user) }) // PUT and DELETE routes app.Put("/users/{id}", func(c *xun.Context) error { c.WriteStatus(http.StatusOK) return nil }) app.Delete("/users/{id}", func(c *xun.Context) error { c.WriteStatus(http.StatusNoContent) return nil }) app.Start() http.ListenAndServe(":8080", nil) } ``` -------------------------------- ### Go: Send SSE Events Source: https://github.com/yaitoo/xun/blob/main/README.md This Go code demonstrates how to send Server-Sent Events (SSE) using the 'sse' extension. It shows how to retrieve a specific SSE connection by user ID and send a named text event, or broadcast an event to all connected clients. It also includes an example of shutting down the SSE server and closing all connections. Dependencies include the 'sse' extension and Go's 'context' package. ```go // push an event to the user u := ss.Get("user_id") if u != nil { u.Send(sse.TextEvent{ Name:"showMessage", Data:"Hello", }) } // broadcast an event to all users ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) defuncancel() ss.Broadcast(ctx, sse.TextEvent{ Name:"shutdown", Data:"Server is shutting down", }) // shutdown server and close all user connections ss.Shutdown() ``` -------------------------------- ### HTML: Link Compiled CSS and JS Source: https://github.com/yaitoo/xun/blob/main/README.md This HTML snippet shows how to link the compiled Tailwind CSS file (`theme.css`) and the application JavaScript file (`app.js`) in the `assets.html` file. It also includes a link to `skin.css`. This setup ensures that the project's styles and scripts are correctly loaded in the browser. ```html ``` -------------------------------- ### HTML: Include htmx.js and htmx-ext.js Source: https://github.com/yaitoo/xun/blob/main/README.md This HTML snippet illustrates how to include the htmx.js library and the custom `htmx-ext.js` script in a web page. It also includes links to CSS files and the main application JavaScript (`app.js`). This setup is crucial for enabling dynamic content loading and interactive features powered by htmx. ```html ``` -------------------------------- ### Cookie Management in Go with Xun Source: https://context7.com/yaitoo/xun/llms.txt Provides functions for setting, getting, and deleting cookies in Go using the Xun framework's cookie extension. Supports both standard and signed (HMAC protected) cookies with automatic encoding/decoding. ```go package main import ( "net/http" "time" "github.com/yaitoo/xun" "github.com/yaitoo/xun/ext/cookie" ) func main() { app := xun.New() secretKey := []byte("my-secret-key-32-bytes-long!!") // Set cookie (base64 encoded) app.Get("/set-cookie", func(c *xun.Context) error { err := cookie.Set(c, http.Cookie{ Name: "user_pref", Value: "theme=dark;lang=en", Path: "/", MaxAge: 3600, HttpOnly: true, Secure: true, SameSite: http.SameSiteLaxMode, }) if err != nil { return err } return c.View(map[string]string{"status": "cookie set"}) }) // Get cookie (automatically decoded from base64) app.Get("/get-cookie", func(c *xun.Context) error { value, err := cookie.Get(c, "user_pref") if err != nil { c.WriteStatus(http.StatusNotFound) return c.View(map[string]string{"error": "cookie not found"}) } return c.View(map[string]string{"value": value}) }) // Set signed cookie (HMAC protected) app.Get("/set-signed", func(c *xun.Context) error { timestamp, err := cookie.SetSigned(c, http.Cookie{ Name: "session", Value: "user-id-123", Path: "/", MaxAge: 7200, HttpOnly: true, Secure: true, }, secretKey) if err != nil { return err } c.Set("timestamp", timestamp) return c.View(map[string]any{"status": "signed cookie set", "ts": timestamp}) }) // Get signed cookie (validates HMAC) app.Get("/get-signed", func(c *xun.Context) error { value, timestamp, err := cookie.GetSigned(c, "session", secretKey) if err != nil { c.WriteStatus(http.StatusUnauthorized) return c.View(map[string]string{"error": "invalid or missing session"}) } return c.View(map[string]any{ "value": value, "timestamp": timestamp, }) }) // Delete cookie app.Get("/delete-cookie", func(c *xun.Context) error { err := cookie.Delete(c, http.Cookie{Name: "user_pref"}) if err != nil { return err } return c.View(map[string]string{"status": "cookie deleted"}) }) app.Start() http.ListenAndServe(":8080", nil) } ``` -------------------------------- ### Initialize Xun Web Application in Go Source: https://context7.com/yaitoo/xun/llms.txt Demonstrates how to initialize a new Xun application with default settings, custom file system and watch options, or custom configurations like HTTP multiplexers and response compressors. ```go package main import ( "net/http" "os" "github.com/yaitoo/xun" ) func main() { // Basic application with default settings app := xun.New() // Application with file system and view engines app := xun.New( xun.WithFsys(os.DirFS("./app")), xun.WithWatch(), // Enable hot reload in development ) // Application with custom configuration mux := http.NewServeMux() app := xun.New( xun.WithMux(mux), xun.WithCompressor(&xun.GzipCompressor{}, &xun.DeflateCompressor{}), xun.WithHandlerViewers(&xun.JsonViewer{}, &xun.HtmlViewer{}), ) app.Start() defer app.Close() http.ListenAndServe(":8080", http.DefaultServeMux) } ``` -------------------------------- ### Set up Auto TLS Certificates in Go Source: https://github.com/yaitoo/xun/blob/main/README.md This Go code demonstrates setting up automatic TLS certificate management using autotls.Configure. It initializes a new autotls instance with certificate cache and hosts, then configures HTTP and HTTPS servers. ```go mux := http.NewServeMux() app := xun.New(xun.WithMux(mux)) //... httpServer := &http.Server{ Addr: ":http", //... } httpsServer := &http.Server{ Addr: ":https", //... } autotls. New(autotls.WithCache(autocert.DirCache("./certs")), autotls.WithHosts("abc.com", "123.com")), Configure(httpServer, httpsServer) go httpServer.ListenAndServe() go httpsServer.ListenAndServeTLS("", "") ``` -------------------------------- ### Go: Serve htmx-ext.js Source: https://github.com/yaitoo/xun/blob/main/README.md This Go code snippet demonstrates how to serve the `htmx-ext.js` file within a Xun web application. It uses the `htmx.HandleFunc()` to provide the necessary JavaScript library that enables seamless integration between native JavaScript methods and htmx features, enhancing interactive capabilities. ```go app.Get("/htmx-ext.js", htmx.HandleFunc()) ``` -------------------------------- ### Deploy Application with Go Embed Directive Source: https://github.com/yaitoo/xun/blob/main/README.md This Go code snippet demonstrates how to embed application assets into a single binary using Go's `//go:embed` directive. It differentiates between development (using local filesystem and watching for changes) and production (using embedded resources) environments. This approach creates dependency-free deployment. ```go //go:embed app var fsys embed.FS func main() { var dev bool flag.BoolVar(&dev, "dev", false, "it is development environment") flag.Parse() var opts []xun.Option if dev { // use local filesystem in development, and watch files to reload automatically opts = []xun.Option{xun.WithFsys(os.DirFS("./app")), xun.WithWatch()} } else { // use embed resources in production environment views, _ := fs.Sub(fsys, "app") opts = []xun.Option{xun.WithFsys(views)} } app := xun.New(opts...) //... app.Start() defer app.Close() if dev { slog.Default().Info("xun-admin is running in development") } else { slog.Default().Info("xun-admin is running in production") } err := http.ListenAndServe(":80", http.DefaultServeMux) if err != nil { panic(err) } } ``` -------------------------------- ### Go: Handle SSE Connections with Xun Source: https://github.com/yaitoo/xun/blob/main/README.md This Go code snippet demonstrates how to initialize the SSE extension and handle incoming SSE connections within a Xun web application. It sets up a route to join SSE topics, manage client requests, and return errors for invalid requests. Dependencies include the 'sse' extension and the Xun framework. ```go ss := sse.New() app.Get("/topic/{id}", func(ctx *xun.Context)error { id := c.Get("SessionID").(string) s, err := ss.Join(c.Request.Context(), id, c.Response) if err != nil { c.WriteStatus(http.StatusBadRequest) return xun.ErrCancelled } s.Wait() ss.Leave(id) return nil }) ``` -------------------------------- ### Configure GZip and Deflate Compression in Go Source: https://github.com/yaitoo/xun/blob/main/README.md This Go code snippet configures the Xun application to use GZip and Deflate compression for handling 'Accept-Encoding' headers. It initializes the compressor with both GzipCompressor and DeflateCompressor. ```go app := xun.New(WithCompressor(&GzipCompressor{}, &DeflateCompressor{})) ``` -------------------------------- ### Virtual Host Routing with net/http (Go) Source: https://github.com/yaitoo/xun/blob/main/README.md Illustrates how to configure routing in Go's standard net/http package to handle requests for different hostnames that resolve to the same IP address. It defines handlers for specific domains. ```go mux.HandleFunc("GET /", func(w http.ResponseWriter, req *http.Request) {...}) mux.HandleFunc("GET abc.com/", func(w http.ResponseWriter, req *http.Request) {...}) mux.HandleFunc("GET 123.com/", func(w http.ResponseWriter, req *http.Request) {...}) ``` -------------------------------- ### Multiple Viewers based on Accept Header (Bash) Source: https://github.com/yaitoo/xun/blob/main/README.md Demonstrates how to make requests to an HTTP server and receive different responses based on the 'Accept' header, falling back to a default viewer if no specific match is found. This showcases content negotiation. ```bash curl -v http://127.0.0.1 > GET / HTTP/1.1 > Host: 127.0.0.1 > User-Agent: curl/8.7.1 > Accept: */* > * Request completely sent off < HTTP/1.1 200 OK < Date: Thu, 26 Dec 2024 07:46:13 GMT < Content-Length: 19 < Content-Type: text/plain; charset=utf-8 > {"Name":"go-xun"} curl --header "Accept: text/html; \*/\*" http://127.0.0.1 ``` > GET / HTTP/1.1 > Host: 127.0.0.1 > User-Agent: curl/8.7.1 > Accept: text/html; */* > * Request completely sent off < HTTP/1.1 200 OK < Date: Thu, 26 Dec 2024 07:49:47 GMT < Content-Length: 343 < Content-Type: text/html; charset=utf-8 > Xun-Admin
hello go-xun
``` ``` -------------------------------- ### Configure Request Logging with Go Source: https://context7.com/yaitoo/xun/llms.txt Set up request logging for a web application using the yaitoo/xun/ext/reqlog package. This allows logging all incoming requests with a customizable format, including user and visitor identification extracted from cookies. It requires the `github.com/yaitoo/xun` and its extensions `github.com/yaitoo/xun/ext/cookie`, `github.com/yaitoo/xun/ext/reqlog` packages. ```go package main import ( "log" "net/http" "os" "github.com/yaitoo/xun" "github.com/yaitoo/xun/ext/cookie" "github.com/yaitoo/xun/ext/reqlog" ) func main() { app := xun.New() // Setup logger logFile, err := os.OpenFile("./access.log", os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644) if err != nil { panic(err) } defer logFile.Close() logger := log.New(logFile, "", 0) // Visitor ID extractor getVisitorID := func(c *xun.Context) string { value, err := cookie.Get(c, "visitor_id") if err != nil { return "" } return value } // User ID extractor getUserID := func(c *xun.Context) string { secretKey := []byte("secret-key") value, _, err := cookie.GetSigned(c, "session_id", secretKey) if err != nil { return "" } return value } // Enable request logging middleware app.Use(reqlog.New( reqlog.WithLogger(logger), reqlog.WithUser(getUserID), reqlog.WithVisitor(getVisitorID), reqlog.WithFormat(reqlog.Combined), // Combined Log Format (XLF/ELF) )) app.Get("/", func(c *xun.Context) error { return c.View(map[string]string{"page": "home"}) }) app.Get("/api/users", func(c *xun.Context) error { return c.View([]map[string]string{ {"id": "1", "name": "Alice"}, {"id": "2", "name": "Bob"}, }) }) app.Start() http.ListenAndServe(":8080", nil) } ``` -------------------------------- ### Layout and Content Definition (Xun HTML) Source: https://github.com/yaitoo/xun/blob/main/README.md Demonstrates how to create a shared layout in Xun and define content blocks within a specific page that utilize the layout. Uses Go's html/template syntax. ```html Xun-Admin {{ block "content" .}} {{ end }} ``` ```html {{ define "content" }}
hello world
{{ end }} ``` -------------------------------- ### Go Route Handler for Basic View Source: https://github.com/yaitoo/xun/blob/main/README.md A Go route handler that renders a view with a simple string map as data. The page defined at `/{$}` will be rendered. ```go app.Get("/{$", func(c *xun.Context) error { return c.View(map[string]string{ "Name": "go-xun", }) }) ``` -------------------------------- ### Organize Routes with Route Groups in Go Source: https://context7.com/yaitoo/xun/llms.txt This Go code demonstrates how to organize routes with shared prefixes and middleware using route groups in the Xun framework. It sets up API versioning with specific middleware for each version. Dependencies include the 'net/http' package and the 'github.com/yaitoo/xun' library. ```go package main import ( "net/http" "github.com/yaitoo/xun" ) func main() { app := xun.New() // API v1 group v1 := app.Group("/api/v1") v1.Use(func(next xun.HandleFunc) xun.HandleFunc { return func(c *xun.Context) error { c.WriteHeader("X-API-Version", "v1") return next(c) } }) v1.Get("/users", func(c *xun.Context) error { return c.View([]map[string]string{ {"id": "1", "name": "Alice"}, {"id": "2", "name": "Bob"}, }) }) v1.Get("/users/{id}", func(c *xun.Context) error { id := c.Request.PathValue("id") return c.View(map[string]string{"id": id, "name": "User " + id}) }) // API v2 group v2 := app.Group("/api/v2") v2.Use(func(next xun.HandleFunc) xun.HandleFunc { return func(c *xun.Context) error { c.WriteHeader("X-API-Version", "v2") return next(c) } }) v2.Get("/users", func(c *xun.Context) error { return c.View(map[string]any{ "version": "2", "data": []map[string]string{ {"id": "1", "name": "Alice", "email": "alice@example.com"}, }, }) }) app.Start() http.ListenAndServe(":8080", nil) } ``` -------------------------------- ### Serve Real-time Report with Xun Source: https://github.com/yaitoo/xun/blob/main/README.md Serves the real-time HTML analysis report generated by GoAccess through a Xun application endpoint. This Go code snippet defines a route to serve the static HTML file. ```go app.Get("/reports/realtime.html", func(c *xun.Context) error { http.ServeFile(c.Response, c.Request, "./realtime.html") return nil }) ``` -------------------------------- ### Implement HSTS Redirect and Header in Go Source: https://github.com/yaitoo/xun/blob/main/README.md These Go snippets demonstrate how to implement HTTP Strict Transport Security (HSTS) using the 'hsts' package. It shows how to configure HSTS to redirect HTTP requests to HTTPS and how to write the HSTS header for HTTPS requests. ```go app.Use(hsts.Redirect()) ``` ```go app.Use(hsts.WriteHeader()) ``` -------------------------------- ### Apply Middleware for Cross-Cutting Concerns in Go Source: https://context7.com/yaitoo/xun/llms.txt This Go code demonstrates how to create and apply middleware for handling cross-cutting concerns such as logging and authentication within an application using the Xun framework. It shows global middleware application and middleware specific to route groups. Dependencies include the 'log', 'net/http', 'time' packages, and the 'github.com/yaitoo/xun' library. ```go package main import ( "log" "net/http" "time" "github.com/yaitoo/xun" ) func main() { app := xun.New() // Global logging middleware app.Use(func(next xun.HandleFunc) xun.HandleFunc { return func(c *xun.Context) error { start := time.Now() defer func() { duration := time.Since(start) log.Printf("%s %s - %v", c.Request.Method, c.Routing.Pattern, duration) }() return next(c) } }) // Authentication middleware app.Use(func(next xun.HandleFunc) xun.HandleFunc { return func(c *xun.Context) error { token := c.Request.Header.Get("X-Token") if token == "" { c.WriteStatus(http.StatusUnauthorized) return xun.ErrCancelled } c.Set("Token", token) return next(c) } }) // Group with specific middleware admin := app.Group("/admin") admin.Use(func(next xun.HandleFunc) xun.HandleFunc { return func(c *xun.Context) error { token := c.Request.Header.Get("X-Admin-Token") if token != "admin-secret" { c.WriteStatus(http.StatusForbidden) return xun.ErrCancelled } return next(c) } }) admin.Get("/{$}", func(c *xun.Context) error { return c.View(map[string]string{"page": "admin dashboard"}) }) app.Get("/public", func(c *xun.Context) error { return c.View(map[string]string{"page": "public"}) }) app.Start() http.ListenAndServe(":8080", nil) } ``` -------------------------------- ### Go Route for XML Sitemap Rendering Source: https://github.com/yaitoo/xun/blob/main/README.md A Go route handler that renders an XML sitemap using a text template. It specifies the data model and the template file to use for rendering. ```go app.Get("/sitemap.xml", func(c *xun.Context) error { return c.View(Sitemap{ LastMod: time.Now(), }, "text/sitemap.xml") // use `text/sitemap.xml` as current Viewer to render }) ``` -------------------------------- ### Logging Middleware (Go) Source: https://github.com/yaitoo/xun/blob/main/README.md A simple logging middleware for a Go application using the Xun framework. It logs the request pattern and the time taken to process the request, providing insights into request duration. ```go app.Use(func(next xun.HandleFunc) xun.HandleFunc { return func(c *xun.Context) error { n := time.Now() defer func() { duration := time.Since(n) log.Println(c.Routing.Pattern, duration) }() return next(c) } }) ``` -------------------------------- ### Enable CSRF Middleware in Go Source: https://context7.com/yaitoo/xun/llms.txt Protects web applications against Cross-Site Request Forgery (CSRF) attacks by integrating CSRF middleware. This Go code snippet demonstrates how to initialize the Xun application, set a secret key, and apply the CSRF middleware. It also shows how to serve the CSRF JavaScript token handler and configure routes for form submission and updates, with automatic CSRF token validation. ```go package main import ( "net/http" "github.com/yaitoo/xun" "github.com/yaitoo/xun/ext/csrf" ) func main() { app := xun.New() secretKey := []byte("your-secret-key-32-bytes-long!") // Enable CSRF middleware app.Use(csrf.New(secretKey)) // Serve CSRF JavaScript token handler app.Get("/assets/csrf.js", csrf.HandleFunc(secretKey)) // Enable CSRF with JavaScript token for bot prevention app.Use(csrf.New(secretKey, csrf.WithJsToken())) app.Get("/form", func(c *xun.Context) error { return c.View(map[string]string{ "title": "Contact Form", }) }) app.Post("/submit", func(c *xun.Context) error { // CSRF token is automatically validated // If invalid, request returns 418 (I'm a teapot) status return c.View(map[string]string{"status": "success"}) }) app.Put("/update/{id}", func(c *xun.Context) error { id := c.Request.PathValue("id") return c.View(map[string]string{"status": "updated", "id": id}) }) app.Delete("/delete/{id}", func(c *xun.Context) error { id := c.Request.PathValue("id") c.WriteStatus(http.StatusNoContent) return nil }) app.Start() http.ListenAndServe(":8080", nil) } ``` -------------------------------- ### Bash: Build Tailwind CSS Source: https://github.com/yaitoo/xun/blob/main/README.md This bash command initiates the Tailwind CSS build process using the CLI tool. It specifies the input CSS file (`./app/tailwind.css`), the output file (`./app/public/theme.css`), and enables watch mode (`--watch`) to automatically recompile CSS when source files change. This command is used to generate the final CSS that will be included in your HTML. ```bash npx tailwindcss -i ./app/tailwind.css -o ./app/public/theme.css --watch ``` -------------------------------- ### Automatic SSL Certificate Management with Go Source: https://context7.com/yaitoo/xun/llms.txt Configure automatic SSL certificate issuance and renewal using Let's Encrypt with the yaitoo/xun/ext/autotls package. This involves setting up HTTP and HTTPS servers, configuring certificate caching, and specifying the hosts for which certificates should be managed. It requires the `github.com/yaitoo/xun` and `github.com/yaitoo/xun/ext/autotls` packages, as well as `golang.org/x/crypto/acme/autocert`. ```go package main import ( "net/http" "golang.org/x/crypto/acme/autocert" "github.com/yaitoo/xun" "github.com/yaitoo/xun/ext/autotls" ) func main() { mux := http.NewServeMux() app := xun.New(xun.WithMux(mux)) app.Get("/", func(c *xun.Context) error { return c.View(map[string]string{"status": "secure"}) }) app.Start() // HTTP server (handles ACME challenges) httpServer := &http.Server{ Addr: ":http", Handler: mux, } // HTTPS server httpsServer := &http.Server{ Addr: ":https", Handler: mux, } // Configure AutoTLS autotls.New( autotls.WithCache(autocert.DirCache("./certs")), autotls.WithHosts("example.com", "www.example.com"), ).Configure(httpServer, httpsServer) // Start both servers go httpServer.ListenAndServe() httpsServer.ListenAndServeTLS("", "") } ``` -------------------------------- ### Request Logging with Xun Source: https://github.com/yaitoo/xun/blob/main/README.md Configures the request logging middleware for the Xun application. It allows customization of log format and enables integration with a provided logger. Dependencies include the 'reqlog' middleware and standard Go libraries for file operations and logging. ```go func main(){ //.... logger, _ := setupLogger() app.Use(reqlog.New(reqlog.WithLogger(logger), reqlog.WithUser(getUserID), reqlog.WithVisitor(getVisitorID), reqlog.WithFormat(reqlog.Combined)))) //... } func setupLogger() (*log.Logger, error) { logFile, err := os.OpenFile("./access.log", os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644) if err != nil { return nil, err } return log.New(logFile, "", 0), nil } func getVisitorID(c *xun.Context) string { v, err := c.Request.Cookie("visitor_id") // use fingerprintjs to generate visitor id in client's cookie if err != nil { return "" } return v.Value } func getUserID(c *xun.Context) string { v, _, err := cookie.GetSigned(c, "session_id", secretKey) if err != nil { return "" } return v } ``` -------------------------------- ### Basic HTML Page Structure (Xun) Source: https://github.com/yaitoo/xun/blob/main/README.md Defines a basic HTML page structure for a Xun application. This serves as the entry point for a route, typically the index page. ```html Xun-Admin
hello world
``` -------------------------------- ### Apply HTMX Interceptor (Go) Source: https://github.com/yaitoo/xun/blob/main/README.md This Go code snippet shows how to create a new Xun application instance and apply an HTMX interceptor. The `xun.WithInterceptor(htmx.New())` option integrates HTMX functionality into the application's request processing pipeline. ```go app := xun.New(xun.WithInterceptor(htmx.New())) ```