htmx-patterns-contract
| ID |
14 |
| UUID |
a1b2c3d4-htmx-1234-5678-abcdef123456 |
| Version |
1.0 |
| Status |
active |
| Scope |
HTMX-Nutzung in View-Templates - einheitliche Patterns, CSRF, Confirmations |
| Erstellt |
2025-12-27 11:29:38 von claude |
| Aktualisiert |
2025-12-27 11:51:56 |
YAML-Inhalt
contract:
name: htmx-patterns
version: "1.2"
description: |
Regeln fuer konsistente HTMX-Nutzung in View-Dateien.
Automatisch validiert durch pre_rules_htmx.py Hook.
enforcement:
hook: quality/pre_rules_htmx.py
level: pre-hook (BLOCK)
scope: /src/View/**/*.php
rules:
critical:
- id: HTMX-C1
name: csrf-on-post
check: hx-post MUSS X-CSRF-TOKEN in hx-headers haben
example: hx-headers='{"X-CSRF-TOKEN": "<?= $csrfToken ?>"}'
- id: HTMX-C2
name: csrf-on-delete
check: hx-delete MUSS X-CSRF-TOKEN in hx-headers haben
- id: HTMX-C3
name: csrf-on-patch
check: hx-patch MUSS X-CSRF-TOKEN in hx-headers haben
- id: HTMX-C4
name: delete-requires-confirm
check: hx-delete MUSS hx-confirm Attribut haben
example: hx-confirm="Wirklich loeschen?"
- id: HTMX-C5
name: csrf-on-put
check: hx-put MUSS X-CSRF-TOKEN in hx-headers haben
added: 2025-12-27 (nach Bug in Task #443)
- id: HTMX-C6
name: controller-error-handling
check: Controller MUSS htmxError() fuer Fehler nutzen
note: htmxError() sendet HX-Retarget zu #htmx-messages
recommended:
- id: HTMX-R1
name: no-fetch-for-simple-post
severity: major
check: Einfache POST-Aktionen SOLLTEN HTMX statt fetch() verwenden
- id: HTMX-R2
name: no-inline-onclick-for-ajax
severity: major
check: Keine onclick-Handler fuer AJAX, HTMX verwenden
- id: HTMX-R3
name: use-hx-indicator
severity: major
check: hx-indicator Attribut MUSS gesetzt sein wenn Loading-State gewuenscht
note: Nur .htmx-indicator Klasse reicht NICHT
- id: HTMX-R4
name: use-hx-disabled-elt
severity: minor
check: hx-disabled-elt gegen Doppelklicks verwenden
infrastructure:
layout:
file: /src/View/layout.php
container: <div id="htmx-messages" class="htmx-messages" aria-live="polite"></div>
css:
file: /public/css/admin.css
classes:
- .htmx-indicator (hidden by default)
- .htmx-request .htmx-indicator (shown during request)
- .htmx-request .htmx-content (hidden during request)
- .htmx-messages (fixed position, top-right)
controller_helpers:
htmxAlert: Sendet Alert mit HX-Retarget zu #htmx-messages
htmxError: Wrapper fuer htmxAlert('error', ...)
htmxSuccess: Wrapper fuer htmxAlert('success', ...)
htmxRedirect: Sendet HX-Redirect Header
isHtmxRequest: Prueft HTTP_HX_REQUEST Header
patterns:
action_with_redirect:
description: Aktion mit Server-Redirect (empfohlen)
view: |
<button hx-post="/endpoint"
hx-headers='{"X-CSRF-TOKEN": "<?= $csrfToken ?>"}'
hx-swap="none"
hx-disabled-elt="this">
Action
</button>
controller: |
if ($this->isHtmxRequest()) {
if (!$result->success) {
$this->htmxError($result->message);
return;
}
$this->htmxRedirect('/target');
return;
}
form_with_indicator:
description: Form mit Loading-Indicator
view: |
<form hx-put="/api/endpoint"
hx-headers='{"X-CSRF-TOKEN": "<?= $csrfToken ?>"}'
hx-target="#result"
hx-indicator="#submit-btn"
hx-disabled-elt="#submit-btn">
<button type="submit" id="submit-btn">
<span class="htmx-indicator">Laden...</span>
<span class="htmx-content">Speichern</span>
</button>
</form>
delete_with_confirm:
description: Delete mit Bestaetigung
template: |
<button hx-delete="/item/123"
hx-confirm="Wirklich loeschen?"
hx-headers='{"X-CSRF-TOKEN": "<?= $csrfToken ?>"}'
hx-target="closest tr"
hx-swap="outerHTML swap:1s">
Loeschen
</button>
Aktionen
← Zurück zur Übersicht