Rat docs

Pups (components)

A pup is any .rat file under pups/. Its filename becomes a tag (pups/greeting.rat becomes the greeting tag). Its > server block defines defaults that callers can override via attrs, and its > page block is the markup. Attributes on the call site become local variables inside the pup body.

Define a pup

pups/greeting.rat

tagline is a server var with a default — any caller can override it by passing the attribute. Inside the body it reads like any other identifier.

> server
tagline: 'hello'

> page
<p class['greeting']> [tagline], friend.

Use the pup

Pass props as attrs

Call sites look like HTML tags. The attribute becomes the local variable inside the pup — tagline['nice to meet you'] inside the call seeds the pup's tagline for that instance.

> page
<greeting>
<greeting tagline['nice to meet you']>
<greeting tagline['welcome back, Ada']>
Result

hello, friend.

nice to meet you, friend.

welcome back, Ada, friend.

Children slot

<children> inlines caller markup

A pup that wraps content uses the children tag to splice in whatever the caller wrote between the open and close tags. The children evaluate in the caller's scope, so any [name] reads in there resolve against the page that invoked the pup — not the pup's own state.

# pups/card.rat
> page
<div class['card']>
    <header> Card
    <div class['card-body']>
        <children>

# somewhere in a page
<card>
    <h2> Hello
    <p> Anything goes here.

Pup with its own state

Reactive counter as a component

Pups can declare their own page-tier state and handlers — the framework rebinds each instance separately, so two counter tags on one page keep independent counts.

# pups/counter.rat
> page
count: 0
<button on_click[count++]> clicked [count] times

# in a page
<counter>
<counter>

Next: Services — singletons with state and methods you call as auth.login(u, p) from any page.