# DfCustomCodeManager — Guida completa

> DfCustomCodeManager fornisce una risposta semplice a un problema universale nei negozi Shopware: dove mettere, come versionare e come proteggere il CSS e il JavaScript personalizzato che si finisce sempre per…

- Pagina: <https://www.datafirefly.com/it/documentation/df-custom-code-manager/>
- Lingua: it
- Aggiornato il: 2026-06-29
- Altre lingue: [fr](https://www.datafirefly.com/documentation/df-custom-code-manager/index.md), [en](https://www.datafirefly.com/en/documentation/df-custom-code-manager/index.md), [es](https://www.datafirefly.com/es/documentation/df-custom-code-manager/index.md), [de](https://www.datafirefly.com/de/documentation/df-custom-code-manager/index.md), [pl](https://www.datafirefly.com/pl/documentation/df-custom-code-manager/index.md), [nl](https://www.datafirefly.com/nl/documentation/df-custom-code-manager/index.md), [pt](https://www.datafirefly.com/pt/documentation/df-custom-code-manager/index.md)
- Indice: <https://www.datafirefly.com/it/documentation/llms.txt>

DfCustomCodeManager fornisce una risposta semplice a un problema universale nei negozi Shopware: **dove mettere, come versionare e come proteggere il CSS e il JavaScript personalizzato** che si finisce sempre per aggiungere a un tema? Il plugin offre un editor di codice integrato nell'amministrazione, un sistema di **container** che raggruppano **snippet SCSS o JavaScript**, e soprattutto un'**iniezione diretta nella compilazione del tema** tramite gli eventi nativi di Shopware. La conseguenza: nessun file aggiuntivo servito, nessuna richiesta HTTP in più per il visitatore, e i tuoi snippet SCSS ereditano automaticamente le variabili e i mixin del tema attivo. Questa guida copre l'installazione, la configurazione, la creazione di container e snippet, la compilazione del tema, la cronologia delle versioni, la modalità sicura, la libreria di preset, l'importazione/esportazione e la risoluzione dei problemi.

## Installazione

1. Scarica l'archivio `DfCustomCodeManager-1.0.0.zip` dal tuo account DataFirefly.
2. Installalo tramite **Amministrazione → Estensioni → Le mie estensioni → Carica estensione**, oppure decomprimi la cartella `DfCustomCodeManager` in `custom/plugins/`.
3. Esegui l'installazione e l'attivazione: ``` bin/console plugin:refresh bin/console plugin:install --activate DfCustomCodeManager bin/console cache:clear ```
4. All'installazione, il plugin crea le sue 4 tabelle (`df_ccm_container`, `df_ccm_container_sales_channel`, `df_ccm_snippet`, `df_ccm_snippet_version`) e registra i suoi subscriber sugli eventi di compilazione del tema.
5. Ricompila il tema affinché tenga conto del plugin: ``` bin/console theme:compile ```

Compatibile con Shopware 6.6.x e 6.7.x sulla stessa codebase (composer `^6.6.0 || ^6.7.0`). Il modulo di amministrazione è **precompilato**, **nessun build è richiesto**. Richiesto PHP 8.2+. La compilazione SCSS si appoggia a `scssphp/scssphp`, già fornito da `shopware/storefront`. Nessuna dipendenza Composer aggiuntiva.

## Dove trovare il plugin nell'amministrazione

Dopo l'attivazione, una voce **Custom Code Manager** appare nel menu **Cataloghi** dell'amministrazione (icona arancione, posizione 100). È la schermata principale: elenco dei container, ricerca, filtri e le azioni globali **Importa**, **Esporta**, **Preset** e **Compila il tema**. Tutta la configurazione di basso livello (modalità sicura, minify, banner) avviene da **Estensioni → Le mie estensioni → DfCustomCodeManager → ⋯ → Configura**.

Se la voce non appare dopo un aggiornamento, esegui `bin/console assets:install && bin/console cache:clear` poi ricarica l'amministrazione con un refresh forzato (Ctrl+Shift+R).

## Configurazione del plugin

La card di configurazione del plugin Shopware espone tre interruttori semplici ma essenziali:

- **Modalità sicura** (`DfCustomCodeManager.config.safeMode`): disattivata per default. Quando attivata, **tutti** i container vengono ignorati alla prossima compilazione, come se fossero tutti inattivi. È la rete di sicurezza descritta più sotto.
- **Minify JS** (`DfCustomCodeManager.config.minifyJs`): minificazione di base del JavaScript iniettato. Utile in produzione, lasciarla disattivata in sviluppo per poter leggere gli snippet nel bundle compilato.
- **Aggiungi banner** (`DfCustomCodeManager.config.addBanner`): aggiunge un commento `/* DataFirefly Custom Code Manager */` all'inizio del codice iniettato. Pratico per individuare rapidamente i tuoi snippet nel bundle compilato.

## Il modello mentale: container e snippet

Il plugin si organizza su **due livelli**:

- Un **container** è un raggruppamento logico: _Promo estate 2026_, _GTM analytics_, _Dark mode opt-in_, _A/B test pulsante CTA_… Ogni container ha un nome, una descrizione, una priorità, un interruttore attivo/inattivo e un ambito per canale di vendita.
- Uno **snippet** è un'unità di codice all'interno di un container. Tipo SCSS o JavaScript, nome, codice, priorità, interruttore attivo/inattivo, note Markdown e un interruttore per attivare o meno l'iniezione delle variabili del tema.

Un container può contenere **più snippet di tipi misti**. È utile per raggruppare logicamente gli snippet che vanno insieme: per esempio un container _Dark mode opt-in_ con uno snippet SCSS per gli stili e uno snippet JavaScript per il toggle di classe su `html`.

## Creare il tuo primo container

1. Da **Cataloghi → Custom Code Manager**, clicca su **Nuovo container** in alto a destra.
2. Dagli un nome evocativo (es. _Promo estate 2026 — sticky header & badge_).
3. Imposta la **priorità** (lasciala a 0 per default, alzala se vuoi che questo container venga iniettato più tardi nel bundle e quindi sovrascriva altri stili).
4. (Opzionale) Attiva **Limita a canali di vendita specifici** e seleziona uno o più canali. Se l'opzione è disattivata, il container si applica a **tutti** i canali.
5. Compila una descrizione (note interne, contesto, ticket associato) — non verrà mai iniettata nel bundle.
6. Salva. Sei ora pronto ad aggiungere snippet.

## Aggiungere uno snippet SCSS o JavaScript

Nella card **Snippet di codice** della pagina container, due pulsanti: **Aggiungi SCSS** e **Aggiungi JavaScript**. Ogni snippet aggiunto appare come una card con:

- Un badge **SCSS** (info) o **JS** (warning).
- Un campo nome (visibile solo in modifica).
- Un interruttore attivo/inattivo.
- Un pulsante **Valida sintassi** (✓).
- Un pulsante **Cronologia** (orologio) — disponibile dal primo salvataggio.
- Un pulsante **Duplica**.
- Un pulsante **Rimuovi**.
- Un **editor di codice** con evidenziazione sintattica adatta al tipo.
- Una zona **Note** Markdown per documentare cosa fa lo snippet.

L'editor di codice usa nativamente il componente `mt-code-editor` introdotto in Shopware 6.7 (basato su Meteor). Su Shopware 6.6, il plugin passa automaticamente a `sw-code-editor` (il componente più vecchio basato su Ace). Come ultima risorsa (componente non disponibile), un `textarea` in font monospaziato prende il sopravvento — senza evidenziazione sintattica ma perfettamente funzionale.

## Compilare il tema

Uno snippet salvato **non è ancora visibile** sullo storefront finché il tema non è stato ricompilato. Due modi per farlo:

- Dall'amministrazione, il pulsante **Compila il tema** (in alto a destra nell'elenco, o nella pagina container). Una notifica conferma la fine dell'operazione.
- Dalla riga di comando: ``` bin/console theme:compile ```

Al momento della compilazione, il plugin ascolta tre eventi Shopware e vi inietta i tuoi snippet:

- `ThemeCompilerEnrichScssVariablesEvent` — cattura la mappa delle variabili SCSS del tema attivo. È ciò che permette ai tuoi snippet SCSS di usare `$sw-color-brand-primary`, `$font-family-base`, ecc.
- `ThemeCompilerConcatenatedStylesEvent` — aggiunge il tuo SCSS compilato alla fine del foglio di stile principale.
- `ThemeCompilerConcatenatedScriptsEvent` — aggiunge il tuo JavaScript alla fine del bundle script principale.

Risultato: **zero richieste HTTP aggiuntive** servite al visitatore, il tuo codice passa attraverso tutta la catena di ottimizzazione Shopware (concatenazione, minificazione, fingerprinting di cache).

## Ereditarietà delle variabili e dei mixin del tema

Per default, ogni snippet SCSS beneficia di un **preambolo automatico** che contiene tutte le variabili e i mixin esposti dal tema attivo e dai suoi plugin di tema. Puoi quindi scrivere in uno snippet:

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

…senza importare nulla manualmente, esattamente come in un file SCSS del tema. Se per una ragione particolare (conflitto di variabili, snippet autocontenuto) vuoi disattivare questa ereditarietà su uno snippet specifico, deseleziona l'interruttore **Variabili del tema disponibili** nel footer della card snippet.

## Ambito multi-canale

Nella card **Ambito e canali** del container, attiva **Limita a canali di vendita specifici** e seleziona i canali rilevanti. Il container verrà quindi iniettato solo nelle compilazioni di tema per quei canali. Molto utile per:

- Un banner promozionale riservato a un negozio di brand secondario.
- Uno script di tracking specifico per un mercato.
- Un A/B test su un singolo canale per misurare l'impatto.

## Priorità di caricamento

La priorità è un intero (default 0) che controlla l'**ordine di iniezione** nel bundle compilato: più il valore è alto, più tardi il codice viene iniettato, e quindi più può sovrascrivere ciò che lo precede. La priorità esiste a **due livelli**:

- **A livello container**: ordine tra container.
- **A livello snippet**: ordine tra snippet _all'interno di_ uno stesso container.

L'ordine finale è: `(priorità container, priorità snippet)` crescente. Consiglio semplice: lascia tutto a 0 per default, usa la priorità solo quando devi esplicitamente sovrascrivere qualcosa.

## Cronologia delle versioni

A ogni salvataggio di uno snippet, il plugin crea automaticamente una **versione** nella tabella `df_ccm_snippet_version`. Le **ultime 5 versioni** per snippet vengono conservate (la più vecchia viene eliminata quando si raggiunge il limite). Per consultare e ripristinare una versione:

1. Sulla card snippet, clicca sull'icona **Cronologia** (orologio).
2. Si apre un modal con l'elenco delle versioni: data, autore, commento e anteprima.
3. Clicca su **Ripristina** a destra della versione desiderata — il codice dello snippet viene immediatamente sostituito da quello della versione. Viene creata una nuova versione per registrare il ripristino.
4. Salva il container e ricompila per vedere l'effetto.

Per cronologie più lunghe, il journal completo resta nella tabella `df_ccm_snippet_version` (le vecchie versioni sono solo nascoste dal modal). Uno sviluppatore può estendere molto facilmente `VersionTracker::MAX_VERSIONS_PER_SNIPPET` se necessario.

## Modalità sicura: la rete di sicurezza d'emergenza

La modalità sicura è un interruttore globale nella configurazione del plugin. Attivata, fa in modo che **tutti i container vengano ignorati alla prossima compilazione**, senza modificare alcun dato. Uso tipico:

1. Uno snippet mal testato rompe qualcosa in produzione alle 22.
2. Vai a **Estensioni → Le mie estensioni → DfCustomCodeManager → ⋯ → Configura**.
3. Attiva l'interruttore **Modalità sicura** e salva.
4. Ricompila il tema: `bin/console theme:compile`.
5. Lo storefront torna al suo stato nativo (senza alcuno snippet iniettato). Ora puoi identificare e correggere lo snippet incriminato con calma.
6. Una volta corretto, disattiva la modalità sicura e ricompila di nuovo.

La modalità sicura è uno strumento d'emergenza, non una modalità operativa. Una volta risolto l'incidente, ricordati di disattivarla, altrimenti nessuno dei tuoi container verrà iniettato.

## Libreria di preset

Il pulsante **Preset** (dall'elenco dei container) apre una libreria di 8 container installabili in un clic:

- **Sticky header** — header che si trasforma allo scorrimento (classe `is-sticky` aggiunta oltre una soglia).
- **Torna su** — pulsante torna su, visibile da un certo punto di scroll.
- **Skin banner cookie** — re-skinning del banner cookie nativo per allinearlo al tuo brand.
- **Badge prodotto — Nuovo** — badge "Nuovo" sui prodotti creati di recente.
- **Barra spedizione gratuita** — barra di avanzamento spedizione gratuita in cima alla pagina.
- **Pulsanti arrotondati** — pulsanti arrotondati in tutto il negozio.
- **Evento GTM DOM-ready** — innesca un evento personalizzato non appena il DOM è pronto, per inizializzare i tuoi data layer.
- **Fade-in allo scorrimento** — apparizione progressiva degli elementi allo scroll.

Cliccare su **Installa** crea il container e i suoi snippet nel database. Resta solo da ricompilare il tema per vederli online. I container creati a partire da un preset sono container come gli altri: puoi modificarli, ampliarli, disattivarli, eliminarli.

## Importazione / Esportazione JSON

Per migrare snippet tra ambienti (dev, staging, produzione) o tra negozi:

1. **Esportazione** — seleziona uno o più container nell'elenco (caselle), poi clicca su **Esporta**. Viene scaricato un file JSON, che contiene tutti i container selezionati con i loro snippet, la loro priorità, le loro note — e il numero di versione del formato (`EXPORT_VERSION = 1`) per la retrocompatibilità.
2. **Importazione** — sull'ambiente di destinazione, clicca su **Importa** e seleziona il file JSON. I container e gli snippet vengono ricreati identici.

L'importazione non tocca i container esistenti (nessuna fusione per nome): crea sempre nuove voci. Se vuoi sovrascrivere un container esistente, eliminalo manualmente prima di importare.

## Validazione sintattica

Il pulsante ✓ **Valida sintassi** su ogni card snippet innesca una validazione lato server senza salvare nulla. A seconda del tipo:

- **SCSS** — il plugin lancia una **compilazione a vuoto** tramite `scssphp/scssphp` iniettando il preambolo delle variabili del tema. Se la compilazione passa, lo snippet è valido. Altrimenti, gli errori sono riportati in una zona di errore sulla card (numero di riga, messaggio).
- **JavaScript** — il plugin pulisce il codice da stringhe e commenti, poi verifica l'**equilibrio delle parentesi graffe** `{}`, **tonde** `()` e **quadre** `[]`. Questo check non sostituisce un vero parser ECMAScript, ma cattura il 90 % degli errori di copia-incolla (parentesi dimenticata, stringa mal chiusa). Per andare oltre, valida il tuo JavaScript in uno strumento dedicato prima di incollarlo.

## Architettura tecnica

Per gli sviluppatori che vogliono capire o estendere il plugin:

- **Namespace PHP radice**: `DataFirefly` (sub-namespace: `CustomCodeManager`, classi sotto `src/`).
- **Plugin class**: `DfCustomCodeManager` (estende `ShopwareCoreFrameworkPlugin`).
- **Prefisso SystemConfig**: `DfCustomCodeManager.config.*`.
- **Tabelle**: `df_ccm_container`, `df_ccm_container_sales_channel`, `df_ccm_snippet`, `df_ccm_snippet_version`.
- **Migrations**: `Migration1779580800CreateCcmContainerTable`, `Migration1779580801CreateCcmSnippetTable`, `Migration1779580802CreateCcmSnippetVersionTable`.
- **Services**: `CodeCompiler` (orchestrazione + cache), `SnippetExporter` (importazione/esportazione JSON), `SnippetValidator` (validazione sintattica), `VersionTracker` (snapshot + restore + trim).
- **Subscribers**: `ThemeCompilerSubscriber` (i 3 eventi di compilazione), `SnippetWrittenSubscriber` (snapshot automatico in scrittura).
- **Route API private** sotto `/api/_action/df-ccm/` (scope `api`): `validate`, `export`, `import`, `restore-version`, `recompile`, `presets`.

Tutte le dichiarazioni di service sono esplicite in `services.xml` (nessun autowiring) per rimanere allineate alle convenzioni DataFirefly.

## Estendere il modulo di amministrazione

Il modulo di amministrazione è compilato e collocato sotto `Resources/public/administration/js/df-custom-code-manager.js`. È **precompilato nello ZIP** e non richiede **alcun build locale**. Per estenderlo, individua i componenti (`df-ccm-list`, `df-ccm-detail`, `df-ccm-snippet-card`, `df-ccm-code-field`, `df-ccm-preset-modal`, `df-ccm-version-modal`) e personalizza tramite il sistema di override standard di Shopware (`Component.override`).

## FAQ e risoluzione dei problemi

**I miei snippet non appaiono nello storefront.** Hai ricompilato il tema? Finché `theme:compile` non è stato eseguito dopo una modifica, nulla cambia. Verifica anche che il container e lo snippet siano attivi, che il canale di vendita interessato sia nell'ambito (se l'ambito è ristretto), e che la modalità sicura non sia attivata.

**Errore di compilazione SCSS in console dopo theme:compile.** Il più delle volte è una variabile del tema che non esiste (errore di battitura) o uno snippet SCSS che apre un blocco senza chiuderlo. Disattiva lo snippet incriminato, ricompila per confermare, poi correggi con calma. La validazione sintattica sulla card snippet cattura la maggior parte di questi casi prima del salvataggio.

**Il menu Custom Code Manager non appare nell'amministrazione.** Esegui `bin/console assets:install && bin/console cache:clear` poi ricarica l'amministrazione con Ctrl+Shift+R. Il modulo è nel gruppo **Cataloghi**.

**L'editor di codice mostra una textarea senza evidenziazione.** È il fallback quando né `mt-code-editor` (6.7) né `sw-code-editor` (6.6) sono disponibili. Verifica la tua versione Shopware e che il modulo di amministrazione sia caricato correttamente.

**Voglio disattivare temporaneamente tutti gli snippet senza eliminare nulla.** È esattamente la modalità sicura. Toggle nella configurazione del plugin, ricompilazione, fatto.

**Il pulsante "Compila il tema" gira all'infinito.** Verifica i log Shopware. La compilazione può richiedere tempo su un tema grande; in caso di blocco reale, la causa abituale è uno snippet SCSS che cicla o contiene una variabile sconosciuta. Attiva la modalità sicura, ricompila, poi riattiva gli snippet uno a uno per identificare il colpevole.

**Il mio snippet JavaScript non si innesca.** Ricorda che il codice iniettato viene eseguito **nel bundle globale**, quindi in un contesto diverso da quello dei plugin JavaScript Shopware classici. Per interagire con i plugin JavaScript dello storefront, ascolta piuttosto `document.addEventListener('DOMContentLoaded', …)` o gli eventi globali che lo storefront emette.

**Cosa succede alla disinstallazione?** Al momento di `plugin:uninstall`, Shopware mostra la casella standard **Conserva i dati utente**. Se è **deselezionata**, il plugin elimina le sue 4 tabelle e tutti i dati associati (container, snippet, versioni, collegamenti canale). Se è **selezionata**, le tabelle restano in posizione e ritroverai i tuoi snippet se reinstalli il plugin in seguito.
