Un tema non è più un foglio di stile copiato. Da Maho 26.9 lo storefront è vestito da una skin compilata costruita su Tailwind CSS 4 e daisyUI 5, e il tuo tema è uno strato sottile di token sopra di essa. Il vantaggio: cambi una manciata di variabili e ridisegni l’intero store, senza toccare i template del core e senza perdere le tue modifiche a ogni aggiornamento. In questo tutorial creiamo un tema, lo attiviamo e lo personalizziamo.
Cosa serve
- Maho 26.9 o superiore, con il nuovo sistema di skin.
- Un ambiente di sviluppo funzionante. Nei nostri esempi usiamo Harbor, il launcher Docker
Compose open source di MageMEGA, ispirato a Laravel Sail, presentato in Sviluppo locale di Maho
con
Harbor: se non lo conosci, parti da quell’articolo
e poi torna qui. I comandi funzionano comunque anche con
./mahodiretto. - Node.js solo per la variante con build Tailwind propria (Opzione B). Con i design token non serve alcun tool di build.
Quick start: un tema in tre passaggi
1. Genera lo scheletro
./vendor/bin/harbor maho dev:frontend:theme:create -p base -t mytheme --parent base/default
Il comando scrive:
app/design/frontend/base/mytheme/etc/theme.xml(il tema e il suo parent),app/design/frontend/base/mytheme/layout/local.xml(le modifiche al layout),public/skin/frontend/base/mytheme/css/theme.css(l’identità del tema).
Il tema nasce dentro il package base esistente e nel project root. Passa --parent base/default esplicitamente: prima che esista un tema locale, la lista dei temi disponibili è
vuota. Aggiungi --tailwind se vuoi la tua build.
2. Definisci l’identità
Apri public/skin/frontend/base/mytheme/css/theme.css e cambia i token:
:root {
--font-display: 'Figtree', sans-serif;
--color-primary: #0e7a5f;
--color-base-100: #ffffff;
--color-base-200: #f3f6f4;
--color-base-content: #17221d;
--radius-box: 1rem;
}
Ogni componente deriva da queste variabili, quindi il tema si estende a tutto lo store.
3. Attiva il tema per uno store view
./vendor/bin/harbor maho config:set design/package/name "base" --scope stores --scope-id 2
./vendor/bin/harbor maho config:set design/theme/skin "mytheme" --scope stores --scope-id 2
./vendor/bin/harbor maho cache:flush
design/theme/skin va impostato per website o store view, mai a livello globale: a scope
default sostituisce la skin di tutti i website e perdi le varianti di settore (base/fashion,
base/electronics, e così via). Trova l’id dello store view in amministrazione, in System >
Manage Stores.
Per vedere il tema senza attivarlo, aggiungi ?___package=base&___skin=mytheme a qualsiasi URL.
🧵 Nota di sarto. Un tema Maho è un abito su misura, non un vestito intero cucito da zero: la skin compilata è il tessuto, i design token sono i tuoi aghi. Cambi pochi punti e l’abito veste tutta la bottega.
Come funziona il nuovo sistema
Il package base contiene i template e i layout in base/default e le varianti di settore; la
skin compilata vive in public/skin/frontend/base/default. Ogni pagina carica due fogli di
stile:
css/styles.css: il motore compilato, organizzato in cascade layer, condiviso da tutti i temi.css/theme.css: l’identità del tema attivo, fuori dai layer e caricato dopo, quindi vince sempre, senza!important.
Da qui la regola d’oro: sovrascrivi il meno possibile. Ogni file che copi smette di ricevere le
correzioni di Maho e va riconciliato a mano a ogni upgrade. Il plugin Composer riscrive i file del
core a ogni composer install/update, quindi non modificare mai nulla sotto
public/skin/frontend/base/...: crea il tuo tema e tieni i tuoi asset nella sua skin.
I livelli di personalizzazione
Usa sempre il livello più basso che ottiene il risultato:
| Livello | Metodo | Impatto sugli aggiornamenti |
|---|---|---|
| 0 | Theme Settings nell’admin | Nessuno |
| 1 | Design token in theme.css |
Nessuno |
| 2 | Regole CSS aggiuntive in theme.css |
Nessuno |
| 3 | Layout XML in local.xml |
Minimo |
| 4 | Override dei template | Alto, da evitare |
Personalizzare con i token (livello 1)
I token coprono colori, tipografia, raggi, prezzi, filtri, galleria e molto altro. Quando un token non basta, aggiungi CSS normale sotto i token: essendo fuori dai layer, ha la precedenza.
.btn { border-radius: 9999px; }
#nav a { text-transform: uppercase; letter-spacing: 0.04em; }
Non usare !important: se ti sembra necessario, c’è un errore di ordine o di layer.
Dark mode
Il tema scuro segue il sistema operativo con un blocco @media, mantenendo il selettore a
specificità zero:
@media (prefers-color-scheme: dark) {
:root:where(:not([data-color-scheme="light"])) {
--color-base-100: #131917;
--color-base-content: #dbe7e1;
}
}
Il commerciante può disattivarlo per store view: in quel caso lo storefront imposta
data-color-scheme="light" e ogni regola scura resta agganciata al selettore :where().
Opzione B: la tua build Tailwind
Serve solo se scrivi template con classi Tailwind o usi @apply. Crea
public/skin/frontend/base/mytheme/src/tailwind.css e importa l’entry di base:
@import "../../../base/default/src/tailwind.css";
:root { --color-primary: #0e7a5f; }
@layer components {
.mytheme-banner { @apply alert alert-info rounded-box; }
}
Poi compila:
./vendor/bin/harbor maho dev:frontend:theme:build --theme base/mytheme
Con questa opzione tailwind.css diventa css/styles.css, servito al posto del bundle di
Maho: possiedi il motore e devi ricostruirlo a ogni upgrade. Committa il CSS compilato (in
produzione non serve Node.js) e non modificare mai css/styles.css a mano.
Layout e sottotemi
Per aggiungere, spostare o rimuovere blocchi non serve toccare i template: usa
app/design/frontend/base/mytheme/layout/local.xml.
<layout version="0.1.0">
<default>
<reference name="left"><remove name="left.newsletter"/></reference>
</default>
</layout>
Prima di intervenire, chiedi a Maho quali handle e quali file di layout compongono quella pagina: il comando seguente stampa gli handle caricati per l’URL, i file XML coinvolti, i blocchi rimossi e l’albero finale dei blocchi.
./vendor/bin/harbor maho dev:frontend:layout:debug https://localhost:8443/tua-url.html
Così sai esattamente dove agganciarti nel local.xml, e perché un blocco c’è o non c’è.
Un sottotema (variante stagionale, A/B) sta nello stesso package e dichiara il parent. Il suo
theme.css sostituisce quello principale, quindi importa prima il parent:
@import url('../../../base/mytheme/css/theme.css');
:root { --color-primary: #c62828; }
Font, icone e contenuti CMS
-
I web font si dichiarano in
theme.xmlcon<fonts>, mai con@importin CSS: Maho genera un<link>che il preload scanner vede subito. -
Nelle pagine e nei blocchi CMS usa la direttiva
{{icon ...}}invece di SVG inline (il sanitizer lo rimuove):{{icon name="truck" variant="outline" size="32" label="Consegna"}} -
Le classi daisyUI usabili nel contenuto sono solo quelle elencate nella safelist di
tailwind.css.
Verificare e pubblicare
config:get design/package/nameeconfig:get design/theme/skinconfermano l’attivazione,cache:flushapplica le modifiche.dev:frontend:theme:export --theme base/mytheme --forcesalva su file i Theme Settings dichiarati inglobal/design/tokens(senza--force, setheme.cssesiste già, il comando si ferma). Non esportadesign/tokens/custom_cssné il flag dark mode: portali nel tema a mano.- Fai un controllo visivo a circa 390, 820 e 1280 px (il layout cambia a 771 px) e assicurati che la console non mostri errori o asset 404.
🧵 Ultima nota di sarto. Un buon tema non si riconosce dagli strappi, ma da quanto poco tocca il tessuto originale. Cuciture poche, dritte e sempre nel tuo atelier. Buon lavoro!
Troubleshooting
| Sintomo | Controlla |
|---|---|
| Il tema non si applica | config:get di design/package/name e design/theme/skin allo scope giusto, poi cache:flush |
| Il sottotema perde l’identità del parent | l’@import del parent in cima a theme.css |
| Le modifiche CSS non si vedono | path o scope sbagliato, oppure stai modificando la copia del core (sovrascritta) |
| Il tema non compare nei select del Design | deve esistere etc/theme.xml sotto app/design/frontend/base/<tema>/ nel project root |
| Asset del preview 404 | usa /skin/frontend/... senza codice store |
| Build fallita | toolchain Node.js/Bun mancante |
| Icona vuota | nome Tabler errato, oppure svuota la cache icons |
Se preferisci partire da un tema pronto
Lightclean è il tema per MahoCommerce che MageMEGA ha preparato per un negozio pulito e leggero: si può usare così com’è, oppure come parent di un child theme costruito con il metodo di questa guida. La panoramica è nella pagina Lightclean.
Nota di redazione.Testo preparato con l'aiuto dell'AI e verificato sulla fonte prima della pubblicazione. Può contenere errori: se ne trovi uno, segnalalo.Leggi il Manifesto
Il tuo negozio vende ancora?
Raccontaci da dove parti: ti rispondiamo con una prima valutazione, senza impegno.
Chiedi l'analisi del negozio