### Basic Templ HTTP Server Setup Source: https://github.com/a-h/templ/blob/main/docs/docs/09-developer-tools/03-live-reload.md A simple Go program that sets up an HTTP server using the Templ templating engine. It defines a basic HTML component and serves it at the root path. This is a foundational example for demonstrating live reload. ```go package main import ( "fmt" "net/http" "github.com/a-h/templ" ) func main() { component := hello("World") http.Handle("/", templ.Handler(component)) fmt.Println("Listening on :8080") http.ListenAndServe(":8080", nil) } ``` -------------------------------- ### Install Templ CLI using Docker Source: https://github.com/a-h/templ/blob/main/docs/docs/02-quick-start/01-installation.md Demonstrates how to pull and use the templ Docker image. It includes instructions for running the generator within a container and a multi-stage Dockerfile example for integrating templ into a build process. ```bash docker pull ghcr.io/a-h/templ:latest ``` ```bash docker run -v `pwd`:/app -w=/app ghcr.io/a-h/templ:latest generate ``` ```dockerfile # Fetch FROM golang:latest AS fetch-stage COPY go.mod go.sum /app WORKDIR /app RUN go mod download # Generate FROM ghcr.io/a-h/templ:latest AS generate-stage COPY --chown=65532:65532 . /app WORKDIR /app RUN ["templ", "generate"] # Build FROM golang:latest AS build-stage COPY --from=generate-stage /app /app WORKDIR /app RUN CGO_ENABLED=0 GOOS=linux go build -o /app/app # Test FROM build-stage AS test-stage RUN go test -v ./... # Deploy FROM gcr.io/distroless/base-debian12 AS deploy-stage WORKDIR / COPY --from=build-stage /app/app /app EXPOSE 8080 USER nonroot:nonroot ENTRYPOINT ["/app"] ``` -------------------------------- ### Install Templ Snapshot Source: https://github.com/a-h/templ/blob/main/README.md Builds and installs a snapshot version of the templ binary. This involves removing any previous installations, clearing LSP logs, updating the version, and then installing the binary to the Go bin path. ```shell # Remove templ from the non-standard ~/bin/templ path # that this command previously used. rm -f ~/bin/templ # Clear LSP logs. rm -f cmd/templ/lspcmd/*.txt # Update version. version set --template="0.3.%d" # Install to $GOPATH/bin or $HOME/go/bin cd cmd/templ && go install ``` -------------------------------- ### Creating and Rendering with Context in Go Source: https://github.com/a-h/templ/blob/main/docs/docs/03-syntax-and-usage/15-context.md Provides a Go code example demonstrating how to create a context with a specific key-value pair using `context.WithValue` and then pass this context to a Templ component's `Render` function. This setup is necessary for the Templ component to access the context value. ```go // Define the context key type. type contextKey string // Create a context key for the theme. var themeContextKey contextKey = "theme" // Create a context variable that inherits from a parent, and sets the value "test". ctx := context.WithValue(context.Background(), themeContextKey, "test") // Pass the ctx variable to the render function. themeName().Render(ctx, w) ``` -------------------------------- ### Go: Setup Templ Counter with Datastar SSE Source: https://github.com/a-h/templ/blob/main/docs/docs/05-server-side-rendering/04-datastar.md Sets up HTTP routes for a counter example using Datastar SSE. It handles global counter increments and per-user counter increments, persisting user state in sessions. It retrieves user session data and uses `atomic.Uint32` for global state management. ```go package site import ( "net/http" "sync/atomic" "github.com/Jeffail/gabs/v2" "github.com/go-chi/chi/v5" "github.com/gorilla/sessions" "github.com/starfederation/datastar-go/datastar" ) func setupExamplesTemplCounter(examplesRouter chi.Router, sessionSignals sessions.Store) error { var globalCounter atomic.Uint32 const ( sessionKey = "templ_counter" countKey = "count" ) userVal := func(r *http.Request) (uint32, *sessions.Session, error) { sess, err := sessionSignals.Get(r, sessionKey) if err != nil { return 0, nil, err } val, ok := sess.Values[countKey].(uint32) if !ok { val = 0 } return val, sess, nil } examplesRouter.Get("/templ_counter/data", func(w http.ResponseWriter, r *http.Request) { userVal, _, err := userVal(r) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) } signals := TemplCounterSignals{ Global: globalCounter.Load(), User: userVal, } c := templCounterExampleInitialContents(signals) datastar.NewSSE(w, r).MergeFragmentTempl(c) }) updateGlobal := func(signals *gabs.Container) { signals.Set(globalCounter.Add(1), "global") } examplesRouter.Route("/templ_counter/increment", func(incrementRouter chi.Router) { incrementRouter.Post("/global", func(w http.ResponseWriter, r *http.Request) { update := gabs.New() updateGlobal(update) datastar.NewSSE(w, r).MarshalAndMergeSignals(update) }) incrementRouter.Post("/user", func(w http.ResponseWriter, r *http.Request) { val, sess, err := userVal(r) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) } val++ sess.Values[countKey] = val if err := sess.Save(r, w); err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) } update := gabs.New() updateGlobal(update) update.Set(val, "user") datastar.NewSSE(w, r).MarshalAndMergeSignals(update) }) }) return nil } ``` -------------------------------- ### Troubleshooting Templ Binary Installation Source: https://github.com/a-h/templ/blob/main/docs/docs/09-developer-tools/02-ide-support.md Verifies that the 'go', 'gopls', and 'templ' binaries are installed and accessible in the system's PATH. ```bash which go gopls templ ``` -------------------------------- ### Install Templ CLI using Go Source: https://github.com/a-h/templ/blob/main/docs/docs/02-quick-start/01-installation.md Installs the templ CLI tool globally or as a local project tool using the Go build system. Requires Go 1.24 or greater. The global installation adds 'templ' to your PATH, while the tool installation allows running via 'go tool templ'. ```bash go install github.com/a-h/templ/cmd/templ@latest ``` ```bash go get -tool github.com/a-h/templ/cmd/templ@latest ``` -------------------------------- ### Restart Server Command Example Source: https://github.com/a-h/templ/blob/main/docs/docs/09-developer-tools/03-live-reload.md An example of how to configure the `--cmd` argument for `templ generate --watch`. This specific command tells Templ to rebuild and run the Go application when Go files change, which is crucial for server-side updates during development. ```bash templ generate --watch --cmd="go run ." ``` -------------------------------- ### Install Project Dependencies Source: https://github.com/a-h/templ/blob/main/benchmarks/react/README.md Run this command in your terminal to install all necessary project dependencies using npm. ```bash npm i ``` -------------------------------- ### Configure Application Entrypoint Source: https://github.com/a-h/templ/blob/main/docs/docs/07-project-structure/01-project-structure.md The main entrypoint initializes dependencies, configures the HTTP server, and starts the application listener. ```go func main() { log := slog.New(slog.NewJSONHandler(os.Stderr)) s, err := db.NewCountStore(os.Getenv("TABLE_NAME"), os.Getenv("AWS_REGION")) if err != nil { log.Error("failed to create store", slog.Any("error", err)) os.Exit(1) } cs := services.NewCount(log, s) h := handlers.New(log, cs) var secureFlag = true if os.Getenv("SECURE_FLAG") == "false" { secureFlag = false } sh := session.NewMiddleware(h, session.WithSecure(secureFlag)) server := &http.Server{ Addr: "localhost:9000", Handler: sh, ReadTimeout: time.Second * 10, WriteTimeout: time.Second * 10, } fmt.Printf("Listening on %v\n", server.Addr) server.ListenAndServe() } ``` -------------------------------- ### Initialize Go Project for Templ Source: https://github.com/a-h/templ/blob/main/docs/docs/02-quick-start/02-creating-a-simple-templ-component.md Commands to create a new directory, initialize a Go module, and install the templ dependency. ```bash mkdir hello-world cd hello-world go mod init github.com/a-h/templ-examples/hello-world go get github.com/a-h/templ ``` -------------------------------- ### Run the Project Source: https://github.com/a-h/templ/blob/main/benchmarks/react/README.md After building the project, use this command to start the application. Ensure the build step is completed first. ```sh npm start ``` -------------------------------- ### Install Templ CLI using Nix Source: https://github.com/a-h/templ/blob/main/docs/docs/02-quick-start/01-installation.md Provides commands to run the templ CLI using Nix, either directly or by entering a development shell. It also shows how to integrate templ into a Nix flake for project-specific use or system-wide installation. ```bash nix run github:a-h/templ ``` ```bash nix develop github:a-h/templ ``` ```nix { inputs = { ... templ.url = "github:a-h/templ"; ... }; outputs = inputs@{ ... }: # For NixOS configuration: { # Add the overlay, nixpkgs.overlays = [ inputs.templ.overlays.default ]; # and install the package environment.systemPackages = with pkgs; [ templ ]; }; # For a flake project: let forAllSystems = f: nixpkgs.lib.genAttrs allSystems (system: f { inherit system; pkgs = import nixpkgs { inherit system; }; }); templ = system: inputs.templ.packages.${system}.templ; in { packages = forAllSystems ({ pkgs, system }: { myNewPackage = pkgs.buildGoModule { ... preBuild = "''${templ system}/bin/templ generate''; }; }); devShell = forAllSystems ({ pkgs, system }: pkgs.mkShell { buildInputs = with pkgs; [ go (templ system) ]; }); } } ``` -------------------------------- ### Run Go application Source: https://github.com/a-h/templ/blob/main/examples/integration-react/README.md Starts the Go application from the current directory. ```go go run . ``` -------------------------------- ### Start Gopls Process Source: https://github.com/a-h/templ/wiki/coverage.html Starts the gopls process and establishes a JSON-RPC 2.0 connection over stdin/stdout. Returns the gopls location and a ReadWriteCloser for communication. ```go // NewGopls starts gopls and opens up a jsonrpc2 connection to it. func NewGopls(ctx context.Context, log *slog.Logger, opts Options) (location string, rwc io.ReadWriteCloser, err error) { location, err = FindGopls() if err != nil { return "", nil, err } cmd := exec.Command(location, opts.AsArguments()...) rwc, err = newProcessReadWriteCloser(log, cmd) return location, rwc, err } ``` -------------------------------- ### Start Templ Proxy Server Source: https://github.com/a-h/templ/wiki/coverage.html Starts a proxy server for Templ development. It can handle HTTP or HTTPS and optionally opens the default browser to the proxied URL. It includes retry logic for the browser opening and TLS configuration. ```go func (cmd *Generate) startProxy() (p *proxy.Handler, err error) { var target *url.URL target, err = url.Parse(cmd.Args.Proxy) if err != nil { return nil, FatalError{Err: fmt.Errorf("failed to parse proxy URL: %w", err)} } scheme := "http" if cmd.Args.ProxyTLSCrt != "" && cmd.Args.ProxyTLSKey != "" { scheme = "https" } p = proxy.New(cmd.Log, scheme, cmd.Args.ProxyBind, cmd.Args.ProxyPort, target) go func() { cmd.Log.Info("Proxying", slog.String("from", p.URL), slog.String("to", p.Target.String())) server := &http.Server{ Addr: fmt.Sprintf("%s:%d", cmd.Args.ProxyBind, cmd.Args.ProxyPort), Handler: p, } // Configure TLS if certificates are provided. if cmd.Args.ProxyTLSCrt != "" && cmd.Args.ProxyTLSKey != "" { cert, err := tls.LoadX509KeyPair(cmd.Args.ProxyTLSCrt, cmd.Args.ProxyTLSKey) if err != nil { cmd.Log.Error("Failed to load TLS certificates", slog.Any("error", err)) return } server.TLSConfig = &tls.Config{Certificates: []tls.Certificate{cert}} if err = server.ListenAndServeTLS(cmd.Args.ProxyTLSCrt, cmd.Args.ProxyTLSKey); err != nil { cmd.Log.Error("Proxy failed", slog.Any("error", err)) } return } if err := server.ListenAndServe(); err != nil { cmd.Log.Error("Proxy failed", slog.Any("error", err)) } }() if !cmd.Args.OpenBrowser { cmd.Log.Debug("Not opening browser") return p, nil } go func() { cmd.Log.Debug("Waiting for proxy to be ready", slog.String("url", p.URL)) backoff := backoff.NewExponentialBackOff() backoff.InitialInterval = time.Second var client http.Client client.Timeout = 1 * time.Second // Configure TLS with CA pool for self-signed certificates on localhost. if cmd.Args.ProxyTLSCrt != "" && cmd.Args.ProxyTLSKey != "" { client.Transport = cmd.createTLSTransport() } for { if resp, err := client.Get(p.URL); err == nil { if resp.StatusCode != http.StatusBadGateway { break } } d := backoff.NextBackOff() cmd.Log.Debug("Proxy not ready, retrying", slog.String("url", p.URL), slog.Any("backoff", d)) time.Sleep(d) } if err := browser.OpenURL(p.URL); err != nil { cmd.Log.Error("Failed to open browser", slog.Any("error", err)) } }() return p, nil } ``` -------------------------------- ### Run Templ Docs Development Server Source: https://github.com/a-h/templ/blob/main/README.md Starts the development server for the templ documentation website. This command should be run from the 'docs' directory. ```shell npm run start ``` -------------------------------- ### Get Go Tool Information Source: https://github.com/a-h/templ/wiki/coverage.html Retrieves the Go version and architecture. This is a foundational step for environment checks. ```go func getGoInfo() (d ToolInfo) { d.Level = slog.LevelError var err error d.Location, err = exec.LookPath("go") if err != nil { d.Message = fmt.Sprintf("failed to find go: %v", err) return } cmd := exec.Command(d.Location, "version") v, err := cmd.Output() if err != nil { d.Message = fmt.Sprintf("failed to get go version: %v", err) return } d.Version = strings.TrimSpace(string(v)) d.Level = slog.LevelInfo return } ``` -------------------------------- ### Initialize and Run Go Web Server Source: https://github.com/a-h/templ/blob/main/docs/docs/03-syntax-and-usage/11-forms.md Demonstrates the entrypoint pattern for a Go web server, including initializing a database connection pool, setting up HTTP routing with ServeMux, and serving static files. The server is executed within a run function to handle errors gracefully. ```go func main() { log := slog.Default() ctx := context.Background() if err := run(ctx, log); err != nil { log.Error("Failed to run server", slog.Any("error", err)) os.Exit(1) } } func run(ctx context.Context, log *slog.Logger) error { pool, err := sqlitex.NewPool(dbURI, sqlitex.PoolOptions{}) if err != nil { return err } store := sqlitekv.New(pool) if err := store.Init(ctx); err != nil { return err } db := db.New(store) mux := http.NewServeMux() mux.Handle("/", home.NewHandler()) mux.Handle("/contacts", contacts.NewHandler(log, db)) mux.Handle("/static/", http.StripPrefix("/static/", http.FileServer(http.Dir("static")))) log.Info("Starting server", slog.String("address", addr)) return http.ListenAndServe(addr, mux) } ``` -------------------------------- ### Display Fixed Data with templ.Handler in Go Source: https://github.com/a-h/templ/blob/main/docs/docs/05-server-side-rendering/01-creating-an-http-server-with-templ.md This example demonstrates serving pages with fixed data, such as a timestamp from when the server started. It utilizes templ.Handler with optional parameters like templ.WithStatus to control the HTTP response. The component receives data as parameters, promoting reusability. ```templ package main import "time" templ timeComponent(d time.Time) {
{ d.String() }
} templ notFoundComponent() {
404 - Not found
} ``` ```go package main import ( "net/http" "time" "github.com/a-h/templ" ) func main() { http.Handle("/", templ.Handler(timeComponent(time.Now()))) http.Handle("/404", templ.Handler(notFoundComponent(), templ.WithStatus(http.StatusNotFound))) http.ListenAndServe(":8080", nil) } ``` -------------------------------- ### Serve Application with Go Source: https://github.com/a-h/templ/blob/main/docs/docs/03-syntax-and-usage/20-using-react-with-templ.md Implement a Go web server to serve the templ-generated HTML and the static JavaScript bundle. ```go package main import ( "fmt" "log" "net/http" "github.com/a-h/templ" ) func main() { mux := http.NewServeMux() // Serve the templ page. mux.Handle("/", templ.Handler(page())) // Serve static content. mux.Handle("/static/", http.StripPrefix("/static/", http.FileServer(http.Dir("static")))) // Start the server. fmt.Println("listening on localhost:8080") if err := http.ListenAndServe("localhost:8080", mux); err != nil { log.Printf("error listening: %v", err) } } ``` -------------------------------- ### Install TypeScript Dependencies Source: https://github.com/a-h/templ/blob/main/examples/typescript/README.md Installs the necessary Node.js dependencies for the TypeScript project. This command should be run in the 'ts' directory. ```bash npm install ``` -------------------------------- ### Create a Web Server with Templ in Go Source: https://github.com/a-h/templ/blob/main/docs/docs/02-quick-start/03-running-your-first-templ-application.md This Go code snippet sets up a basic HTTP server using the net/http package. It integrates a Templ component by using `templ.Handler` to serve HTML content. The server listens on port 3000 and responds to requests with the generated HTML. ```Go package main import ( "fmt" "net/http" "github.com/a-h/templ" ) func main() { component := hello("John") http.Handle("/", templ.Handler(component)) fmt.Println("Listening on :3000") http.ListenAndServe(":3000", nil) } ``` -------------------------------- ### Parse If Statement in Templ Source: https://github.com/a-h/templ/wiki/coverage.html Parses an 'if' statement from content, returning start and end positions. Requires content to start with 'if'. ```Go func If(content string) (start, end int, err error) { if !strings.HasPrefix(content, "if") { return 0, 0, ErrExpectedNodeNotFound } return extract(content, func(body []ast.Stmt) (start, end int, err error) { stmt, ok := body[0].(*ast.IfStmt) if !ok { return 0, 0, ErrExpectedNodeNotFound } start = int(stmt.If) + len("if") end = latestEnd(start, stmt.Init, stmt.Cond) return start, end, nil }) } ``` -------------------------------- ### Render Templ Component in Go Source: https://github.com/a-h/templ/blob/main/docs/docs/02-quick-start/02-creating-a-simple-templ-component.md A main.go file demonstrating how to instantiate a generated templ component and render it to standard output. ```go package main import ( "context" "os" ) func main() { component := hello("John") component.Render(context.Background(), os.Stdout) } ``` -------------------------------- ### Create New Document Source: https://github.com/a-h/templ/wiki/coverage.html Initializes a new Document with the given content, splitting it into lines. ```go func NewDocument(log *slog.Logger, s string) *Document { return &Document{ Log: log, Lines: strings.Split(s, "\n"), } } ``` -------------------------------- ### Templignore Fmt Example Source: https://github.com/a-h/templ/blob/main/docs/docs/09-developer-tools/01-cli.md An example of a `.templignore_fmt` file used to specify glob patterns for files and directories that should be ignored by the `templ fmt` command. ```plaintext # Ignore generated test fixtures. generator/test-* ``` -------------------------------- ### Initialize TypeScript Project with NPM Source: https://github.com/a-h/templ/blob/main/docs/docs/03-syntax-and-usage/13-script-templates.md Commands to create a new directory, initialize an NPM project, and install necessary development dependencies including TypeScript and esbuild. ```bash mkdir ts cd ts npm init npm install --save-dev typescript esbuild ``` -------------------------------- ### Parse For Statement in Templ Source: https://github.com/a-h/templ/wiki/coverage.html Parses a 'for' statement (either standard or range-based) from content, returning start and end positions. Requires content to start with 'for'. ```Go func For(content string) (start, end int, err error) { if !strings.HasPrefix(content, "for") { return 0, 0, ErrExpectedNodeNotFound } return extract(content, func(body []ast.Stmt) (start, end int, err error) { stmt := body[0] switch stmt := stmt.(type) { case *ast.ForStmt: start = int(stmt.For) + len("for") end = latestEnd(start, stmt.Init, stmt.Cond, stmt.Post) return start, end, nil case *ast.RangeStmt: start = int(stmt.For) + len("for") end = latestEnd(start, stmt.Key, stmt.Value, stmt.X) return start, end, nil } return 0, 0, ErrExpectedNodeNotFound }) } ``` -------------------------------- ### Emacs Templ Mode Installation Source: https://github.com/a-h/templ/blob/main/docs/docs/09-developer-tools/02-ide-support.md Installs the templ-ts-mode for Emacs via MELPA, providing syntax highlighting and indentation for Templ files. Requires the tree-sitter parser for Templ. ```emacs-lisp (use-package templ-ts-mode :ensure t) ``` -------------------------------- ### Initialize LSP Client Connection in Go Source: https://github.com/a-h/templ/wiki/coverage.html Sets up a new Language Server Protocol client connection. It initializes a JSON-RPC connection and registers handlers for client methods. ```go // NewClient returns the context in which Client is embedded, jsonrpc2.Conn, and the Server. func NewClient(ctx context.Context, client Client, stream jsonrpc2.Stream, logger *slog.Logger) (context.Context, jsonrpc2.Conn, Server) { ctx = WithClient(ctx, client) conn := jsonrpc2.NewConn(stream) conn.Go(ctx, Handlers( ClientHandler(logger, client, jsonrpc2.MethodNotFoundHandler), ), ) server := ServerDispatcher(conn, logger.With(slog.String("name", "server"))) return ctx, conn, server } ``` -------------------------------- ### Install Tailwind CSS CLI Source: https://github.com/a-h/templ/blob/main/docs/docs/09-developer-tools/04-live-reload-with-other-tools.md Installs the Tailwind CSS and its CLI package using npm. These are required for processing CSS with Tailwind directives and generating a CSS bundle. ```bash npm install tailwindcss @tailwindcss/cli ``` -------------------------------- ### Parse Switch Statement in Templ Source: https://github.com/a-h/templ/wiki/coverage.html Parses a 'switch' statement (either standard or type-based) from content, returning start and end positions. Requires content to start with 'switch'. ```Go func Switch(content string) (start, end int, err error) { if !strings.HasPrefix(content, "switch") { return 0, 0, ErrExpectedNodeNotFound } return extract(content, func(body []ast.Stmt) (start, end int, err error) { stmt := body[0] switch stmt := stmt.(type) { case *ast.SwitchStmt: start = int(stmt.Switch) + len("switch") end = latestEnd(start, stmt.Init, stmt.Tag) return start, end, nil case *ast.TypeSwitchStmt: start = int(stmt.Switch) + len("switch") end = latestEnd(start, stmt.Init, stmt.Assign) return start, end, nil } return 0, 0, ErrExpectedNodeNotFound }) } ``` -------------------------------- ### Vim Plugin Installation for Templ Source: https://github.com/a-h/templ/blob/main/docs/docs/09-developer-tools/02-ide-support.md Installs necessary plugins for Templ language support in Vim using vim-plug. Requires Vim 8+ and includes LSP and autocomplete configurations. ```vim Plug 'prabirshrestha/vim-lsp' Plug 'prabirshrestha/asyncomplete.vim' Plug 'prabirshrestha/asyncomplete-lsp.vim' ``` -------------------------------- ### Build Project for Production Source: https://github.com/a-h/templ/blob/main/benchmarks/react/README.md Execute this command to build the project for production deployment. This typically optimizes assets and code. ```sh npm run build ``` -------------------------------- ### Start RPC Handler Goroutine Source: https://github.com/a-h/templ/wiki/coverage.html Starts a new goroutine that runs the `run` method, which is responsible for processing incoming messages from the stream. This method is typically called once per connection. ```go func (c *conn) Go(ctx context.Context, handler Handler) { go c.run(ctx, handler) } ``` -------------------------------- ### Go Pretend Blog Posts Data Source: https://github.com/a-h/templ/blob/main/docs/docs/06-static-rendering/02-blog-example.md Initializes a slice of Post structs with sample blog post data. This data is used for demonstration purposes in the static blog generation. ```go posts := []Post{ { Date: time.Date(2023, time.January, 1, 0, 0, 0, 0, time.UTC), Title: "Happy New Year!", Content: `New Year is a widely celebrated occasion in the United Kingdom, marking the end of one year and the beginning of another. Top New Year Activities in the UK include: * Attending a Hogmanay celebration in Scotland * Taking part in a local First-Foot tradition in Scotland and Northern England * Setting personal resolutions and goals for the upcoming year * Going for a New Year's Day walk to enjoy the fresh start * Visiting a local pub for a celebratory toast and some cheer `, }, { Date: time.Date(2023, time.May, 1, 0, 0, 0, 0, time.UTC), Title: "May Day", Content: `May Day is an ancient spring festival celebrated on the first of May in the United Kingdom, embracing the arrival of warmer weather and the renewal of life. Top May Day Activities in the UK: * Dancing around the Maypole, a traditional folk activity * Attending local village fetes and fairs * Watching or participating in Morris dancing performances * Enjoying the public holiday known as Early May Bank Holiday `, }, } ``` -------------------------------- ### ListenAndServe Starts JSON-RPC Server Source: https://github.com/a-h/templ/wiki/coverage.html Starts a JSON-RPC 2.0 server on the specified network address. It listens for incoming connections and serves them using the provided StreamServer. Exits after idleTimeout if no clients are active, otherwise exits on error. ```go // ListenAndServe starts an jsonrpc2 server on the given address. // // If idleTimeout is non-zero, ListenAndServe exits after there are no clients for // this duration, otherwise it exits only on error. func ListenAndServe(ctx context.Context, network, addr string, server StreamServer, idleTimeout time.Duration) error { ln, err := net.Listen(network, addr) if err != nil { return fmt.Errorf("failed to listen %s:%s: %w", network, addr, err) } defer func() { _ = ln.Close() }() if network == "unix" { defer func() { _ = os.Remove(addr) }() } return Serve(ctx, ln, server, idleTimeout) } ``` -------------------------------- ### NewServer Source: https://github.com/a-h/templ/wiki/coverage.html Initializes a new language server instance, setting up the connection and client dispatcher. ```APIDOC ## NewServer ### Description Initializes a new language server, returning the context, JSON-RPC connection, and client interface. ### Parameters - **ctx** (context.Context) - The context for the server. - **server** (Server) - The server implementation. - **stream** (jsonrpc2.Stream) - The communication stream. - **logger** (*slog.Logger) - The logger instance. ### Returns - context.Context: The updated context with the client. - jsonrpc2.Conn: The JSON-RPC connection. - Client: The client interface. ``` -------------------------------- ### Initialize LSP Server Connection in Go Source: https://github.com/a-h/templ/wiki/coverage.html Sets up a new Language Server Protocol server connection. It initializes a JSON-RPC connection and registers handlers for server methods. ```go // SPDX-FileCopyrightText: 2019 The Go Language Server Authors // SPDX-License-Identifier: BSD-3-Clause package protocol import ( "context" "log/slog" "github.com/a-h/templ/lsp/jsonrpc2" ) // NewServer returns the context in which client is embedded, jsonrpc2.Conn, and the Client. func NewServer(ctx context.Context, server Server, stream jsonrpc2.Stream, logger *slog.Logger) (context.Context, jsonrpc2.Conn, Client) { conn := jsonrpc2.NewConn(stream) cliint := ClientDispatcher(conn, logger.With(slog.String("name", "client"))) ctx = WithClient(ctx, cliint) conn.Go(ctx, Handlers( ServerHandler(logger, server, jsonrpc2.MethodNotFoundHandler), ), ) return ctx, conn, cliint } ``` -------------------------------- ### Start Templ Proxy in Watch Mode Source: https://github.com/a-h/templ/blob/main/docs/docs/09-developer-tools/04-live-reload-with-other-tools.md Starts the templ proxy server in watch mode, which automatically refreshes the browser when .templ files change. It's configured not to open the browser automatically, assuming another process will handle that. ```bash templ generate --watch --proxy="http://localhost:8080" --open-browser=false ``` -------------------------------- ### Templ Info Command Implementation Source: https://github.com/a-h/templ/wiki/coverage.html Parses arguments for the 'info' command, sets up logging, and runs the info command logic. Handles JSON output and verbosity flags. ```Go const infoUsageText = `usage: templ info [...] Displays information about the templ environment. Args: -json Output information in JSON format to stdout. (default false) -v Set log verbosity level to "debug". (default "info") -log-level Set log verbosity level. (default "info", options: "debug", "info", "warn", "error") -help Print help and exit. ` func infoCmd(stdout, stderr io.Writer, args []string) (code int) { cmd := flag.NewFlagSet("diagnose", flag.ExitOnError) jsonFlag := cmd.Bool("json", false, "") verboseFlag := cmd.Bool("v", false, "") logLevelFlag := cmd.String("log-level", "info", "") helpFlag := cmd.Bool("help", false, "") err := cmd.Parse(args) if err != nil { _, _ = fmt.Fprint(stderr, infoUsageText) return 64 // EX_USAGE } if *helpFlag { _, _ = fmt.Fprint(stdout, infoUsageText) return } log := sloghandler.NewLogger(*logLevelFlag, *verboseFlag, stderr) ctx, cancel := context.WithCancel(context.Background()) signalChan := make(chan os.Signal, 1) signal.Notify(signalChan, os.Interrupt) go func() { <-signalChan _, _ = fmt.Fprintln(stderr, "Stopping...") cancel() }() err = infocmd.Run(ctx, log, stdout, infocmd.Arguments{ JSON: *jsonFlag, }) if err != nil { _, _ = color.New(color.FgRed).Fprint(stderr, "(✗) ") _, _ = fmt.Fprintln(stderr, "Command failed: "+err.Error()) return 1 } return 0 } ``` -------------------------------- ### Project initialization and generation commands Source: https://github.com/a-h/templ/blob/main/docs/docs/06-static-rendering/01-generating-static-html-files-with-templ.md Shell commands to initialize a Go module and generate Go code from templ files. ```bash mkdir static-generator cd static-generator go mod init github.com/a-h/templ-examples/static-generator templ generate go run *.go ``` -------------------------------- ### strings.Builder Utility Source: https://github.com/a-h/templ/wiki/coverage.html A simple function to get a new strings.Builder. ```APIDOC ## GetBuilder ### Description Returns a new, zero-valued strings.Builder. ### Signature func GetBuilder() (sb strings.Builder) ### Returns - **sb** (strings.Builder) - A new strings.Builder instance. ``` -------------------------------- ### Go HTTP Server for State Management Source: https://github.com/a-h/templ/blob/main/docs/docs/05-server-side-rendering/02-example-counter-application.md Implements a Go HTTP server that handles both GET and POST requests. The GET handler renders the Templ UI, while the POST handler parses form data to update the global counter state based on button clicks. ```go package main import ( "fmt" "log" "net/http" ) type GlobalState struct { Count int } var global GlobalState func getHandler(w http.ResponseWriter, r *http.Request) { component := page(global.Count, 0) component.Render(r.Context(), w) } func postHandler(w http.ResponseWriter, r *http.Request) { // Update state. r.ParseForm() // Check to see if the global button was pressed. if r.Form.Has("global") { global.Count++ } //TODO: Update session. // Display the form. getHandler(w, r) } func main() { // Handle POST and GET requests. http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { if r.Method == http.MethodPost { postHandler(w, r) return } getHandler(w, r) }) // Start the server. fmt.Println("listening on http://localhost:8000") if err := http.ListenAndServe("localhost:8000", nil); err != nil { log.Printf("error listening: %v", err) } } ``` -------------------------------- ### Benchmark Results Source: https://github.com/a-h/templ/blob/main/benchmarks/templ/README.md Sample output from running Go benchmarks, showing operations per second (ops/op), nanoseconds per operation (ns/op), bytes allocated per operation (B/op), and allocations per operation (allocs/op) for different templating methods. ```text go test -bench . goos: darwin goarch: arm64 pkg: github.com/a-h/templ/benchmarks/templ BenchmarkTempl-10 3291883 369.1 ns/op 536 B/op 6 allocs/op BenchmarkGoTemplate-10 481052 2475 ns/op 1400 B/op 38 allocs/op BenchmarkIOWriteString-10 20353198 56.64 ns/op 320 B/op 1 allocs/op PASS ok github.com/a-h/templ/benchmarks/templ 4.650s ``` -------------------------------- ### Get Line Lengths Source: https://github.com/a-h/templ/wiki/coverage.html Calculates and returns the length of each line in the document. ```go func (d *Document) LineLengths() (lens []int) { lens = make([]int, len(d.Lines)) for i, l := range d.Lines { lens[i] = len(l) } return } ``` -------------------------------- ### GET /go Source: https://github.com/a-h/templ/wiki/coverage.html Retrieves the Go source code for a given URI. ```APIDOC ## GET /go ### Description Retrieves the Go source code content associated with a specific URI. ### Method GET ### Endpoint /go ### Parameters #### Query Parameters - **uri** (string) - Required - The URI of the Go source code to retrieve. ### Response #### Success Response (200) - **string** (string) - The Go source code content. #### Error Response - **404 Not Found**: If the specified URI is not found. ``` -------------------------------- ### NewClient Source: https://github.com/a-h/templ/wiki/coverage.html Initializes a new language client instance, setting up the connection and server dispatcher. ```APIDOC ## NewClient ### Description Initializes a new language client, returning the context, JSON-RPC connection, and server interface. ### Parameters - **ctx** (context.Context) - The context for the client. - **client** (Client) - The client implementation. - **stream** (jsonrpc2.Stream) - The communication stream. - **logger** (*slog.Logger) - The logger instance. ### Returns - context.Context: The updated context with the client. - jsonrpc2.Conn: The JSON-RPC connection. - Server: The server interface. ``` -------------------------------- ### GET /sourcemap Source: https://github.com/a-h/templ/wiki/coverage.html Retrieves the source map information for a given URI. ```APIDOC ## GET /sourcemap ### Description Retrieves the source map information, specifically the mapping of source lines to target lines, for a given URI. ### Method GET ### Endpoint /sourcemap ### Parameters #### Query Parameters - **uri** (string) - Required - The URI for which to retrieve source map information. ### Response #### Success Response (200) - **SourceLinesToTarget** (object) - An object containing the mapping of source lines to target lines. #### Error Response - **404 Not Found**: If the specified URI is not found. ``` -------------------------------- ### New String Loader Initialization Source: https://github.com/a-h/templ/wiki/coverage.html Initializes a new StringLoader. It sets up the cache and resolves the development mode watch root path if provided. Handles errors during symlink evaluation. ```go func NewStringLoader(devModeWatchRootPath string) (sl *StringLoader) { sl = &StringLoader{ cache: make(map[string]watchState), } if devModeWatchRootPath == "" { return sl } resolvedRoot, err := filepath.EvalSymlinks(devModeWatchRootPath) if err != nil { sl.watchModeRootErr = fmt.Errorf("templ: failed to eval symlinks for watch mode root %q: %w", devModeWatchRootPath, err) return sl } sl.watchModeRoot = resolvedRoot return sl } ``` -------------------------------- ### GET /templ Source: https://github.com/a-h/templ/wiki/coverage.html Retrieves the templated string content for a given URI. ```APIDOC ## GET /templ ### Description Retrieves the raw templated string content associated with a specific URI. ### Method GET ### Endpoint /templ ### Parameters #### Query Parameters - **uri** (string) - Required - The URI of the templated content to retrieve. ### Response #### Success Response (200) - **string** (string) - The templated string content. #### Error Response - **404 Not Found**: If the specified URI is not found. ``` -------------------------------- ### Initialize OnceHandle in Go Source: https://github.com/a-h/templ/wiki/coverage.html Demonstrates how to initialize a OnceHandle for ensuring a piece of code runs only once. This is useful for global setup or initialization tasks. ```Go import "github.com/a-h/templ" import templruntime "github.com/a-h/templ/runtime" var helloHandle = templ.NewOnceHandle() ``` -------------------------------- ### Initialize Templ Server Source: https://github.com/a-h/templ/wiki/coverage.html Constructs a new Server instance for handling templ file requests. It initializes various caches and sources required for the translation process. ```go func NewServer(log *slog.Logger, target lsp.Server, cache *SourceMapCache, diagnosticCache *DiagnosticCache, noPreload bool, formatConf format.Config) (s *Server) { return &Server{ Log: log, Target: target, SourceMapCache: cache, DiagnosticCache: diagnosticCache, TemplSource: newDocumentContents(log), GoSource: make(map[string]string), NoPreload: noPreload, formatConf: formatConf, } } ``` -------------------------------- ### Peek Input Prefixes Source: https://github.com/a-h/templ/wiki/coverage.html Checks if the input stream starts with any of the provided prefixes. ```Go func peekPrefix(pi *parse.Input, prefixes ...string) bool { for _, prefix := range prefixes { pp, ok := pi.Peek(len(prefix)) if !ok { continue } if prefix == pp { return true } } return false } ``` -------------------------------- ### Buffer Management Source: https://github.com/a-h/templ/wiki/coverage.html Functions for getting, releasing, and managing buffers used for writing. ```APIDOC ## GetBuffer ### Description Retrieves a buffer from the pool or creates a new one if the writer is not already a buffer. ### Signature func GetBuffer(w io.Writer) (b *Buffer, existing bool) ### Parameters - **w** (io.Writer) - The writer to associate with the buffer. ### Returns - **b** (*Buffer) - The buffer instance. - **existing** (bool) - True if the provided writer was already a Buffer. ## ReleaseBuffer ### Description Flushes the buffer and returns it to the pool. ### Signature func ReleaseBuffer(w io.Writer) (err error) ### Parameters - **w** (io.Writer) - The buffer to release. ### Returns - **err** (error) - An error if flushing fails. ``` -------------------------------- ### Generate Basic HTML Structure with Templ Source: https://github.com/a-h/templ/wiki/coverage.html This snippet demonstrates how to generate a complete HTML document, including head, body, styles, and scripts, using the templ.Raw and templruntime.WriteString functions. It also shows how to handle context errors and buffer management. ```go func Example() templ.Component { return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil { return templ_7745c5c3_CtxErr } templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) if !templ_7745c5c3_IsBuffer { defer func() { templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) if templ_7745c5c3_Err == nil { templ_7745c5c3_Err = templ_7745c5c3_BufErr } }() } ctx = templ.InitializeContext(ctx) templ_7745c5c3_Var1 := templ.GetChildren(ctx) if templ_7745c5c3_Var1 == nil { templ_7745c5c3_Var1 = templ.NopComponent } ctx = templ.ClearChildren(ctx) templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, "

Hello

") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } templ_7745c5c3_Err = templ.Raw("
World
").Render(ctx, templ_7745c5c3_Buffer) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, "") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } return nil }) } var _ = templruntime.GeneratedTemplate ``` -------------------------------- ### Go CSRF Protection Middleware Setup Source: https://github.com/a-h/templ/blob/main/docs/docs/03-syntax-and-usage/11-forms.md Demonstrates how to set up CSRF protection middleware using the gorilla/csrf package in Go. This includes generating a key and configuring trusted origins and the field name for the CSRF token. ```Go csrfKey := mustGenerateCSRFKey() csrfMiddleware := csrf.Protect(csrfKey, csrf.TrustedOrigins([]string{"localhost:8080"}), csrf.FieldName("_csrf")) ``` -------------------------------- ### Get All Document URIs Source: https://github.com/a-h/templ/wiki/coverage.html Returns a slice of all document URIs currently managed. ```go func (dc *DocumentContents) URIs() (uris []string) { dc.m.Lock() defer dc.m.Unlock() uris = make([]string, len(dc.uriToContents)) var i int for k := range dc.uriToContents { uris[i] = k i++ } return uris } ``` -------------------------------- ### Creating and Rendering a View Model in templ Source: https://github.com/a-h/templ/blob/main/docs/docs/04-core-concepts/04-view-models.md Demonstrates how to transform domain data into a specific View Model struct and pass it to a templ component. This pattern simplifies template logic and improves testability by decoupling the UI from the underlying service layer. ```go package invitesget type Handler struct { Invites *InviteService } func (h Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) { invites, err := h.Invites.Get(getUserIDFromContext(r.Context())) if err != nil { //TODO: Log error server side. } m := NewInviteComponentViewModel(invites, err) teamInviteComponent(m).Render(r.Context(), w) } func NewInviteComponentViewModel(invites []models.Invite, err error) (m InviteComponentViewModel) { m.InviteCount = len(invites) if err != nil { m.ErrorMessage = "Failed to load invites, please try again" } return m } type InviteComponentViewModel struct { InviteCount int ErrorMessage string } templ teamInviteComponent(model InviteComponentViewModel) { if model.InviteCount > 0 {
You have { fmt.Sprintf("%d", model.InviteCount) } pending invites
} if model.ErrorMessage != "" {
{ model.ErrorMessage }
} } ``` -------------------------------- ### FoldingRange Struct Source: https://github.com/a-h/templ/wiki/coverage.html Represents a folding range with start and end positions, and an optional kind. ```APIDOC ## FoldingRange Struct ### Description Defines a range in the document that can be folded, including its start and end points, and its type. ### Fields - **StartLine** (uint32) - The zero-based line number from where the folded range starts. - **StartCharacter** (uint32, optional) - The zero-based character offset from where the folded range starts. Defaults to the length of the start line. - **EndLine** (uint32) - The zero-based line number where the folded range ends. - **EndCharacter** (uint32, optional) - The zero-based character offset before the folded range ends. Defaults to the length of the end line. - **Kind** (FoldingRangeKind, optional) - Describes the kind of the folding range (e.g., 'comment', 'region'). ```