Motywy potomne PrestaShop: Classic i Hummingbird
Tworzenie motywów potomnych PrestaShop — nadpisywanie szablonów, personalizacja SCSS, hooki JavaScript, szablony modułów i zmiany w PS 9.
Czym jest motyw potomny i dlaczego ma znaczenie
Motyw potomny (child theme) dziedziczy szablony i zasoby z motywu nadrzędnego, pozwalając nadpisać tylko to, co zmieniasz. Bez niego każda poprawka CSS czy edycja szablonu trafia do plików motywu nadrzędnego — i zostaje nadpisana przy kolejnej aktualizacji.
Motyw potomny to przezroczysta nakładka. PrestaShop najpierw szuka pliku w motywie potomnym. Jeśli go znajdzie — używa go. Jeśli nie — sięga do motywu nadrzędnego. Dodajesz tylko to, co zmieniasz.
Używaj motywu potomnego do punktówych modyfikacji — kolory, poprawki układu, nadpisywanie szablonów, własne CSS/JS. Buduj pełny własny motyw tylko wtedy, gdy potrzebujesz zasadniczo innej architektury.
| Motyw nadrzędny | Wersja PS | Framework | Najlepszy do |
|---|---|---|---|
| Classic | 1.7.x / 8.x | Bootstrap 4, jQuery | Maksymalna kompatybilność, stabilna baza |
| Hummingbird | 9.1+ | Bootstrap 5.3, TypeScript | Nowoczesne sklepy, gotowość na PS 9 |
W nowych projektach na PrestaShop 9.1+ wybierz Hummingbird — to domyślny motyw przyszłości i jedyny aktywnie rozwijany przez projekt PrestaShop.
Struktura motywu potomnego
Motyw potomny żyje obok motywu nadrzędnego w katalogu /themes/. Minimalny motyw potomny wymaga zaledwie dwóch plików:
themes/my-child-theme/
config/
theme.yml <-- wymagany: konfiguracja motywu
preview.png <-- wymagany: podgląd motywu 200x200
W miarę rozrastania się dostosowań katalog odzwierciedla strukturę motywu nadrzędnego, ale zawiera tylko zmodyfikowane pliki:
themes/my-child-theme/
config/theme.yml
assets/
css/custom.css
js/custom.js
templates/
catalog/product.tpl
_partials/header.tpl
modules/
ps_featuredproducts/views/templates/hook/
ps_featuredproducts.tpl
translations/en-US/Shop/Theme.xlf
preview.png
Dodawaj tylko pliki, które zmieniasz. Każdy dodany plik to plik, który musisz utrzymywać. Pusty motyw potomny dziedziczący wszystko jest lepszy niż zatłoczony niezmienionymi kopiami.
Konfiguracja theme.yml
Plik config/theme.yml to serce motywu potomnego. Kluczowa linia to parent: classic (lub parent: hummingbird) — ustanawia ona łańcuch dziedziczenia:
parent: classic
name: my-child-theme
display_name: My Child Theme
version: 1.0.0
author:
name: "Your Name"
email: "you@example.com"
url: "https://yoursite.com"
meta:
compatibility:
from: 1.7.0.0
to: ~
assets:
use_parent_assets: true
theme_settings:
default_layout: layout-full-width
layouts:
category: layout-left-column
Tworzenie motywu potomnego dla Classic
Classic to oryginalny domyślny motyw PrestaShop od wersji 1.7. Proces składa się z czterech kroków:
# 1. Utwórz katalog
mkdir -p themes/my-classic-child/config
# 2. Utwórz config/theme.yml z parent: classic (patrz wyżej)
# 3. Dodaj preview.png (200x200)
# 4. Aktywuj przez Back Office > Design > Theme & Logo
# Lub CLI: php bin/console prestashop:theme:enable my-classic-child
Z ustawieniem use_parent_assets: true i bez nadpisań otrzymujesz idealną kopię Classic. Szablony, CSS, JS, typy obrazów, układy i nadpisania szablonów modułów — wszystko jest dziedziczone.
Tworzenie motywu potomnego dla Hummingbird
Hummingbird używa Bootstrap 5.3 (CSS custom properties), CSS Layers (@layer), TypeScript kompilowanego z Webpack 5 oraz nazewnictwa BEM (.product__name, .product__description-short). Konfiguracja jest identyczna jak dla Classic — utwórz theme.yml z parent: hummingbird i kompatybilnością from: 9.0.0. Różnica polega na dostosowywaniu zasobów.
System warstw CSS w Hummingbird
Hummingbird definiuje następującą kolejność warstw w swoim SCSS:
@layer vendors, bs-base, bs-components, bs-custom-components,
ps-base, ps-components, ps-pages, ps-modules, utilities;
Style w późniejszych warstwach nadpisują wcześniejsze niezależnie od specyficzności selektora. Umieszczaj własne reguły w odpowiedniej warstwie:
@layer ps-components {
.product__name {
font-family: 'Your Custom Font', sans-serif;
}
}
@layer ps-pages {
.page--category .product-miniature {
border: 1px solid #eee;
border-radius: 8px;
}
}
Kompilacja SCSS
Aby używać własnego SCSS, dodaj krok kompilacji. Utwórz package.json z sass jako zależnością deweloperską i skryptami build:css (sass src/scss/custom.scss assets/css/custom.css --style=compressed) oraz watch:css. Następnie npm install && npm run build:css, aby skompilować.
Dart Sass może dodać znacznik UTF-8 BOM na początku skompilowanego CSS, powodując że przeglądarki po cichu ignorują reguły. Usuń go: sed -i '1s/^\xEF\xBB\xBF//' assets/css/custom.css
Nadpisywanie szablonów
Nadpisywanie szablonów to domena motywów potomnych. PrestaShop używa Smarty, który wspiera przejrzysty model dziedziczenia.
Kolejność rozpoznawania szablonów
- Motyw potomny —
themes/my-child/templates/ - Motyw nadrzędny —
themes/hummingbird/templates/
Metoda 1: Pełna kopia (prosta, trudniejsza w utrzymaniu)
Skopiuj szablon nadrzędny i edytuj go. Twoja wersja całkowicie zastępuje wersję nadrzędną:
cp themes/hummingbird/templates/catalog/product.tpl \
themes/my-child/templates/catalog/product.tpl
Wada: Jesteś właścicielem całego pliku. Aktualizacje szablonu nadrzędnego do Ciebie nie dotrą.
Metoda 2: Smarty {extends} (preferowana)
Rozszerz szablon nadrzędny i nadpisz tylko konkretne bloki:
{extends file='parent:catalog/listing/category.tpl'}
{block name='product_list_header'}
<div class="custom-category-header">
<h1>{$category.name}</h1>
<p>{$listing.pagination.total_items} products</p>
</div>
{/block}
Prefiks parent: jest kluczowy — bez niego Smarty znajdzie własny plik motywu potomnego i stworzy nieskończoną pętlę.
Modyfikatory bloków
Zamiast zastępować cały blok, dodaj treść na końcu lub na początku:
{extends file='parent:catalog/product.tpl'}
{block name='product_description' append}
<div class="shipping-notice">Free shipping on orders over $50</div>
{/block}
{block name='product_prices' prepend}
<span class="price-badge">Best Price</span>
{/block}
Struktura bloków w Hummingbird
Kluczowe punkty nadpisywania na stronie produktu Hummingbird (catalog/product.tpl):
{block name='product_cover_thumbnails'} — zdjęcia produktu
{block name='product_header'} — nazwa produktu (h1)
{block name='product_manufacturer'} — link do marki
{block name='product_prices'} — wyświetlanie ceny
{block name='product_description_short'} — krótki opis
{block name='product_variants'} — selektory kombinacji
{block name='product_add_to_cart'} — przycisk dodaj do koszyka
{block name='product_tabs'} — akordeon opis/szczegóły
{block name='product_accessories'} — produkty powiązane
Aby znaleźć dostępne bloki na dowolnej stronie, przeczytaj plik szablonu motywu nadrzędnego — każdy {block name='...'} to punkt nadpisania.
Dostosowywanie CSS
Rejestracja CSS w theme.yml
assets:
use_parent_assets: true
css:
all:
- id: my-child-custom-style
path: assets/css/custom.css
media: all
priority: 200
Wyższe wartości priority ładują się później, pozwalając nadpisać style nadrzędne. W Hummingbird preferuj deklaracje @layer zamiast walczyć ze specyficznością. W Classic dopasuj głębokość selektora do motywu nadrzędnego. Unikaj !important.
Zmiana schematu kolorów
W Hummingbird (Bootstrap 5) nadpisz CSS custom properties:
:root {
--bs-primary: #2563eb;
--bs-primary-rgb: 37, 99, 235;
--bs-body-font-family: 'Inter', system-ui, sans-serif;
}
Dostosowywanie JavaScript
Rejestracja JS w theme.yml
assets:
use_parent_assets: true
js:
all:
- id: my-child-custom-js
path: assets/js/custom.js
priority: 200
Zastąp all nazwą strony, aby ograniczyć zasięg skryptów: product, category, cart, checkout, cms, index (strona główna) lub dowolna nazwa kontrolera.
Zdarzenia JavaScript w PrestaShop
Twoje skrypty mogą nasłuchiwać zdarzeń PrestaShop poprzez globalny obiekt prestashop:
prestashop.on('updatedProduct', function(event) { /* combination changed */ });
prestashop.on('updateCart', function(event) { /* cart updated */ });
Dostępność jQuery
W motywie Classic jQuery jest ładowany globalnie. W Hummingbird jQuery 3.x jest nadal ładowany dla kompatybilności z modułami, ale sam motyw używa TypeScript. W nowym kodzie motywu potomnego preferuj czysty JS.
Nie usuwaj jQuery z motywu potomnego — zepsujesz moduły zewnętrzne, które na nim polegają. Ale we własnym kodzie czysty JS zapewnia lepszą wydajność i kompatybilność na przyszłość.
Nadpisywanie szablonów modułów
Możesz nadpisać sposób renderowania dowolnego modułu, umieszczając szablony w katalogu modules/ motywu.
Kolejność rozpoznawania
- Motyw potomny:
themes/my-child/modules/module_name/views/templates/... - Motyw nadrzędny:
themes/parent/modules/module_name/views/templates/... - Sam moduł:
modules/module_name/views/templates/...
Jak nadpisać
Znajdź szablon modułu (np. modules/ps_featuredproducts/views/templates/hook/ps_featuredproducts.tpl), skopiuj go do odpowiedniej ścieżki w themes/my-child/modules/ i edytuj kopię. Moduł może się aktualizować bez wpływu na Twoją wersję.
Nadpisania w motywie mają absolutny priorytet. Jeśli moduł zaktualizuje swój szablon w celu naprawy luki bezpieczeństwa, a Twój motyw ma starszą kopię, stara wersja nadal będzie używana. Okresowo porównuj swoje nadpisania z aktualnymi wersjami modułów.
Tłumaczenia w motywach potomnych
Kolejność rozpoznawania tłumaczeń:
- Tłumaczenia z bazy danych (Back Office > International > Translations)
- Katalog
translations/motywu potomnego - Katalog
translations/motywu nadrzędnego - Tłumaczenia modułów
- Tłumaczenia jądra
Najprostsze podejście to Back Office (International > Translations). Aby tłumaczenia były kontrolowane wersją, utwórz pliki XLIFF w themes/my-child/translations/en-US/Shop/Theme/Global.xlf:
<xliff xmlns="urn:oasis:names:tc:xliff:document:1.2" version="1.2">
<file original="shop-theme-global" source-language="en-US"
target-language="en-US" datatype="plaintext">
<body>
<trans-unit id="add_to_cart" approved="yes">
<source>Add to cart</source>
<target>Add to bag</target>
</trans-unit>
</body>
</file>
</xliff>
W sklepach wielojęzycznych utwórz pliki dla każdego locale (translations/fr-FR/, translations/de-DE/). Wyczyść cache po zmianach: php bin/console cache:clear
Typowe dostosowania
Własny układ nagłówka
{extends file='parent:_partials/header.tpl'}
{block name='header_nav'}
<nav class="custom-header-nav container">
<div class="row align-items-center">
<div class="col-md-3">{hook h='displayNav1'}</div>
<div class="col-md-6 text-center">
<a href="{$urls.base_url}"><img src="{$shop.logo}" alt="{$shop.name}"></a>
</div>
<div class="col-md-3 text-end">{hook h='displayNav2'}</div>
</div>
</nav>
{/block}
Własne czcionki
Umieść pliki WOFF2 w assets/fonts/ i odwołaj się do nich w CSS:
@font-face {
font-family: 'CustomFont';
src: url('../fonts/CustomFont-Regular.woff2') format('woff2');
font-weight: 400;
font-display: swap;
}
body { font-family: 'CustomFont', system-ui, sans-serif; }
Zawsze używajfont-display: swap, aby zapobiec niewidocznemu tekstowi podczas ładowania. Wstępnie ładuj krytyczne czcionki:<link rel="preload" as="font" type="font/woff2" crossorigin>.
Zmiana układu strony produktu
{extends file='parent:catalog/product.tpl'}
{block name='product_description_short'}
<div class="product__description-short">{$product.description_short nofilter}</div>
{if $product.description}
<div class="product__description-full mt-3">{$product.description nofilter}</div>
{/if}
{/block}
{block name='product_description'}{/block} {* usunięty z kart *}
Zmiany w motywach PS 9
- Hummingbird jest domyślny. Classic pozostaje dostępny, ale aktywny rozwój jest skierowany na Hummingbird.
- Smarty pozostaje w front office. Twig służy tylko do panelu administracyjnego. Twoje nadpisania
{extends}i{block}działają jak dotychczas. - Bootstrap 5.3 zastępuje Bootstrap 4. Zapoznaj się z przewodnikiem migracji, jeśli przechodzisz z Classic.
- CSS Layers (
@layer) zmieniają sposób działania specyficzności w Hummingbird. - WebP domyślnie dla obrazów. Nowy klucz
frameworkw theme.yml:bootstrap-v5.3.3. - Niektóre stare zmienne globalne JS usunięte. Testuj dokładnie przy migracji z PS 8.
Twig może w przyszłości trafić do front office w kolejnej głównej wersji. Pisanie czystych szablonów z minimalnymi nadpisaniami ułatwi każdą przyszłą migrację.
Debugowanie problemów z motywem
Najpierw wyczyść wszystkie cache: php bin/console cache:clear. Na czas prac deweloperskich ustaw cache szablonów na “Force compilation” i wyłącz CCC w Advanced Parameters > Performance.
Podczas prac deweloperskich zawsze wymuszaj kompilację szablonów i wyłączaj CCC. Bez tego debugujesz pliki z cache.
Włącz debugowanie Smarty, dodając ?SMARTY_DEBUG do dowolnego adresu URL front office. Pokaże to załadowane szablony, ścieżki plików i zmienne. Włącz to w config/defines.inc.php, ustawiając _PS_SMARTY_FORCE_COMPILE_ i _PS_SMARTY_CONSOLE_ na 1.
Typowe błędy
| Objaw | Prawdopodobna przyczyna | Rozwiązanie |
|---|---|---|
| Biała strona | Błąd składni Smarty | Sprawdź var/logs/ |
| Szablon nie znaleziony | Zła ścieżka lub brak prefiksu parent: | Upewnij się, że ścieżka odzwierciedla motyw nadrzędny |
| Nieskończona pętla / timeout | {extends} bez prefiksu parent: | Użyj {extends file='parent:...'} |
| Brak treści bloku | Niezgodność nazwy bloku | Sprawdź dokładne nazwy w szablonie nadrzędnym |
| CSS nie działa | Problem z cache lub specyficznością | Wyczyść cache, sprawdź priorytet w DevTools |
| Podwójnie zakodowany HTML | Automatyczne escapowanie już zakodowanej treści | Użyj {$var nofilter} |
Jeśli cache się utrzymuje, usuń również var/cache/prod/smarty/compile/ i var/cache/prod/smarty/cache/.
Aktualizacje z motywami potomnymi
To właśnie tutaj motywy potomne się spłacają. Gdy motyw nadrzędny się aktualizuje:
- Pliki tylko w motywie nadrzędnym — aktualizowane normalnie, motyw potomny dziedziczy je automatycznie.
- Pliki nadpisane w motywie potomnym — wersja potomna nadal jest używana, aktualizacja nadrzędna jest niewidoczna.
- Pliki własne motywu potomnego — całkowicie niezagrożone.
Przed aktualizacją: zrób kopię zapasową, wypisz swoje nadpisania (find themes/my-child/templates -name "*.tpl"), zaktualizuj w środowisku testowym (poradnik lokalnego developmentu), porównaj zmienione szablony nadrzędne ze swoimi nadpisaniami za pomocą diff i przetestuj każdą dostosowaną stronę.
Precyzyjne nadpisania {extends} są lepsze niż pełne kopie plików. Przy nadpisywaniu bloków nowe bloki nadrzędne są automatycznie włączane. Pełne kopie plików całkowicie je pomijają.
Lista kontrolna przed uruchomieniem motywu potomnego
Konfiguracja: theme.yml ma poprawne parent: i name: (małe litery, bez spacji). use_parent_assets: true jest ustawione. preview.png istnieje. Zakres kompatybilności odpowiada Twojej wersji PS.
Szablony: Wszystkie nadpisania używają {extends file='parent:...'} tam, gdzie to możliwe. Nazwy bloków dokładnie odpowiadają motywowi nadrzędnemu. Brak błędów Smarty w var/logs/. Nadpisania szablonów modułów przetestowane z aktualnymi wersjami modułów. nofilter użyty dla zmiennych HTML.
Zasoby: Własny CSS ładuje się po nadrzędnym (wysoki priority). Brak nadmiernego użycia !important. Czcionki używają font-display: swap i WOFF2. Brak błędów JS w konsoli. CCC włączone bez żadnych problemów.
Testowanie: Desktop (Chrome, Firefox, Safari, Edge), mobile (iOS Safari, Android Chrome), breakpointy responsywne. Zweryfikuj: stronę główną, kategorie, produkt, koszyk, checkout, konto klienta, CMS, wyszukiwarkę, 404.
Utrzymanie: Motyw potomny w Git. Nadpisane szablony udokumentowane. Proces kompilacji udokumentowany (zobacz nasz poradnik narzędzi deweloperskich). Zespół wie, że nie należy edytować plików nadrzędnych.