Child Themes PrestaShop: Przewodnik po personalizacji 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 | 8.1+ / 9.x | Bootstrap 5.3, TypeScript | Nowoczesne sklepy, gotowość na PS 9 |
W nowych projektach na PrestaShop 8.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.
More guides available
Browse our knowledge base for more practical PrestaShop tutorials, or reach out if you need help.