Jak renderują się sceny
Ta strona śledzi scenę od załadowania strony storefrontu do momentu zamontowania jej w DOM. Przydatna, gdy debugujesz “dlaczego mój popup się nie pojawia” albo projektujesz custom integrację motywu.
Footer hook
Dział zatytułowany „Footer hook”P2Lab Stage rozszerza jeden template Shopware: footer layoutu storefrontu. Plugin dodaje ukryty kontener kontekstu do istniejącego bloku layout_footer_inner_container:
{% sw_extends '@Storefront/storefront/layout/footer/footer.html.twig' %}
{% block layout_footer_inner_container %} {{ parent() }} {% if p2labStageContext %} <div data-p2lab-stage data-p2lab-stage-context="{{ context|json_encode }}" hidden></div> {% endif %}{% endblock %}Rozszerzenie p2labStageContext jest wypełniane przez subscribera nasłuchującego każdego ładowania strony storefrontu i obliczającego tożsamość bieżącej strony (typ strony, ID produktu / kategorii / producenta / strony CMS, URL żądania, skonfigurowany tryb GDPR, route URLs które plugin JS musi wywołać).
Żadne inne base templates nie są nadpisywane. Popupy nie są embedded w Twig — są pobierane client-side z /p2lab-stage/resolve.
Plugin JS
Dział zatytułowany „Plugin JS”P2LabStagePlugin jest zarejestrowany na selektor [data-p2lab-stage]. Na każdej stronie, gdzie ten kontener istnieje, PluginManager Shopware instancjuje plugin. Plugin następnie:
- Czyta
data-p2lab-stage-contextdo obiektu JS. - Czyta ID suppressed popupów z
sessionStorage/localStorage(zależnie od trybu GDPR — zobacz niżej). - POST-uje
/p2lab-stage/resolvez kontekstem strony + suppressed IDs. - Dla każdego zwróconego popupu planuje go zgodnie z triggerem.
Endpoint resolve
Dział zatytułowany „Endpoint resolve”POST /p2lab-stage/resolve robi ciężką robotę server-side.
Payload in
Dział zatytułowany „Payload in”{ "pageType": "product", "requestUrl": "/product/spring-jacket", "productId": "<uuid>", "productIds": [], "categoryId": "<uuid>", "manufacturerId": "<uuid>", "productStreamIds": [], "cmsPageId": null, "clientSuppressedIds": ["<popup-uuid-1>", "<popup-uuid-2>"]}Kanał sprzedaży i grupa klientów nie są wysyłane — są odczytywane server-side z SalesChannelContext, którego nie da się okłamać z klienta.
Pipeline filtrowania
Dział zatytułowany „Pipeline filtrowania”Server-side, plugin chodzi po każdej aktywnej scenie i stosuje te filtry w kolejności:
- Przełącznik Active + harmonogram w zakresie (
active_from/active_to). - Kanał sprzedaży match.
- Grupa klientów match (przeciwko grupie zalogowanego klienta, albo domyślnej grupie dla anonymous).
- Reguła ewaluacja (z
rule_operatorOR / AND). - Kategorie (z
includeChildrenper wiersz, uwzględniając ścieżkę kategorii). - Produkty / Producenci / Product streamy / Strony CMS matche.
- Typy stron + wzorce URL z
pages_operator. - Client-suppressed IDs (popupy, które klient mówi że już odrzucił w tej sesji).
- Server-side dismiss state (sesja PHP, gdy zgoda GDPR brakuje dla storage).
Przeżywające sceny są sortowane po priorytecie.
Display mode i limit per-sesja
Dział zatytułowany „Display mode i limit per-sesja”Pozostała lista jest następnie cap’owana przez ustawienia systemowe:
displayMode = only-first(domyślnie) — pozostaje tylko pierwsza (najwyższego priorytetu) scena; reszta jest dropowana dla tej strony.displayMode = queue— domaxPerSessionscen jest zachowane (albo wszystkie jeślimaxPerSession = 0).
Ten limit to optymalizacja bandwidth — klient też trackuje własny session-wide distinct-popup counter.
Payload out
Dział zatytułowany „Payload out”{ "popups": [ { "id": "<uuid>", "displayType": "modal", "triggerType": "delay", "triggerValue": 5, "frequencyType": "session", "closeButton": true, "overlayClose": true, "permanentDismissButton": false, "statsEnabled": true, "html": "<!-- pre-rendered stage HTML -->" } ], "displayMode": "only-first", "maxPerSession": 3}html jest pre-renderowany server-side z stage-content.html.twig — klient po prostu wstawia go do DOM. Pozycjonowanie / styling / dane animacji każdej warstwy żyją w atrybutach data-* do odczytu przez silniki JS.
Planowanie triggera
Dział zatytułowany „Planowanie triggera”Dla każdego popupu w odpowiedzi resolve:
immediate→ zamontuj od razu.delay→setTimeout(triggerValue × 1000)potem montuj.scroll→ listener scrolla nawindow, odpala przy progu, usuwa się.
Gdy trigger się odpali, popup jest dopinany do document.body, animacja wejścia uruchamia się, silniki parallax / animacji / countdown / coupon się podpinają, a event impression jest wysyłany.
Tracking eventów
Dział zatytułowany „Tracking eventów”Podczas gdy popup jest zamontowany, klient wysyła eventy impression / CTA-click / close / permanent-dismiss do POST /p2lab-stage/track:
{ "popupId": "<uuid>", "eventType": "impression", "pageType": "product", "requestUrl": "/product/spring-jacket"}Jeśli statsEnabled jest false na scenie, serwer silently no-opuje (defensive backstop — klient już pomija większość wywołań).
Przy odrzuceniu klient wywołuje też POST /p2lab-stage/dismiss, żeby zapisać suppression server-side (sesja PHP — przydatne gdy client storage jest niedostępny):
{ "popupId": "<uuid>", "frequencyType": "session", "frequencyValue": null }Nieznane typy częstotliwości fallback na session, żeby misbehaving klient nie zapisał arbitralnych stringów.
Przy zmianie zgody (odwiedzający akceptuje cookies po server-dismiss popupa) klient wywołuje GET /p2lab-stage/dismissed, żeby pobrać listę server-side suppression i zmigrować do client storage.
CMS slider sceny
Dział zatytułowany „CMS slider sceny”Sceny slider nie używają pipeline’u resolve. Element CMS p2lab-stage-slider renderuje się inline przez normalny pipeline Shopping Experiences Shopware — partial Twig slidera jest częścią odpowiedzi HTML strony. Plugin JS slidera (P2LabStageSliderPlugin, zarejestrowany na [data-p2lab-stage-slider]) obsługuje autoplay, transitiony, swipe, kropki, strzałki.
Cachowanie
Dział zatytułowany „Cachowanie”Każdy route storefrontu w pluginie jest oznaczony _httpCache: false — resolve / track / dismiss / dismissed nie mogą być HTTP-cachowane, bo ich odpowiedzi różnią się per sesja, klient i stan częstotliwości. Sam template footera zostaje cachowalny, bo emituje tylko statyczny kontener kontekstu; faktyczne dane sceny są pobierane dynamicznie.
Gdzie dalej
Dział zatytułowany „Gdzie dalej”- Parallax myszy — szczegóły silnika parallax.
- Customizacja CSS — co nadpisać i jak.
- GDPR i storage — gdzie faktycznie żyje stan suppression.
- Analityka → Eventy — co rejestruje każdy event.