The server renders.
htmx swaps it in.
htmx asks the server for a part of the page and puts the answer where it belongs. PAD already speaks that language: every {fragment} of a template can be asked for alone - by its name, or by the element htmx swaps - so one template serves the whole page and every piece of it.
<input name="q" hx-get="?products"
hx-trigger="input changed delay:300ms"
hx-target="#results">
<ul id="results">
{fragment 'results'}
{products}<li>{$name}</li>{/products}
{/fragment}
</ul>
The request carries HX-Target: results; PAD answers that fragment alone.
Parts of a page
2 exampleshtmx asks for a part, PAD answers just that part: a {fragment} of the same template, picked by the element htmx swaps. One template for the whole page and for every piece of it.
Active search
The results update as you type. htmx asks the page again with hx-target="#results"; PAD answers the {fragment 'results'} of the same template - the element's name is enough.
{fragment}HX-Targethx-gethx-trigger delayhx-push-urlLazy loading
The page arrives at once; the slow part - a chart PAD draws - is asked for when the page has loaded, and a skeleton stands in until it comes.
{fragment}{chart}hx-gethx-trigger="load"Changing data
3 examplesPosts, edits and carts - the server keeps the state and answers the HTML that shows it, CSRF token and validation included.
Inline editing
A row turns into a form and back. Each answer is one row of the same loop - the PHP narrows the rows to the one asked for, padValidate checks the post, the session keeps the edits.
padValidatepadSession&padFragment=rowhx-gethx-posthx-includehx-target="closest tr"Forms without reloads
A {form} with rules= posts through htmx and comes back as its own fragment - refilled with PAD's messages, or as a thank-you. The same rules are checked in the browser first.
{form client}rules=padPostedhx-posthx-swap="outerHTML"Out-of-band updates
One answer, two places: the button that was pressed gets its new state, and the cart badge in the header updates too, swapped by its id with hx-swap-oob.
{fragment}padSessionhx-posthx-swap-oobFrom the server
2 examplesParts that come by themselves: after the page, as you scroll, or pushed by the server as events.
Infinite scroll
The last row asks for the next page when it scrolls into view and replaces itself with it - a fragment of rows that ends with the next asker.
{fragment}&padFragment=rowshx-trigger="revealed"hx-swap="outerHTML"Server-sent events
The server pushes HTML: padSse sends a rendered row every second, and htmx's sse extension swaps each one into the page as it arrives.
padSsehx-ext="sse"sse-swapsse-close