### 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').
```