nxweb

package module
v0.2.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jun 4, 2026 License: MIT Imports: 28 Imported by: 0

README

Nexus Web 🚀

Nexus Web is a high-performance Go web framework designed for developers who want the simplicity of Fiber but prefer the stability and compatibility of the built-in net/http package.


✨ Key Features

  • Built on net/http: Standard library stability with a Fiber-like DX.
  • Markdown Native: Full GitHub-Flavored Markdown (GFM) support. Any .md file is automatically processed as a page.
  • Cascading Templates: Automatic inheritance—missing files are inherited from the nearest parent directory.
  • Shortcode Plugins: WordPress-style logic for reusable UI components.

📦 Installation

go get github.com/tkdeng/nexusweb

🚀 Quick Start


import (
  nxweb "github.com/tkdeng/nexusweb"
)

func main(){
  // Initialize the app with the template directory and configuration
  app, err := nxweb.New("./app", nxweb.Config{
    Port: 8080,
    Vars: nxweb.Map{
      "myVar": "This is a static constant", // Compiled once at startup
    },
  })

  // GET Route: Rendering a template with dynamic variables
  app.Get("/path", func(c *nxweb.Ctx) error {
    return c.Render("index", nxweb.Map{
      "dynamicVar": "This is injected at runtime!",
    })
  })

  // POST Route: Demonstrates dynamic parameters and automatic sanitization
  app.Post("/api/user/:id", func(c *nxweb.Ctx) error {
    // c.Params contains URI segments extracted by the router
    userID := c.Params["id"]

    // c.Body(key) returns (any, bool) for JSON or Form data
    val, ok := c.Body("name")
    if !ok {
      return c.Json(nxweb.JSON{"error": "Name is required"})
    }

    // ToType[T] converts the value to the requested type AND 
    // automatically ensures valid UTF-8 for string, []byte, and byte.
    userName := nxweb.ToType[string](val)

    return c.Json(nxweb.JSON{
      "status":  "success",
      "message": "Profile updated",
      "data": nxweb.JSON{
        "id":   userID,
        "name": userName,
      },
    })
  })

  // Start the server
  log.Fatal(app.Listen())
}

🛠 Template Syntax

Feature Syntax Description
Embed {@file} Embeds a file with cascading inheritance.
Static {var} Pre-compiled at startup. HTML-escaped.
Dynamic {$var} Runtime variable via c.Render.
Raw {#var} Renders without HTML escaping.
Escaped Arg {=var} Safely escapes variable for HTML attributes.
Attr Guard {class="var"} Renders the attribute only if var is not empty.
Default {var|def} Provides a fallback value if var is empty.
If {?var{...}} Renders content if var is present/true.
Unless {!var{...}} Renders content if var is missing/false.
Plugin {:name} Executes a custom shortcode/plugin (supports optional {content}).

📂 Cascading Inheritance

Nexus Web uses a recursive search for any embedded file ({@filename}). This applies to all file types.

  • #layout.html: The entry point for the engine.
  • @widget.html: Reserved for widgets, logic, and error handling (e.g., @404.html).
  • *.html / *.md: Components embedded via {@filename}.

Example: If /blog/index.html calls {@sidebar}, but /blog/sidebar.html is missing, the engine automatically "climbs" the directory tree to use the root /sidebar.html.

🔌 Plugins

import "github.com/tkdeng/nexusweb/plugins"

func init() {
  // Runs every render
  plugins.New("button", func(args map[string]string, cont []byte, static bool) ([]byte, error) {
    return []byte("<button>"+args["text"]+"</button>"), nil
  })

  // Runs once at compile-time (Static)
  plugins.New("fast", func(args map[string]string, cont []byte, static bool) ([]byte, error) {
    return []byte("<div>Optimized</div>"), nil
  }, true)
}

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func Clean

func Clean[T interface{ string | []byte }](val T) T

Clean will sanitizes a string to valid UTF-8

func EscapeHTML

func EscapeHTML(html []byte, mode ...string) []byte

EscapeHTML escapes HTML characters and HTML arg quotes

@mode (optional):

  • "html": escapes html characters
  • "args": escapes quotes for html args

func GenRsaKey

func GenRsaKey(crtPath string, keyPath string) error

GenRsaKey generates a new ssl certificate and key pair

  • expires: 3 years
  • rsa: 4096
  • x509
  • sha256
  • recommended renewal: once a year

func GenRsaKeyIfNeeded

func GenRsaKeyIfNeeded(crtPath string, keyPath string) error

GenRsaKeyIfNeeded auto detects if the certificates generated by the GenRsaKey method are either

  • not synchronized by date modified
  • are possibly expired (assuming a 1 year renewal)

If it detects this is true, it will automatically regenerate a new certificate

func Gunzip

func Gunzip(path string) ([]byte, error)

Gunzip will decompress a gzip file and return the bytes

func Gzip

func Gzip(path string, data []byte) error

Gzip will compress the given bytes and save them to a gzip file at the specified path

func PrintMsg

func PrintMsg(color string, msg string, size int, end bool)

PrintMsg prints to console and auto inserts spaces

func ToType

func ToType[T goutil.SupportedType](val any) T

ToType attempts to converts an interface{} from the many possible types in golang, to a specific type of your choice

If the target type is a string, []byte, or byte, it automatically calls Clean to sanitize the value to valid UTF-8. If conversion fails, it returns the nil/zero value for the requested type.

Types

type App

type App struct {
	Router
}

App is the primary entry point for the application. It embeds the core Router and manages the server lifecycle.

func New

func New(root string, config ...Config) (*App, error)

New creates a new webserver

func (*App) Listen

func (app *App) Listen(port ...uint16) error

Listen for http requests

default port :8080

note: ports can also be set in the config when creating a new server, and can optionally be overwritten here.

@port (optional):
- 1: HTTP Port
- 2: SSL Port

type Config

type Config struct {
	Title    string // Website meta title
	AppTitle string // Application display name
	Desc     string // Meta description
	Icon     string // Path to favicon or app icon

	AssetsURI string // Public path for compiled assets
	PublicURI string // Public path for static files

	// Origins defines the list of allowed 'Host' header values (e.g., "example.com").
	// If populated, the framework will reject any request whose hostname does
	// not match an entry in this list. Leave empty to allow any host.
	Origins []string

	// Proxies defines a list of trusted IP addresses allowed to connect to the server.
	// This validates the physical connection (RemoteAddr). If populated, requests
	// from IPs not in this list are rejected.
	// NOTE: For local development, include both "127.0.0.1" (IPv4) and "::1" (IPv6).
	Proxies []string

	Vars Map // Global variables available to all templates

	Port    uint16 // HTTP port (default: 8080)
	PortSSL uint16 // HTTPS port (default: 8443)

	// DevMode (Development Mode) optimizes the framework for active development.
	// When true, it disables asset compression and internal caching, ensuring
	// that changes to files and templates are reflected immediately. It also
	// enables framework-level diagnostic tools for the developer.
	DevMode bool

	Root string // The filesystem root of the project

	// Domains identifies internal project domains.
	// Used by the rendering engine to determine link behavior (e.g., whether
	// a Markdown link is internal or requires target="_blank").
	Domains []string

	// Handler will run before any other routes are called.
	// This can be useful for initializing data, or adding a firewall to your router.
	Handler func(c *Ctx) error
}

Config defines the framework settings, including server ports, security headers, and asset directories.

type Ctx

type Ctx struct {

	// Public Request Metadata
	Host     string // The hostname requested (e.g., example.com)
	RemoteIP string // The physical IP address of the immediate connection (extracted from RemoteAddr)
	IP       string // The End-User IP (extracted from X-Forwarded-For)

	Path   string // The sanitized request path
	Port   string // The port the request arrived on
	Method string // HTTP method (GET, POST, etc.)
	Type   string // Content-Type header of the request

	// Params contains dynamic route segments (e.g., :id)
	Params map[string]string
	// contains filtered or unexported fields
}

Ctx represents the request/response context. It provides a unified API for data retrieval, routing parameters, and response control.

func (*Ctx) AddHeader

func (ctx *Ctx) AddHeader(key string, value string)

AddHeader appends a value to a response header without overwriting existing values.

func (*Ctx) Body

func (ctx *Ctx) Body(key string) (value any, ok bool)

Body returns a value from the request body (JSON or Form) and a boolean for existence.

If the Content-Type is application/json, it looks up the key in the JSON body. Otherwise, it looks up the key in the POST form data.

func (*Ctx) BotProtect

func (ctx *Ctx) BotProtect(useErr418 bool) bool

BotProtect hardens the page against clickjacking and verifies the client is not a bot. Returns TRUE if the request is safe to proceed. Returns FALSE if the request was blocked and a response was already sent.

func (*Ctx) Cookie

func (ctx *Ctx) Cookie(name string, value ...string) string

Cookie is a dual-purpose method for getting and setting cookies. If a value is provided, it sets a secure-by-default, same-site-only cookie that expires in 30 days. Defaults are optimized for security: HttpOnly, Strict SameSite, and Domain-locked.

func (*Ctx) DelCookie

func (ctx *Ctx) DelCookie(name string)

DelCookie expires a cookie by name, effectively deleting it from the browser. It mirrors the secure defaults of the Cookie() method to ensure the browser correctly identifies and overwrites the intended cookie.

func (*Ctx) DelHeader

func (ctx *Ctx) DelHeader(key string)

DelHeader removes a specific header from the response.

func (*Ctx) Error

func (ctx *Ctx) Error(path string, status int, msg string) error

Error attempts to render a beautiful error page using a hierarchical fallback system. It searches for templates in the following order: 1. {path}/@{status} (e.g., /users/@404) 2. {path}/@error (e.g., /users/@error) 3. @{status} (e.g., @404) 4. @error (Global error widget) 5. Plain text/HTML fallback if no templates are found.

func (*Ctx) GetCookie

func (ctx *Ctx) GetCookie(name string) (*http.Cookie, error)

GetCookie retrieves the full native http.Cookie object from the request. Use this when you need to inspect cookie metadata beyond just the value, such as Expiry or Domain attributes.

func (*Ctx) Header

func (ctx *Ctx) Header(key string, value ...string) string

Header is a dual-purpose method for request and response headers. If a value is provided, it sets the response header and returns that value. If no value is provided, it returns the sanitized value of the existing response header.

func (*Ctx) IsBot

func (ctx *Ctx) IsBot() bool

IsBot performs a strict header sanity check to identify crawlers or automated tools. It checks for bot-like User-Agents and missing headers typical of real browsers.

func (*Ctx) IsSSL

func (ctx *Ctx) IsSSL() bool

IsSSL returns true if the current request is encrypted. It checks the underlying TLS connection and the X-Forwarded-Proto header.

func (*Ctx) Json

func (ctx *Ctx) Json(val any, indent ...int) error

Json marshals the provided value into a JSON string and writes it to the response. It sets the 'Content-Type: application/json' header. An optional indent (number of spaces) can be provided for pretty-printing the output.

func (*Ctx) Locals

func (ctx *Ctx) Locals(key string, value ...any) any

Locals stores or retrieves request-scoped variables

func (*Ctx) Next

func (ctx *Ctx) Next() error

Next flags the context to continue execution to the next handler in the stack. This is typically used in middleware to allow the request to reach the main handler.

func (*Ctx) Query

func (ctx *Ctx) Query(key string) (value string, ok bool)

Query returns the value of a query parameter and a boolean indicating its existence.

It lazily initializes the query map from the request URL.

func (*Ctx) Render

func (ctx *Ctx) Render(path string, vars ...Map) error

Render processes a template file with a set of variables and writes the result to the response. It automatically handles path normalization (e.g., index files, suffix stripping) and identifies "Widgets" (paths starting with @). It merges global config variables, router-level variables, and local variables passed into the call.

func (*Ctx) Request

func (ctx *Ctx) Request() *http.Request

Request returns the underlying *http.Request

func (*Ctx) Response

func (ctx *Ctx) Response() http.ResponseWriter

Response returns the underlying http.ResponseWriter

func (*Ctx) SetBody

func (ctx *Ctx) SetBody(key string, value ...string)

SetBody sets a post body parameter

If no value is provided, the key is deleted

func (*Ctx) SetCookie

func (ctx *Ctx) SetCookie(cookie *http.Cookie)

SetCookie adds a Set-Cookie header to the response

func (*Ctx) SetQuery

func (ctx *Ctx) SetQuery(key string, value ...string)

SetQuery modifies or deletes a query parameter in the current context.

If a value is provided, it updates the parameter; if no value is provided, the key is deleted from the query map.

func (*Ctx) Status

func (ctx *Ctx) Status(status int) *Ctx

Status sets the HTTP response status code. This is buffered within the Ctx and only sent to the client when a "Write" method (like JSON, String, etc.) is called. This allows headers to be modified even after the status is set.

func (*Ctx) Write

func (ctx *Ctx) Write(buf []byte) error

Write sends raw bytes to the response body.

type JSON

type JSON map[string]any

JSON is a shorthand for map[string]any, used for flexible data structures like JSON responses or complex body parsing.

type Map

type Map map[string]string

Map is a shorthand for map[string]string, used primarily for passing template variables or configuration sets.

type Router

type Router struct {
	Config Config // Global framework settings
	// contains filtered or unexported fields
}

Router handles path-based request multiplexing and middleware registration.

func (*Router) Get

func (router *Router) Get(path string, cb func(c *Ctx) error)

Get registers a handler for HTTP GET requests on the specified path. It leverages the underlying 'use' method to handle path matching and dynamic parameter extraction (e.g., /:id or /:id?).

func (*Router) NewRouter

func (router *Router) NewRouter(path string, handler func(c *Ctx) error, vars ...Map) *Router

NewRouter creates a sub-router mounted at the specified path.

It provides prefix-based isolation (e.g., /api) and inherits parent variables, which are automatically injected into the Render engine.

@handler will run before any other routes are called. This can be useful for initializing data, or adding a firewall to your router.

func (*Router) Post

func (router *Router) Post(path string, cb func(c *Ctx) error)

Post registers a handler for HTTP POST requests on the specified path. It leverages the underlying 'use' method, which provides automatic body parsing for 'application/json', 'multipart/form-data', and 'application/x-www-form-urlencoded' before the callback is executed.

func (*Router) Use

func (router *Router) Use(path string, cb func(c *Ctx) error)

Use registers a callback for a specific path pattern.

Supports static paths, dynamic segments (/:id), and optional parameters (/:id?). It automatically prepares the request body and form data based on the Content-Type header before reaching child handlers.

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL