SW Shopware 6 Średnio zaawansowany

DfCustomCodeManager: kompletny przewodnik

Instalacja, konfiguracja i eksploatacja DfCustomCodeManager: wbudowany edytor kodu, kontenery wielokanałowe, dziedziczenie zmiennych motywu, historia 5 wersji, safe mode i biblioteka 8 presetów dla Shopware 6.6 i 6.7.

Zaktualizowano Wersja modułu 1.0.0

DfCustomCodeManager daje prostą odpowiedź na uniwersalny problem sklepów Shopware: gdzie umieszczać, jak wersjonować i jak zabezpieczać własny CSS i JavaScript, który prędzej czy później zawsze trafia do motywu? Plugin oferuje edytor kodu wbudowany w administrację, system kontenerów grupujących snippety SCSS lub JavaScript, a przede wszystkim bezpośrednie wstrzykiwanie do kompilacji motywu przez natywne zdarzenia Shopware. Skutek: żadnego dodatkowego serwowanego pliku, żadnego dodatkowego żądania HTTP dla odwiedzającego, a Twoje snippety SCSS automatycznie dziedziczą zmienne i mixiny aktywnego motywu. Ten przewodnik obejmuje instalację, konfigurację, tworzenie kontenerów i snippetów, kompilację motywu, historię wersji, safe mode, bibliotekę presetów, import/eksport i rozwiązywanie problemów.

Instalacja

  1. Pobierz archiwum DfCustomCodeManager-1.0.0.zip ze swojego panelu DataFirefly.
  2. Zainstaluj je przez Administracja → Rozszerzenia → Moje rozszerzenia → Prześlij rozszerzenie albo rozpakuj katalog DfCustomCodeManager do custom/plugins/.
  3. Uruchom instalację i aktywację:
    bin/console plugin:refresh
    bin/console plugin:install --activate DfCustomCodeManager
    bin/console cache:clear
  4. Przy instalacji plugin tworzy swoje 4 tabele (df_ccm_container, df_ccm_container_sales_channel, df_ccm_snippet, df_ccm_snippet_version) i rejestruje subscribery zdarzeń kompilacji motywu.
  5. Przekompiluj motyw, aby uwzględnił plugin:
    bin/console theme:compile

Zgodny z Shopware 6.6.x i 6.7.x na jednym kodzie (composer ^6.6.0 || ^6.7.0). Moduł administracji jest prekompilowany, żaden build nie jest potrzebny. Wymagane PHP 8.2+. Kompilacja SCSS opiera się na scssphp/scssphp, dostarczanym już przez shopware/storefront. Żadnych dodatkowych zależności Composera.

Gdzie znaleźć plugin w administracji

Po aktywacji w menu Katalogi administracji pojawia się pozycja Custom Code Manager (pomarańczowa ikona, pozycja 100). To ekran centralny: lista kontenerów, wyszukiwanie, filtry oraz akcje globalne Importuj, Eksportuj, Presety i Kompiluj motyw. Cała konfiguracja niskopoziomowa (safe mode, minify, banner) odbywa się w Rozszerzenia → Moje rozszerzenia → DfCustomCodeManager → ⋯ → Konfiguruj.

Jeśli pozycja nie pojawia się po aktualizacji, uruchom bin/console assets:install && bin/console cache:clear, a następnie przeładuj administrację z wymuszonym odświeżeniem (Ctrl+Shift+R).

Konfiguracja pluginu

Karta konfiguracji pluginu Shopware udostępnia trzy proste, ale kluczowe przełączniki:

  • Safe mode (DfCustomCodeManager.config.safeMode): domyślnie wyłączony. Po włączeniu wszystkie kontenery są ignorowane przy następnej kompilacji, tak jakby były nieaktywne. To siatka bezpieczeństwa opisana niżej.
  • Minify JS (DfCustomCodeManager.config.minifyJs): podstawowa minifikacja wstrzykiwanego JavaScriptu. Przydatna w produkcji, w developmencie zostaw wyłączoną, aby móc czytać snippety w skompilowanym bundlu.
  • Dodaj banner (DfCustomCodeManager.config.addBanner): dodaje komentarz /* DataFirefly Custom Code Manager */ na początku wstrzykiwanego kodu. Praktyczne do szybkiego namierzania swoich snippetów w skompilowanym bundlu.

Model mentalny: kontenery i snippety

Plugin jest zorganizowany na dwóch poziomach:

  • Kontener to grupowanie logiczne: Promocja lato 2026, GTM analytics, Dark mode opt-in, Test A/B przycisku CTA… Każdy kontener ma nazwę, opis, priorytet, przełącznik aktywny/nieaktywny i zakres per kanał sprzedaży.
  • Snippet to jednostka kodu wewnątrz kontenera. Typ SCSS lub JavaScript, nazwa, kod, priorytet, przełącznik aktywny/nieaktywny, notatki Markdown oraz przełącznik włączający wstrzykiwanie zmiennych motywu.

Kontener może zawierać wiele snippetów mieszanych typów. To przydatne do logicznego grupowania snippetów, które idą w parze: na przykład kontener Dark mode opt-in ze snippetem SCSS dla stylów i snippetem JavaScript dla przełączania klasy na html.

Utworzenie pierwszego kontenera

  1. Z poziomu Katalogi → Custom Code Manager kliknij Nowy kontener w prawym górnym rogu.
  2. Nadaj mu wymowną nazwę (np. Promocja lato 2026: sticky header i badge).
  3. Ustaw priorytet (domyślnie zostaw 0, podnieś wartość, jeśli chcesz, żeby kontener był wstrzykiwany później w bundlu i tym samym nadpisywał inne style).
  4. (Opcjonalnie) Włącz Ogranicz do kanałów sprzedaży i wybierz jeden lub kilka kanałów. Gdy opcja jest wyłączona, kontener obowiązuje na wszystkich kanałach.
  5. Uzupełnij opis (notatki wewnętrzne, kontekst, powiązany ticket); nigdy nie trafi on do bundla.
  6. Zapisz. Możesz teraz dodawać snippety.

Dodanie snippeta SCSS lub JavaScript

Na karcie Fragmenty kodu strony kontenera są dwa przyciski: Dodaj SCSS i Dodaj JavaScript. Każdy dodany snippet pojawia się jako karta z:

  • Plakietką SCSS (info) lub JS (warning).
  • Polem nazwy (widocznym tylko w edycji).
  • Przełącznikiem aktywny/nieaktywny.
  • Przyciskiem Waliduj składnię (✓).
  • Przyciskiem Historia (zegar), dostępnym od pierwszego zapisu.
  • Przyciskiem Duplikuj.
  • Przyciskiem Usuń.
  • Edytorem kodu z kolorowaniem składni dopasowanym do typu.
  • Strefą Notatki w Markdown do dokumentowania działania snippeta.

Edytor kodu natywnie korzysta z komponentu mt-code-editor wprowadzonego w Shopware 6.7 (opartego na Meteor). Na Shopware 6.6 plugin automatycznie przełącza się na sw-code-editor (dawny komponent oparty na Ace). W ostateczności (komponent niedostępny) przejmuje textarea w foncie monospace, bez kolorowania składni, ale w pełni funkcjonalny.

Kompilacja motywu

Zapisany snippet nie jest jeszcze widoczny w storefroncie, dopóki motyw nie zostanie przekompilowany. Dwa sposoby:

  • Z administracji, przycisk Kompiluj motyw (w prawym górnym rogu listy albo na stronie kontenera). Powiadomienie potwierdza zakończenie operacji.
  • Z wiersza poleceń:
    bin/console theme:compile

Przy kompilacji plugin nasłuchuje trzech zdarzeń Shopware i wstrzykuje w nie Twoje snippety:

  • ThemeCompilerEnrichScssVariablesEvent: przechwytuje mapę zmiennych SCSS aktywnego motywu. To dzięki temu Twoje snippety SCSS mogą używać $sw-color-brand-primary, $font-family-base itd.
  • ThemeCompilerConcatenatedStylesEvent: dokleja Twój skompilowany SCSS na końcu głównego arkusza stylów.
  • ThemeCompilerConcatenatedScriptsEvent: dokleja Twój JavaScript na końcu głównego bundla skryptów.

Rezultat: zero dodatkowych żądań HTTP serwowanych odwiedzającemu, Twój kod przechodzi przez cały łańcuch optymalizacji Shopware (konkatenacja, minifikacja, fingerprinting cache).

Dziedziczenie zmiennych i mixinów motywu

Domyślnie każdy snippet SCSS korzysta z automatycznego preambułu zawierającego wszystkie zmienne i wszystkie mixiny udostępniane przez aktywny motyw i jego pluginy motywu. Możesz więc pisać w snippecie:

.header {
    background: $sw-color-brand-primary;
    font-family: $font-family-base;
    transition: $transition-base;
}

…nic nie importując ręcznie, dokładnie jak w pliku SCSS motywu. Jeśli z jakiegoś szczególnego powodu (konflikt zmiennej, snippet samowystarczalny) chcesz wyłączyć to dziedziczenie na konkretnym snippecie, odznacz przełącznik Zmienne motywu dostępne w stopce karty snippeta.

Zakres wielokanałowy

Na karcie Zakres i kanały kontenera włącz Ogranicz do kanałów sprzedaży i wybierz właściwe kanały. Kontener będzie wtedy wstrzykiwany tylko w kompilacjach motywu dla tych kanałów. Bardzo przydatne dla:

  • Banera promocyjnego zarezerwowanego dla sklepu marki drugorzędnej.
  • Skryptu trackingowego specyficznego dla rynku.
  • Testu A/B na jednym kanale w celu zmierzenia efektu.

Priorytet ładowania

Priorytet to liczba całkowita (domyślnie 0), która kontroluje kolejność wstrzykiwania w skompilowanym bundlu: im wyższa wartość, tym później kod jest wstrzykiwany, a więc tym łatwiej może nadpisać to, co go poprzedza. Priorytet istnieje na dwóch poziomach:

  • Na poziomie kontenera: kolejność między kontenerami.
  • Na poziomie snippeta: kolejność między snippetami wewnątrz tego samego kontenera.

Kolejność finalna to: (priorytet kontenera, priorytet snippeta) rosnąco. Prosta rada: domyślnie zostaw wszystko na 0 i używaj priorytetu tylko wtedy, gdy naprawdę musisz coś nadpisać.

Historia wersji

Przy każdym zapisie snippeta plugin automatycznie tworzy wersję w tabeli df_ccm_snippet_version. Zachowywanych jest 5 ostatnich wersji per snippet (najstarsza jest usuwana po osiągnięciu progu). Aby przejrzeć i przywrócić wersję:

  1. Na karcie snippeta kliknij ikonę Historia (zegar).
  2. Otwiera się okno modalne z listą wersji, datą, autorem, komentarzem i podglądem.
  3. Kliknij Przywróć po prawej stronie wybranej wersji; kod snippeta zostaje natychmiast zastąpiony kodem tej wersji. Powstaje nowa wersja dokumentująca przywrócenie.
  4. Zapisz kontener i przekompiluj, aby zobaczyć efekt.

Dla dłuższych historii pełny rejestr pozostaje w tabeli df_ccm_snippet_version (stare wersje są jedynie ukrywane w oknie). Deweloper może bardzo łatwo zwiększyć VersionTracker::MAX_VERSIONS_PER_SNIPPET, jeśli trzeba.

Safe mode: awaryjna siatka bezpieczeństwa

Safe mode to globalny przełącznik w konfiguracji pluginu. Włączony sprawia, że wszystkie kontenery są ignorowane przy następnej kompilacji, bez modyfikowania jakichkolwiek danych. Typowy scenariusz:

  1. Źle przetestowany snippet psuje coś na produkcji o 22:00.
  2. Wejdź w Rozszerzenia → Moje rozszerzenia → DfCustomCodeManager → ⋯ → Konfiguruj.
  3. Włącz przełącznik Safe mode i zapisz.
  4. Przekompiluj motyw: bin/console theme:compile.
  5. Storefront wraca do stanu natywnego (bez żadnego wstrzykniętego snippeta). Możesz teraz spokojnie namierzyć i poprawić winny snippet.
  6. Po poprawce wyłącz safe mode i przekompiluj ponownie.

Safe mode to narzędzie awaryjne, nie tryb pracy. Po rozwiązaniu incydentu pamiętaj o jego wyłączeniu, inaczej żaden z Twoich kontenerów nie będzie wstrzykiwany.

Biblioteka presetów

Przycisk Presety (z listy kontenerów) otwiera bibliotekę 8 kontenerów gotowych do instalacji jednym kliknięciem:

  • Sticky header: nagłówek zmieniający się przy scrollu (klasa is-sticky dodawana powyżej progu).
  • Back to top: przycisk powrotu na górę, widoczny od pewnego scrolla.
  • Cookie banner skin: przeskórkowanie natywnego banera cookies pod Twoją identyfikację wizualną.
  • Product badge, Nowość: plakietka “Nowość” na niedawno utworzonych produktach.
  • Free shipping bar: pasek postępu darmowej dostawy u góry strony.
  • Rounded buttons: zaokrąglone przyciski w całym sklepie.
  • GTM DOM-ready event: wyzwala niestandardowe zdarzenie po gotowości DOM, aby zainicjować Twoje data layers.
  • Fade-in on scroll: stopniowe pojawianie się elementów przy scrollu.

Kliknięcie Zainstaluj tworzy kontener i jego snippety w bazie. Pozostaje tylko przekompilować motyw, aby zobaczyć je online. Kontenery utworzone z presetu są kontenerami jak każde inne: możesz je edytować, rozbudowywać, dezaktywować, usuwać.

Import / Eksport JSON

Aby migrować snippety między środowiskami (dev, staging, produkcja) lub między sklepami:

  1. Eksport: zaznacz jeden lub kilka kontenerów na liście (checkboxy), a następnie kliknij Eksportuj. Pobierany jest plik JSON zawierający wszystkie wybrane kontenery z ich snippetami, priorytetem, notatkami oraz numerem wersji formatu (EXPORT_VERSION = 1) dla wstecznej kompatybilności.
  2. Import: na środowisku docelowym kliknij Importuj i wybierz plik JSON. Kontenery i snippety są odtwarzane identycznie.

Import nie dotyka istniejących kontenerów (brak scalania po nazwie): zawsze tworzy nowe wpisy. Jeśli chcesz nadpisać istniejący kontener, usuń go ręcznie przed importem.

Walidacja składniowa

Przycisk ✓ Waliduj składnię na każdej karcie snippeta uruchamia walidację po stronie serwera, niczego nie zapisując. Zależnie od typu:

  • SCSS: plugin wykonuje kompilację na sucho przez scssphp/scssphp, wstrzykując preambułę zmiennych motywu. Jeśli kompilacja przechodzi, snippet jest poprawny. W przeciwnym razie błędy trafiają do strefy błędów na karcie (numer linii, komunikat).
  • JavaScript: plugin oczyszcza kod z łańcuchów i komentarzy, a następnie sprawdza równowagę klamer {}, nawiasów () i nawiasów kwadratowych []. Ta kontrola nie zastępuje prawdziwego parsera ECMAScript, ale łapie 90% błędów kopiuj-wklej (zapomniana klamra, źle domknięty łańcuch). Aby pójść dalej, zwaliduj swój JavaScript w dedykowanym narzędziu przed wklejeniem.

Architektura techniczna

Dla deweloperów, którzy chcą zrozumieć lub rozszerzyć plugin:

  • Główny namespace PHP: DataFirefly (pod-namespace: CustomCodeManager, klasy w src/).
  • Klasa pluginu: DfCustomCodeManager (rozszerza Shopware\Core\Framework\Plugin).
  • Prefiks SystemConfig: DfCustomCodeManager.config.*.
  • Tabele: df_ccm_container, df_ccm_container_sales_channel, df_ccm_snippet, df_ccm_snippet_version.
  • Migracje: Migration1779580800CreateCcmContainerTable, Migration1779580801CreateCcmSnippetTable, Migration1779580802CreateCcmSnippetVersionTable.
  • Serwisy: CodeCompiler (orkiestracja + cache), SnippetExporter (import/eksport JSON), SnippetValidator (walidacja składniowa), VersionTracker (snapshot + restore + trim).
  • Subscribery: ThemeCompilerSubscriber (3 zdarzenia kompilacji), SnippetWrittenSubscriber (automatyczny snapshot przy zapisie).
  • Prywatne trasy API pod /api/_action/df-ccm/ (scope api): validate, export, import, restore-version, recompile, presets.

Wszystkie deklaracje serwisów są jawne w services.xml (bez autowiringu), zgodnie z konwencjami DataFirefly.

Rozszerzanie modułu administracji

Moduł administracji jest skompilowany i umieszczony w Resources/public/administration/js/df-custom-code-manager.js. Jest prekompilowany w ZIP-ie i nie wymaga żadnego lokalnego builda. Aby go rozszerzyć, rozłóż komponenty (df-ccm-list, df-ccm-detail, df-ccm-snippet-card, df-ccm-code-field, df-ccm-preset-modal, df-ccm-version-modal) i dostosuj przez standardowy system override’ów Shopware (Component.override).

FAQ i rozwiązywanie problemów

Moje snippety nie pojawiają się w storefroncie. Czy przekompilowano motyw? Dopóki theme:compile nie zadziała po modyfikacji, nic się nie zmienia. Sprawdź też, czy kontener i snippet są aktywne, czy dany kanał sprzedaży mieści się w zakresie (jeśli zakres jest ograniczony) i czy safe mode nie jest włączony.

Błąd kompilacji SCSS w konsoli po theme:compile. Najczęściej to zmienna motywu, która nie istnieje (literówka), albo snippet SCSS otwierający blok bez jego domknięcia. Wyłącz podejrzany snippet, przekompiluj dla potwierdzenia, a potem popraw na spokojnie. Walidacja składniowa na karcie snippeta łapie większość takich przypadków przed zapisem.

Menu Custom Code Manager nie pojawia się w administracji. Uruchom bin/console assets:install && bin/console cache:clear, a następnie przeładuj administrację z Ctrl+Shift+R. Moduł jest w grupie Katalogi.

Edytor kodu pokazuje textarea bez kolorowania. To fallback, gdy ani mt-code-editor (6.7), ani sw-code-editor (6.6) nie są dostępne. Sprawdź wersję Shopware i czy moduł administracji jest poprawnie załadowany.

Chcę tymczasowo wyłączyć wszystkie snippety, niczego nie usuwając. Dokładnie do tego służy safe mode. Przełącznik w konfiguracji pluginu, rekompilacja, gotowe.

Przycisk “Kompiluj motyw” kręci się w nieskończoność. Sprawdź logi Shopware. Kompilacja może trwać dłużej na dużym motywie; przy rzeczywistej blokadzie typową przyczyną jest snippet SCSS, który się zapętla albo zawiera nieznaną zmienną. Włącz safe mode, przekompiluj, a potem włączaj snippety jeden po drugim, aby namierzyć winowajcę.

Mój snippet JavaScript się nie uruchamia. Pamiętaj, że wstrzyknięty kod wykonuje się w globalnym bundlu, a więc w innym kontekście niż klasyczne pluginy Shopware. Aby wchodzić w interakcję z pluginami JavaScript storefrontu, nasłuchuj raczej document.addEventListener('DOMContentLoaded', …) lub globalnych zdarzeń emitowanych przez storefront.

Co dzieje się przy odinstalowaniu? Podczas plugin:uninstall Shopware wyświetla standardowy checkbox Zachowaj dane użytkownika. Jeśli jest odznaczony, plugin usuwa swoje 4 tabele i wszystkie powiązane dane (kontenery, snippety, wersje, powiązania kanałów). Jeśli jest zaznaczony, tabele pozostają na miejscu i odzyskasz swoje snippety, jeśli później ponownie zainstalujesz plugin.

Czy ta strona była pomocna?

Nadal utknąłeś? Napisz do wsparcia