Shoptet vám nedá přístup do šablony tak, jak jste zvyklí u webu na míru. HTML generuje systém a vy do něj vstupujete až ve chvíli, kdy je hotové — vlastními styly a vlastním skriptem, které se vkládají v administraci. Všechno, co si přejete změnit, se tedy musí dát udělat nad existující strukturou stránky.
Z toho plyne jednoduché pravidlo: co jde udělat v CSS, dělejte v CSS. JavaScript sahá po struktuře stránky, a každý takový zásah je závazek do budoucna, protože se po aktualizaci šablony může rozejít s realitou.
Co bez problémů zvládne CSS
Samotnými styly se dá změnit podstatně víc, než většina lidí čeká. Pokrývají zdaleka nejčastější požadavky klientů a nemají prakticky žádnou údržbu.
- Barvy, písma, velikosti, rozestupy a rámečky kdekoli na e-shopu
- Vzhled tlačítek, dlaždic produktů, štítků a příznaků akcí
- Skrytí prvku, který klient nepoužívá — třeba porovnávání produktů
- Jiné chování na mobilu a na počítači přes media queries
- Doplnění textu nebo ikony pseudoprvky ::before a ::after
- Změna pořadí prvků uvnitř jednoho kontejneru pomocí flexboxu
Přesun pořadí, který zvládne i CSS
Poslední bod stojí za rozvedení, protože se na něj často zapomíná. Pokud spolu prvky sousedí, tedy mají stejného rodiče, dá se jejich pořadí přeházet bez jediného řádku javascriptu. Stačí z rodiče udělat flexbox a přiřadit vlastnost order.
/* dostupnost nad cenu, bez javascriptu */
.p-detail-inner {
display: flex;
flex-direction: column;
}
.p-detail-inner .availability {
order: -1;
}Má to dva háčky. Zaprvé to funguje jen mezi sourozenci — přes hranice rodičů prvek takhle nedostanete. Zadruhé se mění jen vizuální pořadí, kdežto v kódu prvek zůstává tam, kde byl. Pro čtečky obrazovky a pro procházení klávesnicí tedy platí původní pořadí. U drobného posunu to nevadí, u větších zásahů to začne mást.
Kdy už si bez javascriptu neškrtnete
Jakmile má prvek skončit jinde ve stránce, než kde ho Shoptet vykreslil, CSS nestačí. Typicky jde o požadavky, které dávají obchodní smysl a klient je považuje za maličkost.
- Přesunout dopravu zdarma z patičky detailu produktu nahoru k ceně
- Vytáhnout obsah záložky s parametry rovnou pod popis
- Vložit vlastní blok s garancí mezi košík a souhrn objednávky
- Přemístit vyhledávání z rozbalovacího menu přímo do hlavičky
- Posunout hodnocení produktu nad tlačítko Do košíku
Tohle všechno je práce pro javascript, který prvek najde a přesune ho jinam. A je fér říct, že to není hack — je to standardní postup, jak se Shoptet přizpůsobuje. Jen se musí dělat opatrně.
Jak přesun udělat pořádně
Základ je nenápadný, ale důležitý: metody jako appendChild, before nebo after prvek skutečně přesunou, nevytvoří kopii. Původní prvek tak zůstane jediný a zachová si všechny navěšené obsluhy událostí, které na něm Shoptet má. Pokud byste místo toho sáhli po innerHTML, uděláte kopii bez chování a rozbijete třeba výběr varianty.
document.addEventListener("DOMContentLoaded", () => {
const dostupnost = document.querySelector(".p-detail .availability");
const cena = document.querySelector(".p-detail .price-final");
// Šablona se změnila? Radši neděláme nic, než abychom stránku rozbili.
if (!dostupnost || !cena) return;
cena.before(dostupnost); // přesun, ne kopie
});Selektory v ukázce berte jako ilustraci, ne jako předpis. Konkrétní třídy si vždy ověřte v inspektoru prohlížeče na svém e-shopu, protože se mezi šablonami liší.
Tři pasti, o které jde zakopnout
První je překreslování stránky. Shoptet část obsahu načítá dodatečně — košík, filtry v kategorii, přepnutí varianty. Ve chvíli, kdy systém obsah překreslí, je váš přesun pryč, protože prvek je nový. Řešením je zásah zopakovat. Shoptet k tomu nabízí vlastní události, jejichž aktuální názvy najdete v jeho dokumentaci pro vývojáře. Když si nejste jistí, spolehlivější je sledovat změny přes MutationObserver.
function presunDostupnost() {
const dostupnost = document.querySelector(".p-detail .availability");
const cena = document.querySelector(".p-detail .price-final");
if (!dostupnost || !cena) return;
// Pojistka proti opakovanému běhu: už je na místě, nic neděláme.
if (dostupnost.nextElementSibling === cena) return;
cena.before(dostupnost);
}
presunDostupnost();
// Po překreslení obsahu zásah zopakujeme.
const obsah = document.querySelector("#content");
if (obsah) new MutationObserver(presunDostupnost).observe(obsah, {
childList: true,
subtree: true,
});Druhá past je poskakování obsahu. Prvek se nejdřív vykreslí na původním místě a teprve potom skočí jinam. Návštěvník to vidí a Google to počítá jako posun rozvržení, což zhoršuje hodnocení stránky. Pomůže prvek v CSS skrýt a zviditelnit ho až po přesunu — s tím, že když javascript selže, musí zůstat vidět.
Třetí past jsou křehké selektory. Zápisy typu nth-child nebo cílení na automaticky generované třídy fungují přesně do první úpravy šablony. Držte se stabilních tříd a ID, a když je prvek nemá, najděte si nejbližší rodiče, který je má.
Dobrá úprava Shoptetu se pozná tak, že když přestane fungovat, e-shop vypadá jako předtím — ne rozbitě.
Co nechat na pokoji
Do pokladny a do samotného procesu objednávky bych javascriptem nesahal. Je to nejcitlivější místo celého e-shopu, Shoptet ho mění nejčastěji a chyba se neprojeví hláškou, ale tím, že přestanou chodit objednávky. Pokud je zásah v pokladně nevyhnutelný, testujte ho na zkušebních objednávkách napříč prohlížeči a po každé aktualizaci znovu.
Praktický postup
- Zkuste to nejdřív čistým CSS, včetně změny pořadí přes flexbox
- Teprve když to nejde, sáhněte po javascriptu a přesuňte prvek, nekopírujte ho
- Každý zásah napište tak, aby při nenalezení prvku tiše skončil
- Počítejte s překreslením obsahu a zásah po něm zopakujte
- Všechny úpravy držte na jednom místě a opatřete je komentářem, proč tam jsou
- Po aktualizaci šablony projděte detail produktu, kategorii a košík
Když si tohle pohlídáte, vytěžíte ze Shoptetu překvapivě hodně a zároveň si nezavřete dveře k budoucím aktualizacím. Víc o tom, co se na Shoptetu vyplatí upravovat a čemu se vyhnout, jsem psal v článku o custom šabloně bez bolesti.