Alpine on a PAD page
Alpine reads attributes, PAD writes them. Both love braces - so give each its own, hand Alpine its state as JSON, and let it talk back to the page that wrote it.
1. The braces
PAD reads every { of a template as the start of a tag; Alpine writes objects
with them. Three ways that never collide:
State from PHP
The ^ sigil writes a field as JSON, escaped for the attribute - x-data="{^profile}".
No brace of Alpine's in the template, and a quote in a value stays text.
Components in a file
Alpine.data('tabs', ...) in a script of www/, called by name:
x-data="tabs({^tabs})" - the file never meets the PAD parser.
A space after the brace
x-data="{ open: false }" written as { open: false } -
a brace with a space after it is no PAD tag. It works for a short object; prefer the other two.
2. Load order
The application's scripts first, Alpine last and deferred - a page's components register
themselves on alpine:init before Alpine walks the page:
<script src="alpine-app.js"></script> <!-- pad.get, pad.post -->
<script defer src="https://unpkg.com/alpinejs@3/dist/cdn.min.js"></script>
...
<script src="examples/search.js"></script> <!-- Alpine.data('search', ...) -->
3. Talking back
A page answers JSON when asked - ?page&padFormat=json - with only what its PHP
names in $padExpose; the templates do not run for it. A post carries the session's
token in a header, read from <meta name="csrf-token" content="{csrf token}">:
const answer = await pad.get('examples/search', { q: this.q }); // the JSON of $padExpose
const saved = await pad.post('examples/todos', { op: 'add', text }); // X-CSRF-Token sent
4. One set of rules
Keep a form's rules in PHP: padValidate ( $rules ) checks the post,
padValidateClient ( $rules ) hands them to the component, {validator} brings the
checker, and padValidate.field ( rules.email, value, form ) answers in the server's
words.
5. Events from the server
padSse() streams JSON events; an EventSource opened in
x-init - in a component that closes it again in destroy() - turns them
into state.
Values are text: whatever a visitor typed, the ^ sigil writes it as JSON escaped for the attribute,
and x-text puts it in as text. Avoid x-html with data that is not yours.