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

Bearbeiten

← Zurück zur Übersicht