### Example HTTPEndpoint Implementation Source: https://github.com/getludic/ludic/blob/main/_autodocs/api-reference/web-endpoints.md Demonstrates how to implement `HTTPEndpoint` by defining `get` and `post` methods to handle HTTP requests. This example shows returning HTML components based on the request method. ```python from ludic.web.endpoints import HTTPEndpoint from ludic.html import button class MyButton(HTTPEndpoint): async def get(self, request: Request) -> button: return button("Click Me", hx_post="/api/click") async def post(self, request: Request) -> div: return div("Clicked!") ``` -------------------------------- ### Basic App Setup and Route Source: https://github.com/getludic/ludic/blob/main/skills/ludic-web/SKILL.md Demonstrates how to initialize a LudicApp and define a simple GET route for the homepage. ```APIDOC ## GET / ### Description Handles GET requests to the root path and returns a simple HTML paragraph. ### Method GET ### Endpoint / ### Response #### Success Response (200) - **content** (p) - A Ludic HTML element representing a paragraph. #### Response Example

Hello Stranger!

``` -------------------------------- ### Install and Install Pre-Commit Hooks Source: https://github.com/getludic/ludic/blob/main/CONTRIBUTING.md Installs the pre-commit package and sets up the necessary hooks for code quality checks before committing. ```bash python -m pip install pre-commit pre-commit install --install-hooks ``` -------------------------------- ### Install All Ludic Skills Source: https://github.com/getludic/ludic/blob/main/README.md Installs all available Ludic skills using a wildcard. This command is equivalent to installing both ludic-components and ludic-web skills. ```bash npx skills add https://github.com/getludic/ludic --skill '*' ``` -------------------------------- ### Install and Run Ludic App with uv Source: https://github.com/getludic/ludic/blob/main/_autodocs/configuration.md A single command to install dependencies (including 'full' extras) and run the Ludic application using uv. ```bash uv run --with "'.[full]'" uvicorn main:app ``` -------------------------------- ### Usage Example: LudicApp with Endpoints Source: https://github.com/getludic/ludic/blob/main/_autodocs/api-reference/web-endpoints.md A complete example demonstrating how to set up a Ludic application with multiple endpoints, including URL generation and lazy loading of components. ```APIDOC ## Usage Example Complete example of an endpoint with URL generation and lazy loading: ```python from ludic.web import LudicApp, Endpoint from ludic.html import div, h1, a, p from ludic.attrs import Attrs app = LudicApp() class UserAttrs(Attrs): user_id: int @app.endpoint("/users/{user_id}", name="user-detail") class UserDetail(Endpoint[UserAttrs]): @override def render(self) -> div: user_id = self.attrs["user_id"] return div( h1(f"User {user_id}"), a("Back to Users", href=str(self.url_for("user-list"))), self.lazy_load(UserStats, user_id=user_id) ) @app.endpoint("/users", name="user-list") class UserList(Endpoint[NoAttrs]): @override def render(self) -> div: return div( h1("Users"), p(a("Create New", href=str(self.url_for("user-create")))) ) @app.endpoint("/users/{user_id}/stats", name="user-stats") class UserStats(Endpoint[UserAttrs]): @override def render(self) -> div: user_id = self.attrs["user_id"] return div(p(f"Stats for user {user_id}")) ``` ``` -------------------------------- ### Complete Endpoint Usage Example Source: https://github.com/getludic/ludic/blob/main/_autodocs/api-reference/web-endpoints.md Illustrates a full example of defining multiple endpoints with URL generation and lazy loading capabilities. This includes setting up a `LudicApp`, defining user detail, user list, and user stats endpoints with dynamic routing. ```python from ludic.web import LudicApp, Endpoint from ludic.html import div, h1, a, p from ludic.attrs import Attrs app = LudicApp() class UserAttrs(Attrs): user_id: int @app.endpoint("/users/{user_id}", name="user-detail") class UserDetail(Endpoint[UserAttrs]): @override def render(self) -> div: user_id = self.attrs["user_id"] return div( h1(f"User {user_id}"), a("Back to Users", href=str(self.url_for("user-list"))), self.lazy_load(UserStats, user_id=user_id) ) @app.endpoint("/users", name="user-list") class UserList(Endpoint[NoAttrs]): @override def render(self) -> div: return div( h1("Users"), p(a("Create New", href=str(self.url_for("user-create")))) ) @app.endpoint("/users/{user_id}/stats", name="user-stats") class UserStats(Endpoint[UserAttrs]): @override def render(self) -> div: user_id = self.attrs["user_id"] return div(p(f"Stats for user {user_id}")) ``` -------------------------------- ### Install Ludic with full features Source: https://github.com/getludic/ludic/blob/main/README.md Install the Ludic library with all optional dependencies using pip. ```bash pip install "ludic[full]" ``` -------------------------------- ### Install Both Ludic Skills Source: https://github.com/getludic/ludic/blob/main/README.md Installs both ludic-components and ludic-web skills simultaneously. This is a convenient way to set up the agent for all Ludic development tasks. ```bash npx skills add https://github.com/getludic/ludic --skill ludic-components --skill ludic-web ``` -------------------------------- ### Run Ludic Example Source: https://github.com/getludic/ludic/blob/main/examples/README.md Command to run a Ludic example using Uvicorn. The command must be executed from the repository root. ```bash uvicorn examples.:app --reload ``` -------------------------------- ### Example: Create a Div Element Source: https://github.com/getludic/ludic/blob/main/_autodocs/api-reference/elements.md This example demonstrates creating a `div` element with `p` tag children and setting `id` and `class_` attributes. It uses `Element` for flexible children. ```python from ludic.html import div, p from ludic.types import AnyChildren from ludic.attrs import GlobalAttrs # Create a div with any children container = div( p("Hello"), p("World"), id="main", class_="container" ) ``` -------------------------------- ### Example Usage of Headers Source: https://github.com/getludic/ludic/blob/main/_autodocs/types.md Demonstrates how to create a Headers object with various JSON-serializable values. ```python from ludic.types import Headers headers: Headers = { "X-Custom": "value", "X-Count": 42, "X-Data": {"key": "value"}, } ``` -------------------------------- ### Install and Run Pre-commit Hooks Source: https://github.com/getludic/ludic/blob/main/_autodocs/configuration.md Commands for managing pre-commit hooks in a Ludic project. Includes installation and manual execution of all hooks. ```bash pre-commit install --install-hooks ``` ```bash pre-commit run --all-files ``` -------------------------------- ### Install Ludic with Pip Source: https://github.com/getludic/ludic/blob/main/_autodocs/configuration.md Install Ludic using pip, with options for full installation, core only, or specific extras like Starlette, Django, or FastAPI. ```bash # Full installation with all optional dependencies pip install "ludic[full]" # Core only (no Starlette, uvicorn, or optional features) pip install ludic # With specific extras pip install "ludic[starlette]" # Starlette web framework pip install "ludic[django]" # Django integration pip install "ludic[fastapi]" # FastAPI integration ``` -------------------------------- ### Install Test Dependencies for Pytest Source: https://github.com/getludic/ludic/blob/main/CONTRIBUTING.md Installs the framework with full and test optional dependencies, required for running the test suite with pytest. ```bash python -m pip install -e ".[full,test]" ``` -------------------------------- ### Complete Ludic Import Example Source: https://github.com/getludic/ludic/blob/main/_autodocs/module-exports.md A comprehensive example demonstrating how to import core Ludic components, HTML elements, attributes, types, web framework utilities, styling modules, and optional catalog components. ```python # Core imports from ludic import Component, Attrs, Blank from ludic.html import div, h1, p, button, input_ from ludic.attrs import GlobalAttrs, ButtonAttrs, InputAttrs from ludic.types import Safe, AnyChildren, TAttrs # Web framework imports from ludic.web import LudicApp, Endpoint, Request, LudicResponse from ludic.web.responses import RedirectResponse, JSONResponse # Styling imports from ludic.styles import Theme, Colors, get_default_theme, set_default_theme # Utilities from ludic.types import Safe, JavaScript from ludic.format import format_attrs # Catalog (optional) from ludic.catalog.buttons import Button from ludic.catalog.forms import Field ``` -------------------------------- ### Example: Render Children with Blank Source: https://github.com/getludic/ludic/blob/main/_autodocs/api-reference/elements.md This example shows how to use `Blank` to render multiple `p` tags directly. It also demonstrates conditional rendering where `Blank` can return multiple elements or nothing. ```python from ludic import Blank from ludic.html import div, p, b, i # Render multiple children without wrapping content = Blank( p("First paragraph"), p("Second paragraph"), ) print(content.to_html()) #

First paragraph

Second paragraph

# Useful in conditional rendering def render_optional(show: bool): if show: return Blank(b("Bold"), " and ", i("Italic")) return Blank() ``` -------------------------------- ### Build Web Application with Ludic Source: https://github.com/getludic/ludic/blob/main/_autodocs/README.md Set up a basic web application using LudicApp. This example demonstrates routing a homepage endpoint that returns a custom Card component. ```python # Web application from ludic.web import LudicApp app = LudicApp(debug=True) @app.get("/") async def homepage(request): return Card("Welcome!", title="Home") ``` -------------------------------- ### Install Pre-commit Hooks Source: https://github.com/getludic/ludic/blob/main/AGENTS.md Install pre-commit hooks to ensure code quality checks are performed automatically before each commit. This is a required step before submitting changes. ```bash pre-commit install --install-hooks ``` -------------------------------- ### Install Ludic and Uvicorn Source: https://github.com/getludic/ludic/blob/main/examples/README.md Installs Ludic with full support and Uvicorn for running web applications. Ensure you are using Python 3.12+. ```bash pip install "ludic[full]" pip install uvicorn ``` -------------------------------- ### Instantiate a custom Link component Source: https://github.com/getludic/ludic/blob/main/README.md Example of how to create an instance of the custom Link component with provided children and attributes. ```python link = Link("Hello, World!", to="/home") ``` -------------------------------- ### Example of Using AnyChildren Source: https://github.com/getludic/ludic/blob/main/_autodocs/types.md Demonstrates the flexibility of `AnyChildren` by showing valid examples of passing various types of content (strings, numbers, booleans, nested elements, safe HTML) as children to a `div` element. ```python from ludic.html import div, p # All valid: div("text") div(123) div(True) div(p("nested")) div(Safe("html")) div("text", p("mixed"), 42) ``` -------------------------------- ### Install ludic-components Skill Source: https://github.com/getludic/ludic/blob/main/README.md Installs the ludic-components skill for building components. Use this when you need to work with Ludic's templating, component typing, catalog widgets, htmx attributes, and content boundaries. ```bash npx skills add https://github.com/getludic/ludic --skill ludic-components ``` -------------------------------- ### Register GET Endpoint Source: https://github.com/getludic/ludic/blob/main/_autodocs/api-reference/web-app.md Use the `get` decorator to register a handler for GET requests. It accepts a URL path pattern which can include parameter placeholders like `{param}`. Additional options such as `name` and `include_in_schema` can be passed via `**kwargs`. ```python def get(self, path: str, **kwargs: Any) -> Callable[[TCallable], TCallable] ``` -------------------------------- ### Basic Ludic App Setup Source: https://github.com/getludic/ludic/blob/main/skills/ludic-web/SKILL.md Sets up a basic Ludic application with a root endpoint that returns an HTML paragraph. LudicApp handles serialization of Ludic elements to HTML responses. ```python from ludic.web import LudicApp from ludic.html import b, p app = LudicApp() @app.get("/") async def homepage() -> p: return p(t"Hello {b('Stranger')}!") ``` -------------------------------- ### Example Usage of HXHeaders Source: https://github.com/getludic/ludic/blob/main/_autodocs/types.md Shows how to construct an HXHeaders object with specific htmx response headers. ```python from ludic.types import HXHeaders headers: HXHeaders = { "HX-Redirect": "/success", "HX-Refresh": True, } ``` -------------------------------- ### Create and Configure LudicApp Instance Source: https://github.com/getludic/ludic/blob/main/_autodocs/api-reference/web-app.md Example of creating a LudicApp instance with debug mode enabled and defining a simple homepage route that returns an HTML response. ```python from ludic.web import LudicApp from ludic.html import html, head, body, h1 app = LudicApp(debug=True) @app.get("/") async def homepage(request: Request) -> html: return html( head(), body(h1("Welcome")) ) ``` -------------------------------- ### Install ludic-web Skill Source: https://github.com/getludic/ludic/blob/main/README.md Installs the ludic-web skill for building web applications. Use this for working with LudicApp, typed Endpoint classes, FastAPI/Django integrations, parsers, responses, htmx patterns, and safe URL generation. ```bash npx skills add https://github.com/getludic/ludic --skill ludic-web ``` -------------------------------- ### CSSProperties Example Source: https://github.com/getludic/ludic/blob/main/_autodocs/types.md Demonstrates how to define and use the CSSProperties type alias for styling HTML elements. ```python from ludic.types import CSSProperties from ludic.html import div styles: CSSProperties = { "color": "red", "font-size": "16px", "margin": "10px 20px", } el = div("Styled", style=styles) ``` -------------------------------- ### Ludic Project Structure Example Source: https://github.com/getludic/ludic/blob/main/_autodocs/configuration.md Illustrates the recommended directory and file layout for a Ludic project. This structure helps organize application components, pages, styles, and tests. ```text project/ ├── pyproject.toml # Package metadata and dependencies ├── main.py # Application entry point ├── components/ │ ├── __init__.py │ ├── buttons.py │ ├── cards.py │ └── forms.py ├── pages/ │ ├── __init__.py │ ├── home.py │ ├── about.py │ └── dashboard.py ├── styles/ │ ├── __init__.py │ └── theme.py └── tests/ ├── __init__.py ├── test_components.py └── test_pages.py ``` -------------------------------- ### Set up a Ludic Web Application Source: https://github.com/getludic/ludic/blob/main/_autodocs/index.md Initialize a Ludic web application with debug mode enabled and define a simple homepage route. This is the starting point for building web interfaces with Ludic. ```python from ludic.web import LudicApp from ludic.html import html, body, h1 app = LudicApp(debug=True) @app.get("/") async def homepage(request): return html( body(h1("Welcome to Ludic")) ) # Run: uvicorn main:app --reload ``` -------------------------------- ### Example: Create a Section with Strict Children Source: https://github.com/getludic/ludic/blob/main/_autodocs/api-reference/elements.md This example defines a `Section` component inheriting from `ElementStrict`. It enforces that the first child must be an `h1` and the second a `p`, ensuring type safety. ```python from ludic.elements import ElementStrict from ludic.html import h1, p from ludic.attrs import GlobalAttrs class Section(ElementStrict[h1, p, GlobalAttrs]): """A section with exactly a heading and a paragraph.""" html_name = "section" def __init__(self, heading: h1, content: p, **attrs: Unpack[GlobalAttrs]): super().__init__(heading, content, **attrs) # Type-safe: first child must be h1, second must be p section = Section( h1("Title"), p("Content"), id="main-section" ) ``` -------------------------------- ### Create a Ludic web application Source: https://github.com/getludic/ludic/blob/main/README.md Set up a basic Ludic web application using LudicApp and define a route for the homepage. This example integrates the custom Link component. ```python from ludic.web import LudicApp from ludic.html import b, p from .components import Link app = LudicApp() @app.get("/") async def homepage() -> p: return p(t"Hello {b("Stranger")}! Click {Link("here", to="https://example.com")}!") ``` -------------------------------- ### Handler Parameter Extraction Example Source: https://github.com/getludic/ludic/blob/main/_autodocs/api-reference/web-responses.md Illustrates how handler parameters are automatically extracted from the request, including path, query, and type-hinted parameters. ```python # Handler parameters are automatically extracted @app.get("/users/{user_id}") async def user_detail(request: Request, user_id: int, format: str = "json"): # user_id extracted from path: /users/123 # format extracted from query: ?format=json # request passed directly return div(f"User {user_id}") ``` -------------------------------- ### Component with Custom Attributes Example Source: https://github.com/getludic/ludic/blob/main/_autodocs/types.md Illustrates creating a custom component 'Alert' that accepts specific attributes like 'level' and various types of children. ```python from ludic import Component, Attrs from ludic.types import Safe, AnyChildren, TAttrs from ludic.html import div, p class AlertAttrs(Attrs): level: str = "info" # info, warning, error class Alert(Component[AnyChildren, AlertAttrs]): """Component accepting any children with flexible attributes.""" @override def render(self) -> div: level = self.attrs.get("level", "info") # Children can be strings, numbers, elements, or safe HTML return div( *self.children, class_=f"alert alert-{level}", role="alert" ) # Valid usages: Alert("Simple message", level="warning") Alert(p("Nested element"), level="error") Alert("Mixed", 123, p("content"), Safe("bold")) ``` -------------------------------- ### Complete Ludic Application Example Source: https://github.com/getludic/ludic/blob/main/_autodocs/api-reference/web-responses.md Demonstrates the usage of various response types within a Ludic application, including HTML, JSON, plain text, and redirects. ```python from ludic.web import LudicApp, Request from ludic.web.responses import ( RedirectResponse, JSONResponse, PlainTextResponse, ) from ludic.html import div, h1, p, a app = LudicApp() @app.get("/") async def homepage(request: Request) -> div: return div(h1("Welcome")) @app.post("/users") async def create_user(request: Request) -> tuple[div, int]: # Return component with 201 Created status return div(h1("User Created")), 201 @app.get("/users/{user_id}") async def user_detail(request: Request, user_id: int) -> div: return div( h1(f"User {user_id}"), a("Back", href="/") ) @app.delete("/users/{user_id}") async def delete_user(request: Request, user_id: int) -> RedirectResponse: # Delete user... return RedirectResponse(url="/") @app.get("/api/health") async def health(request: Request) -> JSONResponse: return JSONResponse({"status": "ok"}) @app.get("/text") async def text_response(request: Request) -> PlainTextResponse: return PlainTextResponse("Hello World") ``` -------------------------------- ### Use Inline Component Source: https://github.com/getludic/ludic/blob/main/_autodocs/api-reference/components.md Example of using the Inline component to wrap text and apply inline styling or attributes, such as a class. ```python from ludic import Inline from ludic.html import b highlight = Inline( "This is ", b("important"), " text", class_="highlight" ) ``` -------------------------------- ### Use Block Component Source: https://github.com/getludic/ludic/blob/main/_autodocs/api-reference/components.md Example of using the Block component to wrap multiple child elements and apply global attributes like an ID. ```python from ludic import Block from ludic.html import p content = Block( p("First paragraph"), p("Second paragraph"), id="container" ) ``` -------------------------------- ### Accessing Theme in a Component Source: https://github.com/getludic/ludic/blob/main/_autodocs/api-reference/components.md Example of how to access the theme within a component's render method to apply styles. ```python class MyComponent(Component[AnyChildren, GlobalAttrs]): def render(self): color = self.theme.colors.primary return div(style={"color": color}) ``` -------------------------------- ### Automatic Response Conversion Example Source: https://github.com/getludic/ludic/blob/main/_autodocs/api-reference/web-responses.md Demonstrates how LudicApp automatically converts different return types into appropriate HTTP responses based on their type. ```python from ludic.web import LudicApp, Request from ludic.html import div, h1 app = LudicApp() @app.get("/") async def homepage(request: Request) -> div: return div(h1("Welcome")) # Automatically LudicResponse with 200 @app.post("/users") async def create_user(request: Request) -> tuple[div, int]: return div(h1("User Created")), 201 # Status 201 @app.delete("/users/{user_id}") async def delete_user(request: Request, user_id: int) -> None: # Delete user... return None # 204 No Content ``` -------------------------------- ### Homepage Endpoint Source: https://github.com/getludic/ludic/blob/main/_autodocs/api-reference/web-responses.md Handles GET requests to the root path and returns an HTML response. ```APIDOC ## GET / ### Description Handles GET requests to the root path and returns an HTML response. ### Method GET ### Endpoint / ### Response #### Success Response (200) - **component** (div) - The HTML component to render. ### Request Example (No request body for GET) ### Response Example ```html

Welcome

``` ``` -------------------------------- ### Run Tests with uv Source: https://github.com/getludic/ludic/blob/main/CLAUDE.md Execute all tests using uv to manage the Python environment and dependencies. Ensures Python 3.14 and the 'full', 'test' extras are installed. ```bash uv run --python 3.14 --with ".[full,test]" pytest ``` -------------------------------- ### Endpoints as Classes Source: https://github.com/getludic/ludic/blob/main/skills/ludic-web/SKILL.md Illustrates how to define endpoints using classes for managing different HTTP verbs (GET, PUT, DELETE) for a specific resource. ```APIDOC ## Item Endpoint ### Description Manages operations for a resource identified by an integer ID. ### Method GET ### Endpoint /items/{id:int} ### Description Retrieves an item by its ID. ### Method PUT ### Endpoint /items/{id:int} ### Description Updates an item by its ID. ### Parameters #### Path Parameters - **id** (int) - Required - The ID of the item to update. #### Request Body - **data** (Parser[ItemAttrs]) - Required - The data to update the item with, validated against ItemAttrs. ### Method DELETE ### Endpoint /items/{id:int} ### Description Deletes an item by its ID. ``` -------------------------------- ### Define Ludic Web App Routes Source: https://github.com/getludic/ludic/blob/main/_autodocs/api-reference/web-requests.md This Python snippet demonstrates how to set up a LudicApp and define multiple GET routes, including a home page, an about page, a user profile page with a path parameter, and a list of users. ```python from ludic.web import LudicApp, Request from ludic.html import div, h1, a, p app = LudicApp() @app.get("/", name="home") async def home(request: Request) -> div: return div( h1("Welcome"), p(a("Go to About", href=str(request.url_for("about")))) ) @app.get("/about", name="about") async def about(request: Request) -> div: return div( h1("About Page"), p(a("Back Home", href=str(request.url_for("home")))) ) @app.get("/users/{user_id}", name="user-profile") async def user_profile(request: Request, user_id: int) -> div: return div( h1(f"User {user_id}"), p(a("All Users", href=str(request.url_for("users-list")))) ) @app.get("/users", name="users-list") async def users_list(request: Request) -> div: # Generate links to individual users links = [ a(f"User {i}", href=str(request.url_for("user-profile", user_id=i))) for i in range(1, 4) ] return div(h1("Users"), *links) ``` -------------------------------- ### Example: Class-Based Endpoint Registration Source: https://github.com/getludic/ludic/blob/main/_autodocs/api-reference/web-app.md Demonstrates how to register a class-based endpoint using the `app.endpoint` decorator. The `Endpoint` class is used for defining the handler, and attributes like `user_id` can be accessed from `self.attrs`. ```python from ludic.web import LudicApp, Endpoint app = LudicApp() @app.endpoint("/users/{user_id}", name="user-detail") class UserDetail(Endpoint[UserDetailAttrs]): @override def render(self) -> div: user_id = self.attrs["user_id"] return div(f"User {user_id}") ``` -------------------------------- ### Minimal Hardened Ludic App Setup with Security Middleware Source: https://github.com/getludic/ludic/blob/main/skills/ludic-web/SKILL.md Configure a Ludic app with `ProxyHeadersMiddleware` and `TrustedHostMiddleware` to mitigate host header poisoning. Ensure `ProxyHeadersMiddleware` runs before `TrustedHostMiddleware` to correctly process forwarded headers. ```python from starlette.middleware import Middleware from starlette.middleware.trustedhost import TrustedHostMiddleware from uvicorn.middleware.proxy_headers import ProxyHeadersMiddleware from ludic.web import LudicApp middleware = [ # Behind a known proxy/CDN only — set trusted_hosts to your proxy's IP range Middleware(ProxyHeadersMiddleware, trusted_hosts=["127.0.0.1"]), # Reject any request whose Host header isn't one of yours Middleware(TrustedHostMiddleware, allowed_hosts=["example.com", "*.example.com"]), ] app = LudicApp(middleware=middleware) ``` -------------------------------- ### Example Usage of LudicResponse Source: https://github.com/getludic/ludic/blob/main/_autodocs/api-reference/web-responses.md Demonstrates how to use LudicResponse to return a rendered Ludic component from a route handler. LudicApp can automatically convert elements, but explicit return is also shown. ```python from ludic.web import LudicApp, Request from ludic.web.responses import LudicResponse from ludic.html import div, h1 app = LudicApp() @app.get("/") async def homepage(request: Request) -> div | LudicResponse: content = div(h1("Welcome")) # LudicApp automatically converts BaseElement to LudicResponse # but you can also return it explicitly return LudicResponse(content, status_code=200) ``` -------------------------------- ### Serve Documentation Locally Source: https://github.com/getludic/ludic/blob/main/AGENTS.md Build and serve the project documentation locally using MkDocs Material. This command allows you to preview documentation changes. ```bash mkdocs serve ``` -------------------------------- ### Serve and Build Ludic Documentation Source: https://github.com/getludic/ludic/blob/main/_autodocs/configuration.md Use these commands to serve the documentation locally for development or to build static documentation files. ```bash # Serve docs locally mkdocs serve ``` ```bash # Build static docs mkdocs build ``` -------------------------------- ### GET Endpoint Registration Source: https://github.com/getludic/ludic/blob/main/_autodocs/api-reference/web-app.md Register a GET endpoint for a specific URL path. Supports path parameters and additional options. ```APIDOC ## GET /path ### Description Register a GET endpoint for a specific URL path. ### Method GET ### Endpoint /path ### Parameters #### Path Parameters - **path** (str) - Required - URL path pattern (supports `{param}` syntax) #### Query Parameters None explicitly documented. #### Request Body None explicitly documented. ### Request Example None provided. ### Response #### Success Response (200) None explicitly documented. #### Response Example None provided. ``` -------------------------------- ### Initialize BaseElement with Children and Attributes Source: https://github.com/getludic/ludic/blob/main/_autodocs/api-reference/base-element.md Demonstrates basic initialization of a BaseElement with direct children and HTML attributes, including class names. ```python from ludic.html import div, p # Basic usage el = div("Hello", p("World"), id="main", class_="container") ``` -------------------------------- ### Create and Apply a Custom Theme Source: https://github.com/getludic/ludic/blob/main/_autodocs/api-reference/styles-theme.md Demonstrates how to create a custom `Theme` object with specific colors, fonts, and sizes, and then set it as the default for all Ludic components. The custom theme is then applied within a `Card` component. ```python from ludic import Component from ludic.styles import Theme, Colors, Fonts, Sizes, set_default_theme, Color, Size from ludic.html import div, h1, p from typing import override from ludic.attrs import GlobalAttrs # Create custom theme custom_theme = Theme( colors=Colors( primary=Color("#0066cc"), secondary=Color("#999999"), success=Color("#00aa00"), danger=Color("#cc0000"), ), fonts=Fonts( primary="'Inter', sans-serif", secondary="Georgia, serif", monospace="'Courier New', monospace", size=Size(16, "px"), ), sizes=Sizes(), # Use defaults or customize ) # Set as default for all components set_default_theme(custom_theme) # Use in components class Card(Component[str, GlobalAttrs]): @override def render(self) -> div: return div( h1(*self.children, style={ "color": self.theme.colors.primary, "font-family": self.theme.fonts.primary, "font-size": self.theme.fonts.size, "padding": self.theme.sizes.m, "border": f"1px solid {self.theme.colors.secondary}", "border-radius": self.theme.rounding.normal, }), **self.attrs ) ``` -------------------------------- ### User Detail Endpoint Source: https://github.com/getludic/ludic/blob/main/_autodocs/api-reference/web-responses.md Handles GET requests to retrieve details for a specific user by ID. ```APIDOC ## GET /users/{user_id} ### Description Handles GET requests to retrieve details for a specific user by ID. ### Method GET ### Endpoint /users/{user_id} ### Parameters #### Path Parameters - **user_id** (int) - Required - The ID of the user to retrieve. ### Response #### Success Response (200) - **component** (div) - The HTML component displaying user details. ### Response Example ```html

User 123

Back
``` ``` -------------------------------- ### Configure LudicApp Source: https://github.com/getludic/ludic/blob/main/_autodocs/configuration.md Configure a LudicApp instance with basic settings, lifespan context managers for startup/shutdown events, and custom exception handlers. ```python from ludic.web import LudicApp from ludic.html import div # Basic configuration app = LudicApp(debug=True) # With lifespan from contextlib import contextmanager @contextmanager async def lifespan(app): # Startup print("Starting up...") yield # Shutdown print("Shutting down...") app = LudicApp(debug=True, lifespan=lifespan) # With exception handlers from ludic.web import Request from starlette.exceptions import HTTPException @app.exception_handler(404) async def not_found(request: Request, exc: HTTPException): return div("Page not found") @app.exception_handler(ValueError) async def value_error(request: Request, exc: ValueError): return div(f"Invalid value: {exc}") ``` -------------------------------- ### Create a Ludic project using Cookiecutter Source: https://github.com/getludic/ludic/blob/main/README.md Use the Ludic cookiecutter template to quickly set up a new project with UV for dependency management. ```bash uvx cookiecutter gh:getludic/template ``` -------------------------------- ### Text Response Endpoint Source: https://github.com/getludic/ludic/blob/main/_autodocs/api-reference/web-responses.md Handles GET requests to the /text endpoint, returning a plain text response. ```APIDOC ## GET /text ### Description Handles GET requests to the /text endpoint, returning a plain text response. ### Method GET ### Endpoint /text ### Response #### Success Response (200) - **response** (PlainTextResponse) - A plain text string. ### Response Example ``` Hello World ``` ``` -------------------------------- ### text Source: https://github.com/getludic/ludic/blob/main/_autodocs/api-reference/base-element.md Extracts all text content from the element and its descendants. This method is useful for getting the combined text of nested elements. ```APIDOC ## text ### Description Extracts all text content from this element and its descendants. ### Method `@property` ### Endpoint N/A (This is a Python property) ### Parameters None ### Response - **text** (str) - The combined text content of the element and its children. ### Response Example ```python 'Hello World' ``` ``` -------------------------------- ### Initialize BaseElement with T-String Templates Source: https://github.com/getludic/ludic/blob/main/_autodocs/api-reference/base-element.md Shows how to use t-string templates for dynamic content generation within BaseElement children, requiring Python 3.14+. ```python from ludic.html import b el = div(t"Hello {b('World')}", id="main") ``` -------------------------------- ### Configure Cover Layout Source: https://github.com/getludic/ludic/blob/main/_autodocs/api-reference/styles-theme.md Set up the cover layout component using the `Cover` dataclass, defining the minimum height and the HTML element to be used as the centering point. ```python from dataclasses import dataclass from ludic.styles import BaseSize, Size @dataclass class Cover: min_height: BaseSize = Size(100, "vh") element: str = "h1" ``` -------------------------------- ### Health Check Endpoint Source: https://github.com/getludic/ludic/blob/main/_autodocs/api-reference/web-responses.md Handles GET requests to the /api/health endpoint, returning a JSON response indicating the service status. ```APIDOC ## GET /api/health ### Description Handles GET requests to the /api/health endpoint, returning a JSON response indicating the service status. ### Method GET ### Endpoint /api/health ### Response #### Success Response (200) - **response** (JSONResponse) - A JSON object with the status. ### Response Example ```json { "status": "ok" } ``` ``` -------------------------------- ### Render JavaScript Safe String Source: https://github.com/getludic/ludic/blob/main/_autodocs/types.md Example of using the `JavaScript` type to embed code within a ` ``` -------------------------------- ### Starlette Integration with Middleware Source: https://github.com/getludic/ludic/blob/main/_autodocs/configuration.md Integrate Ludic with Starlette by subclassing `LudicApp`. This example shows how to include standard Starlette middleware, such as CORS configuration. ```python from ludic.web import LudicApp from starlette.middleware.cors import CORSMiddleware app = LudicApp( middleware=[ Middleware( CORSMiddleware, allow_origins=["https://example.com"], allow_credentials=True, allow_methods=["*"], allow_headers=["*"], ) ] ) ``` -------------------------------- ### FastAPI Integration Source: https://github.com/getludic/ludic/blob/main/_autodocs/configuration.md Use Ludic components directly within a FastAPI application. No special setup is required for basic component rendering in FastAPI routes. ```python from fastapi import FastAPI from ludic.html import div, h1 app = FastAPI() @app.get("/") def homepage(): return div(h1("Welcome")) ``` -------------------------------- ### Test Homepage Endpoint Source: https://github.com/getludic/ludic/blob/main/skills/ludic-web/SKILL.md Use Starlette's TestClient to make a GET request to the root endpoint and assert the status code and response body content. ```python from starlette.testclient import TestClient def test_homepage(): client = TestClient(app) r = client.get("/") assert r.status_code == 200 assert "Hello" in r.text ``` -------------------------------- ### Home Page Source: https://github.com/getludic/ludic/blob/main/_autodocs/api-reference/web-requests.md Handles requests to the root URL and displays a welcome message with a link to the about page. ```APIDOC ## GET / ### Description Handles requests to the root URL and displays a welcome message with a link to the about page. ### Method GET ### Endpoint / ### Parameters #### Query Parameters None #### Request Body None ### Response #### Success Response (200) Returns an HTML div element. ### Response Example ```html

Welcome

Go to About

``` ``` -------------------------------- ### Initialize Element with Children and Attributes Source: https://github.com/getludic/ludic/blob/main/_autodocs/api-reference/elements.md The constructor for `Element` accepts any number of children and attributes. Children should match the `TChildren` generic type, and attributes should match `TAttrs`. ```python def __init__( self, *children: TChildren, **attrs: Unpack[TAttrs], ) -> None ``` -------------------------------- ### Extract Text Content Source: https://github.com/getludic/ludic/blob/main/_autodocs/api-reference/base-element.md Use this property to extract all text content from an element and its descendants. This is helpful for getting a plain text representation of complex nested elements. ```python from ludic.html import div, p el = div(p("Hello"), " ", p("World")) print(el.text) # Hello World ``` -------------------------------- ### Format Code with Ruff Source: https://github.com/getludic/ludic/blob/main/CLAUDE.md Automatically format code across the project using ruff. ```bash ruff format . ``` -------------------------------- ### Run Project Commands with uv Source: https://github.com/getludic/ludic/blob/main/AGENTS.md Use `uv run` to execute project commands, ensuring the correct Python version and dependencies are used. This is the preferred method for running tests and type checks. ```bash uv run --python 3.14 --with ".[full,test]" pytest ``` ```bash uv run --python 3.14 --with ".[full,test]" pytest tests/test_components.py::test_name ``` ```bash uv run --python 3.14 --with ".[full,test]" mypy ludic ``` -------------------------------- ### Get Aliased Attributes Source: https://github.com/getludic/ludic/blob/main/_autodocs/api-reference/base-element.md Use this property to retrieve attributes with underscored keys converted to their HTML equivalents. This is useful for ensuring compatibility with HTML attribute naming conventions. ```python from ludic.html import div el = div("Content", class_="container", data_value="test") print(el.aliased_attrs) # {'class': 'container', 'data-value': 'test'} ``` -------------------------------- ### Define Element with Specific Children Type Source: https://github.com/getludic/ludic/blob/main/_autodocs/types.md Use TChildren to specify the exact type of children an Element can accept. This example shows an Element that only accepts string children. ```python from ludic.elements import Element from ludic.html import p # Element that accepts only string children class Paragraph(Element[str, GlobalAttrs]): html_name = "p" ``` -------------------------------- ### Create User Endpoint Source: https://github.com/getludic/ludic/blob/main/_autodocs/api-reference/web-responses.md Handles POST requests to create a new user, returning a component and a 201 Created status. ```APIDOC ## POST /users ### Description Handles POST requests to create a new user, returning a component and a 201 Created status. ### Method POST ### Endpoint /users ### Parameters #### Request Body - **request** (Request) - The incoming request object. ### Response #### Success Response (201) - **component** (div) - The HTML component indicating user creation. - **status_code** (int) - The HTTP status code, 201 for Created. ``` -------------------------------- ### URLType Protocol Usage Source: https://github.com/getludic/ludic/blob/main/_autodocs/api-reference/attrs.md Shows how to use the URLType protocol, allowing strings, pathlib.Path objects, or any custom object with a __str__ method to be used for URL attributes. ```python from pathlib import Path from ludic.html import a # str works link1 = a("Home", href="/") # Path works (has __str__) link2 = a("Home", href=Path("/")) # Custom objects work class Route: def __str__(self): return "/home" link3 = a("Home", href=Route()) ``` -------------------------------- ### Attribute Aliasing Example Source: https://github.com/getludic/ludic/blob/main/_autodocs/api-reference/attrs.md Demonstrates how underscores in Python attribute names are converted to dashes and trailing underscores are removed for HTML rendering. Use underscore names in your Python code. ```python from ludic.html import div, input_ el = div( input_( type="text", class_="form-control", hx_get="/search", data_value="test" ) ) print(el.to_html()) #
``` -------------------------------- ### Blank Constructor Source: https://github.com/getludic/ludic/blob/main/_autodocs/api-reference/elements.md A transparent wrapper that renders only its children without adding an element. Accepts no attributes and renders children directly. ```APIDOC ## Blank Constructor ### Description A transparent wrapper that renders only its children without adding an element. Accepts no attributes and renders children directly. ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Constructor Signature ```python def __init__(self, *children: TChildren) -> None ``` | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | `*children` | `TChildren` | No | Child nodes to render | ### Methods #### `to_html` Returns concatenated HTML of all children without wrapping tags. | Attribute | Type | Description | |-----------|------|-------------| | return | `str` | Concatenated HTML of children | ### Example ```python from ludic import Blank from ludic.html import div, p, b, i # Render multiple children without wrapping content = Blank( p("First paragraph"), p("Second paragraph"), ) print(content.to_html()) #

First paragraph

Second paragraph

# Useful in conditional rendering def render_optional(show: bool): if show: return Blank(b("Bold"), " and ", i("Italic")) return Blank() ``` ``` -------------------------------- ### Running Ludic App with Uvicorn Source: https://github.com/getludic/ludic/blob/main/skills/ludic-web/SKILL.md Command to run the Ludic web application using the Uvicorn ASGI server. Assumes the application is saved in a file named 'web.py'. ```bash uvicorn web:app ``` -------------------------------- ### Build Ludic Project Distributions Source: https://github.com/getludic/ludic/blob/main/_autodocs/configuration.md Command to build project distributions (e.g., wheels, sdists) using hatch. Version management is handled by hatch-vcs based on git tags. ```bash hatch build ``` -------------------------------- ### Define a custom Link component in Ludic Source: https://github.com/getludic/ludic/blob/main/README.md Create a reusable Link component by extending Ludic's Component class. This example demonstrates defining custom attributes and overriding the render method. ```python from typing import override from ludic import Attrs, Component from ludic.html import a class LinkAttrs(Attrs): to: str class Link(Component[str, LinkAttrs]): classes = ["link"] @override def render(self) -> a: return a( *self.children, href=self.attrs["to"], style={"color": self.theme.colors.primary}, ) ``` -------------------------------- ### Create Type-Safe Component with Ludic Source: https://github.com/getludic/ludic/blob/main/_autodocs/README.md Define a type-safe component using Ludic's Component and Attrs classes. This example shows how to create a Card component with a title attribute and render it with children. ```python # Type-safe component from ludic import Component, Attrs from ludic.html import div, h1 class CardAttrs(Attrs): title: str class Card(Component[str, CardAttrs]): @override def render(self) -> div: return div( h1(self.attrs["title"]), p(*self.children) ) ``` -------------------------------- ### Register OPTIONS Endpoint Source: https://github.com/getludic/ludic/blob/main/_autodocs/api-reference/web-app.md Use the `options` decorator to register a handler for OPTIONS requests. It accepts a URL path pattern and optional keyword arguments for additional configuration. ```python def options(self, path: str, **kwargs: Any) -> Callable[[TCallable], TCallable] ``` -------------------------------- ### Define Strict Element with Positional Children Source: https://github.com/getludic/ludic/blob/main/_autodocs/types.md Use TChildrenArgs with ElementStrict to define elements that require a specific sequence and number of children. This example creates an Article element expecting an h1 followed by a p. ```python from ludic.elements import ElementStrict from ludic.html import h1, p # Strict element with exactly two children: h1, then p class Article(ElementStrict[h1, p, GlobalAttrs]): html_name = "article" # Valid article = Article(h1("Title"), p("Content")) # Invalid (wrong types or order) article = Article(p("Title"), h1("Content")) # ✗ type error article = Article(h1("Title")) # ✗ type error (missing p) ``` -------------------------------- ### Activate Hatch Shell for Development Source: https://github.com/getludic/ludic/blob/main/CONTRIBUTING.md Activates a shell environment using Hatch, which automatically includes all optional dependencies needed for development and testing. ```bash hatch shell ``` -------------------------------- ### Set Default Theme Source: https://github.com/getludic/ludic/blob/main/_autodocs/api-reference/styles-theme.md Use `set_default_theme` to establish a global default theme. This is useful for creating custom design systems and applying them consistently across your application. Ensure `Theme`, `set_default_theme`, and `Colors` are imported. ```python from ludic.styles import Theme, set_default_theme, Colors # Create custom theme custom_theme = Theme( colors=Colors( primary=Color("#0066cc"), secondary=Color("#666666"), ) ) # Set as default set_default_theme(custom_theme) ``` -------------------------------- ### Define Element with Custom Children Type Variable Source: https://github.com/getludic/ludic/blob/main/_autodocs/types.md Create custom type variables for children to enforce specific types like strings or integers. This example defines a Counter element accepting string or integer children. ```python from ludic.elements import Element from ludic.html import p # Custom type variable MyChildren = TypeVar("MyChildren", str, int) class Counter(Element[MyChildren, GlobalAttrs]): html_name = "span" ``` -------------------------------- ### Import Ludic Styles Utilities Source: https://github.com/getludic/ludic/blob/main/_autodocs/module-exports.md Imports core classes and utilities for theme management, style definitions, and formatting from the ludic.styles module. ```python from ludic.styles import ( # Theme management Theme, get_default_theme, set_default_theme, # Theme components Colors, Fonts, Headers, Sizes, Borders, Rounding, Sidebar, Switcher, Cover, # Types CSSProperties, GlobalStyles, # Utilities format_styles, from_components, from_loaded, ) ``` -------------------------------- ### Integrate HTMX Attributes for Reactive UIs Source: https://github.com/getludic/ludic/blob/main/_autodocs/README.md Add HTMX attributes directly to elements to enable client-side interactivity without JavaScript. This example shows a button that triggers a POST request to an API endpoint and updates a target element. ```python button("Click", hx_post="/api/action", hx_target="#result") ``` -------------------------------- ### Define Border Widths Source: https://github.com/getludic/ludic/blob/main/_autodocs/api-reference/styles-theme.md Configure border widths using the `Borders` dataclass, providing predefined sizes for thin, normal, and thick borders. ```python from dataclasses import dataclass from ludic.styles import BaseSize, Size @dataclass class Borders: thin: BaseSize = Size(0.1) normal: BaseSize = Size(0.23) thick: BaseSize = Size(0.42) ``` -------------------------------- ### Run Mypy with uv Source: https://github.com/getludic/ludic/blob/main/CLAUDE.md Perform static type checking with Mypy using uv to manage the environment. Ensures Python 3.14 and necessary extras are available. ```bash uv run --python 3.14 --with ".[full,test]" mypy ludic ``` -------------------------------- ### Composable HTML Components in Python Source: https://github.com/getludic/ludic/blob/main/README.md Illustrates creating reusable and type-checked HTML components using Python classes and type system. This promotes modularity and dynamic properties like sorting or filtering. ```python Table( TableHead("Id", "Name"), TableRow("1", "John"), TableRow("2", "Jane"), TableRow("3", "Bob"), ) ```