Come personalizzare l'identità visiva di GLPI con il modulo Branding

Branding GLPI che sopravvive agli aggiornamenti: perché modificare il core cancella il marchio all'update, il DOM reale della schermata di login in GLPI 11 (span.glpi-logo, body.welcome-anonymous), il CSS che il modulo inietta tramite hook, una query SQL di audit e le insidie sul campo.

Cambiare il logo di GLPI sembra una modifica da cinque minuti - finché il prossimo aggiornamento non cancella tutto. Personalizzare l'identità visiva modificando il CSS del core o il template di login funziona oggi, ma è un debito che scade da solo: sparisce all'aggiornamento e, nel salto da GLPI 10 a 11, il DOM della schermata di login è stato rinominato, quindi il vecchio hack smette di applicarsi senza lanciare alcun errore. Questa guida mostra come fare branding che sopravvive agli aggiornamenti, dove vive ogni pezzo in GLPI 11 e le insidie che compaiono solo in ambiente cliente.

Il branding in GLPI non è solo estetica

Un GLPI con il volto dell'organizzazione riduce l'attrito: l'utente finale riconosce che è il Service Desk dell'azienda, e non un sistema strano che chiede il login. Ma il costo nascosto non sta nello scegliere il colore giusto - sta in come viene applicata la personalizzazione. Ci sono tre strade, e due di esse si pagano care dopo.

  • Modificare il core (CSS, immagini o template dentro glpi/css, glpi/pics o templates/): funziona, ma il prossimo git pull o l'estrazione della release sovrascrive i file. La personalizzazione evapora e nessuno ricorda perché.
  • Tema/CSS iniettato dall'esterno: sopravvive all'aggiornamento dei file, ma resta legato ai selettori di quella versione. Quando GLPI cambia la struttura HTML - come ha fatto dal 10 all'11 - il selettore non esiste più e il CSS diventa lettera morta, in silenzio.
  • Hook di plugin: GLPI espone punti di iniezione ufficiali (display_login, add_javascript). Il modulo applica il marchio tramite questi hook, senza toccare un solo file del core. È l'unica strada che sopravvive agli aggiornamenti per progettazione.

Cosa si può personalizzare - e dove vive ogni pezzo

Ogni elemento visivo di GLPI vive in un punto diverso del DOM, e cambiarlo senza conoscere il bersaglio giusto è ciò che genera la maggior parte dei ticket "l'ho cambiato e non è successo nulla". La matrice qui sotto mappa ogni pezzo alla sua chiave di configurazione e al meccanismo reale in GLPI 11:

PezzoChiave di configMeccanismo in GLPI 11Insidia comune
Faviconfavicon_picture<link rel="icon"> riscritto via JSLa cache aggressiva del browser trattiene la vecchia icona
Titolo della schedapage_titledocument.titleLe schermate che impostano il proprio titolo lo ripristinano
Logo del loginlogin_picturespan.glpi-logo via content: url(...)Mirare a .login-logo, che non esiste nell'11
Sfondo del loginlogin_backgroundbody.welcome-anonymous / .page-anonymousMirare a body.login-page, che non esiste nell'11
Logo dell'intestazioneinternal_pictureIntestazione interna via add_javascriptConfonderlo con il logo di login (bersagli distinti)
Piè di paginafooter_mode / footer_text.copyright (tema predefinito dell'11)Incollare HTML non sanitizzato nel testo personalizzato
Colori dell'interfacciacolor_*Variabili CSS Tabler (--tblr-*)Passare un valore non hex e iniettare CSS rotto

L'insidia di GLPI 11: il logo di login non è uno sfondo

Nella manutenzione di ambienti cliente, il ticket classico è: "abbiamo aggiornato GLPI e la schermata di login è tornata allo standard". La causa è quasi sempre una personalizzazione fatta direttamente nel core o in un CSS che puntava ai selettori di GLPI 10. Nel salto all'11, il template della schermata di login (page_card_notlogged.html.twig) è stato riscritto: il <body> è diventato body.welcome-anonymous, il contenitore è diventato .page-anonymous e il logo ha smesso di essere un'immagine di sfondo - ora è uno <span class="glpi-logo"> reso da content: var(--logo). L'abbiamo scoperto sul campo il 2026-06-10, indagando perché lo sfondo di login di un cliente semplicemente non si applicava dopo l'upgrade: il vecchio selettore body.login-page non esisteva più nel DOM. Nessun errore nel log - il CSS era corretto per una versione che non girava più. Per questo ora emettiamo i selettori giusti tramite hook, versionati insieme al modulo. Questo è il CSS reale che il modulo inietta - e i selettori morti che spiegano la scomparsa:

/* GLPI 11 - selettori REALI della schermata di login (page_card_notlogged.html.twig) */
/* Il logo NON e uno sfondo: e uno <span class="glpi-logo"> con content: var(--logo) */
.page-anonymous .glpi-logo {
  content: url("/plugins/nextool/front/module_assets.php?module=branding&file=...") !important;
  width: 240px !important;
  height: 130px !important;
  object-fit: contain !important;   /* preserva le proporzioni dell'immagine */
}

/* Lo sfondo va su body.welcome-anonymous / .page-anonymous - MAI su body.login-page */
body.welcome-anonymous,
.page-anonymous {
  background-image: url("...") !important;
  background-size: cover !important;
  background-position: center center !important;
}

/* Selettori di GLPI 10 che NON esistono piu nell'11 (perche il vecchio hack sparisce senza errore):
   .login-logo      -> ora e span.glpi-logo
   body.login-page  -> ora e body.welcome-anonymous  */

Come il modulo applica senza toccare il core

Nella schermata di login non c'è sessione, quindi il modulo si aggancia all'hook display_login e inietta un blocco <style>/<script> in linea. Le immagini (favicon, logo, sfondo) sono servite da un endpoint stateless che non richiede login, con tre protezioni che vale la pena nominare perché sono esattamente il punto in cui i plugin disattenti perdono dati: l'estensione passa per una whitelist (png, jpg, jpeg, gif, ico, svg, webp), il percorso è risolto con realpath() e verificato contro il prefisso della cartella di upload (blocco del path traversal), e il file è salvato con un nome univoco via uniqid() per non collidere né sovrascrivere. Nelle pagine interne, già autenticate, la personalizzazione entra tramite l'hook add_javascript.

Un dettaglio di prestazioni che compare solo misurando: il JS interno viaggia con Cache-Control: private, max-age=86400 e le immagini con public, max-age=604800 (una settimana), ma senza ETag. Il motivo è concreto - con ETag e max-age insieme, Chrome rivalidava (HTTP 304) a ogni caricamento di pagina, e ogni 304 pagava ancora il bootstrap completo di GLPI sul server. Un hash della configurazione entra nel parametro fv= dell'URL, quindi salvare la config cambia l'URL e invalida la cache all'istante, senza rivalidazione.

Configurazione in cinque passi

  1. Attiva il modulo Branding nel catalogo dei moduli NexTool.
  2. Nella scheda Configurazione, carica il favicon, il logo di login e il logo dell'intestazione; imposta larghezza e altezza di ogni logo (accetta px, em, rem, %, vw, vh).
  3. Carica lo sfondo della schermata di login e regola il titolo della scheda del browser.
  4. Scegli il comportamento del piè di pagina: mantenere l'originale, nasconderlo o sostituirlo con del testo (HTML limitato a tag sicuri).
  5. Opzionale: imposta i colori dell'interfaccia tramite variabili CSS (il modulo valida ogni valore come hex prima di emetterlo, prevenendo la CSS injection). Ricarica GLPI per vedere il risultato.

Audit: chi ha cambiato cosa

Ogni azione - attivare, disattivare, salvare config, caricare o eliminare un'immagine - viene registrata in una tabella di log del modulo. In un ambiente con più di un amministratore, questa traccia risponde a "chi ha cambiato il logo venerdì sera" senza dipendere dalla memoria. La query di diagnostica:

-- Traccia di audit del modulo Branding: chi ha cambiato l'identita visiva e quando
SELECT l.date_creation  AS quando,
       u.name           AS utente,
       l.action         AS azione,    -- save_config, upload_picture, delete_picture, toggle_enable/disable
       l.detail         AS dettaglio
FROM   glpi_plugin_nextool_branding_log l
LEFT   JOIN glpi_users u ON u.id = l.users_id
ORDER  BY l.date_creation DESC
LIMIT  20;

Insidie sul campo

  • Favicon che non cambia - il browser mette in cache il favicon in modo aggressivo, per scheda e per sessione. Dopo aver caricato la nuova icona, un hard refresh (Ctrl+Shift+R) o chiudere e riaprire la scheda risolve; non è un bug del modulo.
  • SVG da fonte affidabile - l'SVG è ottimo per un logo (si ingrandisce senza perdere nitidezza), ma può portare script incorporato. Usa SVG solo da grafica generata da te; l'endpoint serve il file con il Content-Type corretto, ma l'igiene inizia al momento dell'upload.
  • Piè di pagina con HTML incollato - il testo personalizzato del piè passa per una sanitizzazione che consente solo una manciata di tag (a, b, strong, i, em, span, br). Incollare un intero blocco di HTML di marketing semplicemente non renderà ciò che ti aspetti.
  • Proporzioni del logo - impostare larghezza e altezza fisse senza rispettare la proporzione originale distorce l'immagine. Il modulo applica object-fit: contain proprio per non stirare, ma verificalo a schermo.
  • Upgrade dal 10 all'11 - se il cliente aveva già un branding manuale su GLPI 10, sparisce nell'11 a causa dei selettori cambiati. Tratta il branding come parte del piano di upgrade, non come una sorpresa post-migrazione.

Vuoi standardizzare l'identità visiva di GLPI su tutti gli ambienti che amministri, senza riaprire l'argomento a ogni aggiornamento? Il modulo Branding è gratuito e applica il marchio tramite hook nativi. E se preferisci esternalizzare l'implementazione e la manutenzione di GLPI, NexTool mantiene ambienti cliente con branding versionato e a prova di aggiornamento.


Este conteúdo foi produzido com auxílio de inteligência artificial e revisado pela equipe Nextool Solutions.

Domande Frequenti

Perché la personalizzazione è stata fatta direttamente nel core (file CSS, immagini o template), e l'aggiornamento di GLPI sovrascrive quei file. Il modo per sopravvivere agli aggiornamenti è applicare il marchio tramite hook di plugin (display_login, add_javascript), senza toccare il core - ed è esattamente lo scopo del modulo Branding.

In GLPI 11 il template della schermata di login è stato riscritto. Il logo non è più un'immagine di sfondo; è diventato uno <span class="glpi-logo"> con content: var(--logo); il body è diventato body.welcome-anonymous e il contenitore .page-anonymous. Se il CSS punta ai selettori di GLPI 10 (.login-logo, body.login-page), non esistono più nel DOM e la regola non si applica, senza lanciare errore.

No. Il modulo Branding applica favicon, logo, sfondo di login, piè di pagina e colori tramite l'interfaccia, via hook nativi. Le modifiche non vivono nei file del core, quindi sopravvivono agli aggiornamenti di GLPI.

Nella scheda Configurazione del modulo, carica l'immagine del favicon e scrivi il titolo desiderato. Il modulo riscrive il <link rel="icon"> e il document.title via JavaScript. Se la nuova icona non appare, è la cache del browser: un hard refresh (Ctrl+Shift+R) o riaprire la scheda risolve.

Sì, l'SVG è accettato e si ingrandisce senza perdere nitidezza. L'upload passa per una whitelist di estensioni e il servizio protegge dal path traversal. Poiché l'SVG può contenere script incorporato, usa solo grafica da fonte affidabile (idealmente generata da te), non file di origine sconosciuta.

Sì. Branding è gratuito, fa parte di NexTool ed è compatibile con GLPI 10 e 11. Attenzione all'upgrade: se c'era un branding manuale sul 10, non migra da solo all'11 (i selettori della schermata di login sono cambiati); riapplicalo tramite il modulo dopo la migrazione.

Hai bisogno di aiuto?