From superpowers-sage
Integrates HTML Forms WordPress plugin with Sage via log1x/sage-html-forms for stateless contact/lead forms using Blade views, hf_get_form, ACF post objects, and progressive JS validation.
npx claudepluginhub codigodoleo/superpowers-sage --plugin superpowers-sageThis skill uses the workspace's default tool permissions.
Stateless form rendering via the HTML Forms WordPress plugin, bridged into Sage by `log1x/sage-html-forms`. Forms live as a CPT (`html-form`), are referenced from ACF blocks via `addPostObject`, and render through a Blade filter that routes to project-controlled form views.
Scaffolds new ACF Composer Gutenberg blocks in Sage themes with custom element architecture, scoped CSS, theme variations, block.json, Blade views, and JS lifecycle.
Develops WordPress themes using Sage framework: create from scratch, set up Blade templates/components, configure Vite/Bud builds, handle template hierarchy, integrate ACF fields, manage assets.
Guides Netlify Forms for serverless HTML form handling on static and JS-rendered sites. Covers setup with data-netlify, JS frameworks (React, Vue, Next.js), AJAX, file uploads, spam filtering, submissions API.
Share bugs, ideas, or general feedback.
Stateless form rendering via the HTML Forms WordPress plugin, bridged into Sage by log1x/sage-html-forms. Forms live as a CPT (html-form), are referenced from ACF blocks via addPostObject, and render through a Blade filter that routes to project-controlled form views.
| Approach | Best for |
|---|---|
| HTML Forms + sage-html-forms | Stateless contact/lead forms; editors pick the form from a dropdown; submissions handled by the HF plugin |
| Livewire form | Reactive state, multi-step wizards, inline validation tied to server state |
Blade + native <form> | Single-field or trivial forms with no submission pipeline |
acorn-livewire skill)<form> is simplerx-form.* components present in resources/views/components/form/ (the design-system form primitives)lando composer require wpackagist-plugin/html-forms
lando theme-composer require log1x/sage-html-forms
Acorn's package discovery auto-registers the service provider — no manual wiring. Full details: references/installation.md.
The form is a html-form CPT post. A block exposes an ACF addPostObject field scoped to that CPT so the editor picks the form. The block view renders it via hf_get_form($form->ID)->get_html(), which the sage-html-forms provider intercepts and routes to a Blade view at resources/views/forms/{form-slug}.blade.php. The Blade form view uses the project's x-form.* components.
{{-- Block view (snippet) --}}
@if ($form)
{!! hf_get_form($form->ID)->get_html() !!}
@endif
{{-- resources/views/forms/{form-slug}.blade.php --}}
<x-html-forms :form="$form">
<x-form.field label="Name" for="name" :required="true">
<x-form.input type="text" name="name" :required="true" minlength="2" />
</x-form.field>
{{-- ...more fields... --}}
<x-button type="submit" variant="primary" class="w-full">Send</x-button>
</x-html-forms>
Full walkthrough: references/blade-form-views.md.
Client-side validation is a reusable ES module imported by the block's JS — never globally enqueued. The module exposes one function:
initHfValidation(formEl, { messages, validators, onSuccess, onError });
Four layers: native HTML5 constraints, blur validation, input lazy re-validation while aria-invalid="true", and post-submit scroll via the HTML Forms plugin's DOM events (hf-success, hf-error, hf-submitted).
Full API and implementation: references/hf-validation.md.
Three documented bugs that silently break forms in this stack. Full symptom/root cause/fix for each: references/traps.md.
pattern attribute backslash escaping in Blade components. $attributes->merge() double-escapes backslashes; patternMismatch never fires. Symptom: form submits even though pattern regex doesn't match user input. Workaround: use a JS validator, not a pattern attribute.type="tel" skips patternMismatch in Chrome. Use type="text" inputmode="tel" instead. Symptom: phone format validator silently no-ops in Chrome (works in Firefox/Safari).ValidityState is non-enumerable. Spread ({ ...field.validity }) and Object.keys() return empty. Symptom: your error-message lookup object is always empty. Access named properties directly: validity.valueMissing, validity.patternMismatch, validity.tooShort, validity.customError, etc.| File | Role |
|---|---|
app/Blocks/{ClassName}.php | ACF block — addPostObject field + with() mapping |
resources/views/blocks/{slug}.blade.php | Block view — calls hf_get_form($form->ID)->get_html() |
resources/views/forms/{form-slug}.blade.php | Form view — x-html-forms + x-form.* structure |
resources/js/blocks/{slug}.js | Block custom element — imports initHfValidation, configures per form |
resources/js/modules/hf-validation.js | Reusable validation module (one per project, not per form) |
agents/forms.md (user-invocable specialist — analyzes and refactors existing forms, or scaffolds new ones)skills/block-scaffolding/SKILL.md Phase 0c (coordinated scaffold when a block embeds a form)Both consumers treat this skill as authoritative — no pattern, template, or trap is documented outside this skill.