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_css, 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_backgroundSolo body.welcome-anonymous (.page-anonymous resta trasparente)Mirare a body.login-page, che non esiste nell'11
Logo dell'intestazioneinternal_pictureCSS nel <head> via add_cssConfonderlo 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/ajax/module_ajax.php?module=branding&file=branding.picture.send.php&path=...") !important;
  width: 240px !important;
  height: 130px !important;
  object-fit: contain !important;   /* preserva le proporzioni dell'immagine */
}

/* Lo sfondo va SOLO su body.welcome-anonymous - MAI su body.login-page.
   Dipingere anche .page-anonymous (figlio diretto) duplicava la grafica sui bordi. */
body.welcome-anonymous {
  background-image: url("...") !important;
  background-size: cover !important;            /* oppure contain, o 100% 100% (allungare) */
  background-position: center center !important;
  background-repeat: no-repeat !important;
  background-attachment: fixed !important;      /* misurato sulla finestra, non sulla pagina */
}
.page-anonymous { background-image: none !important; background-color: transparent !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, webp; l'SVG è stato escluso nella versione 1.4.0) e il tipo reale del file viene verificato dal contenuto, 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 casuale generato dal server, senza riutilizzare il nome inviato, per non collidere né sovrascrivere. Nelle pagine interne, già autenticate, i colori, il logo dell'intestazione e il footer nascosto entrano come CSS nel <head> tramite l'hook add_css, mentre favicon, titolo e footer personalizzato entrano 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=31536000, immutable (un anno: ogni upload crea un file con un nome nuovo), 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. Attivi il modulo Branding nel catalogo dei moduli NexTool.
  2. Nella scheda Configurazione, carichi il favicon, il logo di login e il logo dell'intestazione; imposti larghezza e altezza di ogni logo (accetta px, em, rem, %, vw, vh).
  3. Carichi lo sfondo della schermata di login e regoli il titolo della scheda del browser.
  4. Scelga il comportamento del piè di pagina: mantenere l'originale, nasconderlo o sostituirlo con del testo (HTML limitato a tag sicuri).
  5. Opzionale: imposti i colori dell'interfaccia tramite variabili CSS (il modulo valida ogni valore come hex prima di emetterlo, prevenendo la CSS injection). Ricarichi 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 ed eliminazione di immagini nel dettaglio), 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.
  • L'SVG non è accettato - dalla versione 1.4.0 il modulo rifiuta l'SVG per il logo e la favicon, perché il formato può portare script incorporato e le immagini del modulo sono servite senza login. Per il logo va bene il PNG con sfondo trasparente (o il WEBP), per la favicon PNG o ICO; il server verifica il contenuto reale del file, quindi anche un SVG rinominato in .png viene rifiutato.
  • 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 si aspetta.
  • 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 lo verifichi 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. Tratti il branding come parte del piano di upgrade, non come una sorpresa post-migrazione.

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


Revisionato dal team 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_css, 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, carichi l'immagine del favicon e scriva 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.

No. Dalla versione 1.4.0 il modulo rifiuta l'SVG per il logo e la favicon, perché il formato può contenere script incorporato e le immagini del modulo sono servite senza login. Per il logo va bene il PNG con sfondo trasparente (o il WEBP), per la favicon PNG o ICO. L'upload verifica il contenuto reale del file e il servizio protegge dal path traversal.

Branding è gratuito e fa parte di NexTool, ma funziona solo su GLPI 11: non esiste una versione per GLPI 10. 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); lo riapplichi tramite il modulo dopo la migrazione.

Hai bisogno di aiuto?