3.6 KiB
FDMTech — interfejs PHP dla projektanta (v1)
Projektant jest właścicielem templates/layout.php, templates/home.php, public/assets/css/site.css, public/assets/js/site.js i logo. Renderer nie edytuje tych plików. PHP 8.2+, bez frameworka. public/ jest document root.
Zmienne w obu szablonach
$site: tablicaname,contact_email,contact_phone,navigation(lista{label, url}). Puste dane kontaktowe są dozwolone, nie wymyślamy adresów.$page:slug,title,seo_title,seo_description,published_html,published_css,published_at(string/null). Tylko opublikowane dane.$meta:title,description,canonical(pełny URL lub pusty),robots.$isDemo: bool. Demo należy oznaczyć widocznym komunikatem „Tryb demonstracyjny — formularz nie wysyła zgłoszeń”.$csrfToken: string;$formAction:/inquiries;$formValues: name/email/company/phone/message/consent;$formErrors: mapa błędów;$formNotice: string lub null, sukces mówi wyłącznie o zapisie;$formStatus:idle|invalid|saved|unavailable|limited;$smtpStatus:disabled.$statusCode: HTTP status;$nonce: nonce CSP, jeśli potrzebny dla zaufanego lokalnego skryptu. Skrypty lokalne zdefersą dozwolone; inline wymagają nonce.$e($value): HTML/attribute escaping. Wszystkie teksty, atrybuty, meta i URL wyświetlać przez$e. Tylko$content,$cmsHtmli$cmsStyleTagsą gotowym bezpiecznym HTML.$cmsHtml: przefiltrowany fragment publikacji;$cmsStyleTag: gotowy element style z nonce i CSS ograniczonym do#cms-content(albo pusty).
Sposób renderowania
templates/home.php jest używany tylko w jawnym demo na / jako zaprojektowana strona pokazowa. Produkcyjna strona główna pochodzi z publikacji slug home, tak jak pozostałe strony. Aplikacja buduje $content jako <main id="cms-content">…</main> zawierający treść publikacji. W demo na / zawartość home.php trafia do tego samego main: szablon home nie dodaje własnego main ani ID cms-content.
templates/layout.php otrzymuje $content i tworzy cały dokument: head (escaped SEO, canonical, robots, $cmsStyleTag, CSS), globalny header/nav, <?= $content ?>, footer, lokalny JS. Nawigacja i kontakt pochodzą z $site. Nie umieszczać URL panelu Sensory. layout.php jest używany także dla błędów i formularza.
Formularz aplikacji dostępny pod /kontakt (trasa zarezerwowana, zawsze działa bez JS); linki CTA można kierować na /kontakt. Własny formularz w home: POST $formAction, hidden _csrf=$csrfToken, hidden source=home, pola name, email, opcjonalne company, phone, message, checkbox consent=1 wymagany. Honeypot website ma pozostać pusty (ukryty, tabindex=-1, autocomplete=off). Błędy walidacji wracają na stronę formularza z kodem 422 i zachowanymi wartościami; po zapisie jest 303 do /kontakt, notice jednokrotny. Demo POST zwraca 503, nigdy fikcyjny sukces.
Jawne demo i brak szablonów
APP_DEMO=true w środowisku/.env uruchamia dane demonstracyjne bez łączenia z DB. Domyślnie false. Demo otrzymuje noindex, nofollow. Awaria DB w produkcyjnym trybie zawsze zwraca 503. Brak home.php: semantyczna strona demo aplikacji. Brak layout.php: techniczny dokument HTML z globalną nawigacją i stopką z app/View.php, bez prac nad stylistyką.
Zasoby lokalne /assets/.... CSP blokuje skrypty publikacji, inline event handlers, zewnętrzne skrypty, iframes i obiekty. Obrazy HTTPS są dopuszczone (media CMS muszą być publicznie dostępne). Nie używać inline style w home; CSS projektanta pozostaje w site.css.