GLPI-Corporate-Design anpassen mit dem Modul Branding

Branding im GLPI, das Updates übersteht: warum das Bearbeiten des Core die Marke beim Update löscht, das tatsächliche DOM der Anmeldeseite in GLPI 11 (span.glpi-logo, body.welcome-anonymous), das CSS, das das Modul per Hook einfügt, SQL für die Prüfung und die Fallstricke aus der Praxis.

In diesem Artikel7 Abschnitte

Das GLPI-Logo auszutauschen wirkt wie eine Fünf-Minuten-Anpassung - bis das nächste Update alles löscht. Das Corporate Design durch Bearbeiten des Core-CSS oder des Anmelde-Templates anzupassen, funktioniert am selben Tag, ist aber eine Schuld, die von selbst fällig wird: Es verschwindet beim Update, und beim Sprung von GLPI 10 auf 11 wurde das DOM der Anmeldeseite umbenannt, sodass der alte Hack nicht mehr greift, ohne irgendeinen Fehler auszulösen. Dieser Leitfaden zeigt, wie Sie Branding umsetzen, das Updates übersteht, wo jedes Element in GLPI 11 liegt und welche Fallstricke erst in Kundenumgebungen auftauchen.

Branding im GLPI ist nicht nur Ästhetik

Ein GLPI im Erscheinungsbild der Organisation reduziert Reibung: Der Endanwender erkennt, dass es sich um den Service Desk des Unternehmens handelt und nicht um ein fremdes System, das eine Anmeldung verlangt. Die versteckten Kosten liegen aber nicht in der Wahl der richtigen Farbe - sondern darin, wie die Anpassung angewendet wird. Es gibt drei Wege, und zwei davon werden später teuer.

  • Den Core bearbeiten (CSS, Bilder oder Templates in glpi/css, glpi/pics oder templates/): Das funktioniert, aber der nächste git pull oder das Entpacken des Releases überschreibt die Dateien. Die Anpassung verschwindet, und niemand erinnert sich, warum.
  • Von außen eingefügtes Theme/CSS: Übersteht das Update der Dateien, bleibt aber an die Selektoren der Version gebunden. Wenn GLPI die HTML-Struktur ändert - wie von 10 auf 11 geschehen -, existiert der Selektor nicht mehr und das CSS wird stillschweigend wirkungslos.
  • Plugin-Hook: GLPI bietet offizielle Einfügepunkte (display_login, add_css, add_javascript). Das Modul wendet die Marke über diese Hooks an, ohne eine einzige Datei des Core anzufassen. Es ist der einzige Weg, der Updates konstruktionsbedingt übersteht.

Was sich anpassen lässt - und wo jedes Element liegt

Jedes visuelle Element des GLPI liegt an einer anderen Stelle im DOM, und Änderungen ohne Kenntnis des richtigen Ziels erzeugen die meisten Tickets nach dem Muster „geändert, aber nichts zu sehen“. Die folgende Matrix ordnet jedem Element seinen Konfigurationsschlüssel und den tatsächlichen Mechanismus in GLPI 11 zu:

ElementKonfigurationsschlüsselMechanismus in GLPI 11Häufiger Fallstrick
Faviconfavicon_picture<link rel="icon"> per JS neu geschriebenAggressiver Browser-Cache hält das alte Icon fest
Tab-Titelpage_titledocument.titleSeiten, die ihren eigenen Titel setzen, überschreiben ihn wieder
Anmelde-Logologin_picturespan.glpi-logo über content: url(...).login-logo ansprechen, das es in 11 nicht gibt
Anmelde-Hintergrundlogin_backgroundNur body.welcome-anonymous (.page-anonymous bleibt transparent)body.login-page ansprechen, das es in 11 nicht gibt
Header-Logointernal_pictureCSS im <head> über add_cssVerwechslung mit dem Anmelde-Logo (unterschiedliche Ziele)
Fußzeilefooter_mode / footer_text.copyright (Standard-Theme von 11)Nicht bereinigtes HTML in den benutzerdefinierten Text einfügen
Oberflächenfarbencolor_*Tabler-CSS-Variablen (--tblr-*)Einen Nicht-Hex-Wert übergeben und fehlerhaftes CSS einfügen

Der Fallstrick in GLPI 11: Das Anmelde-Logo ist kein Hintergrund

Im Betrieb von Kundenumgebungen lautet das klassische Ticket: „Wir haben GLPI aktualisiert und die Anmeldeseite ist wieder im Standard.“ Fast immer liegt die Ursache in einer Anpassung direkt im Core oder in einem CSS, das auf die Selektoren von GLPI 10 zielte. Beim Sprung auf 11 wurde das Template der Anmeldeseite (page_card_notlogged.html.twig) neu geschrieben: Aus dem <body> wurde body.welcome-anonymous, aus dem Container .page-anonymous, und das Logo ist kein Hintergrundbild mehr - es ist jetzt ein <span class="glpi-logo">, gerendert über content: var(--logo). Wir haben das am 10. Juni 2026 in der Praxis entdeckt, als wir untersuchten, warum der Anmelde-Hintergrund eines Kunden nach dem Upgrade schlicht nicht angewendet wurde: Der alte Selektor body.login-page existierte im DOM nicht mehr. Im Log gab es keinen Fehler - das CSS war korrekt für eine Version, die nicht mehr lief. Deshalb geben wir die richtigen Selektoren seitdem per Hook aus, versioniert zusammen mit dem Modul. Dies ist das tatsächliche CSS, das das Modul einfügt - und die toten Selektoren, die das Verschwinden erklären:

/* GLPI 11 - seletores REAIS da tela de login (page_card_notlogged.html.twig) */
/* O logo NAO e background: e um <span class="glpi-logo"> com 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 a proporcao da imagem */
}

/* O fundo vai SO no body.welcome-anonymous - NUNCA em body.login-page.
   Pintar tambem o .page-anonymous (filho direto) duplicava a arte nas bordas. */
body.welcome-anonymous {
  background-image: url("...") !important;
  background-size: cover !important;            /* ou contain, ou 100% 100% (esticar) */
  background-position: center center !important;
  background-repeat: no-repeat !important;
  background-attachment: fixed !important;      /* mede pela janela, nao pela pagina */
}
.page-anonymous { background-image: none !important; background-color: transparent !important; }

/* Seletores do GLPI 10 que NAO existem mais no 11 (por isso o hack antigo some sem erro):
   .login-logo      -> agora e span.glpi-logo
   body.login-page  -> agora e body.welcome-anonymous  */

Wie das Modul die Anpassung anwendet, ohne den Core anzufassen

Auf der Anmeldeseite gibt es keine Sitzung, daher hängt sich das Modul an den Hook display_login und fügt einen Inline-Block <style>/<script> ein. Die Bilder (Favicon, Logo, Hintergrund) werden über einen zustandslosen Endpunkt ausgeliefert, der keine Anmeldung erfordert, mit drei Schutzmaßnahmen, die erwähnenswert sind, weil genau dort unachtsame Plugins Lücken haben: Die Dateiendung läuft durch eine Whitelist (png, jpg, jpeg, gif, ico, webp; SVG wurde in Version 1.4.0 entfernt) und der tatsächliche Dateityp wird anhand des Inhalts geprüft, der Pfad wird mit realpath() aufgelöst und gegen das Präfix des Upload-Verzeichnisses geprüft (Schutz vor Path Traversal), und die Datei wird unter einem vom Server erzeugten Zufallsnamen gespeichert, ohne den übermittelten Namen zu übernehmen, damit nichts kollidiert oder überschrieben wird. Auf den internen, bereits authentifizierten Seiten kommen Farben, Header-Logo und ausgeblendete Fußzeile als CSS im <head> über den Hook add_css, Favicon, Titel und benutzerdefinierte Fußzeile über den Hook add_javascript.

Ein Performance-Detail, das erst beim Messen sichtbar wird: Das interne JS wird mit Cache-Control: private, max-age=86400 ausgeliefert und die Bilder mit public, max-age=31536000, immutable (ein Jahr: Jeder Upload erzeugt eine Datei mit neuem Namen), aber ohne ETag. Der Grund ist konkret - mit ETag und max-age zusammen revalidierte Chrome (HTTP 304) bei jedem Seitenaufruf, und jedes 304 kostete auf dem Server trotzdem den vollständigen Bootstrap von GLPI. Ein Hash der Konfiguration fließt in den URL-Parameter fv= ein, sodass das Speichern der Konfiguration die URL ändert und den Cache sofort invalidiert, ohne dass eine Revalidierung nötig ist.

Konfiguration in fünf Schritten

  1. Aktivieren Sie das Modul Branding im Modulkatalog von NexTool.
  2. Laden Sie auf dem Reiter Einstellungen das Favicon, das Anmelde-Logo und das Header-Logo hoch; legen Sie Breite und Höhe jedes Logos fest (akzeptiert px, em, rem, %, vw, vh).
  3. Laden Sie den Hintergrund der Anmeldeseite hoch und passen Sie den Titel des Browser-Tabs an.
  4. Wählen Sie das Verhalten der Fußzeile: Original beibehalten, ausblenden oder durch Text ersetzen (HTML beschränkt auf sichere Tags).
  5. Optional: Legen Sie die Oberflächenfarben über CSS-Variablen fest (das Modul prüft jeden Wert vor der Ausgabe als Hex-Wert und verhindert so CSS Injection). Laden Sie GLPI neu, um das Ergebnis zu sehen.

Prüfprotokoll: Wer hat was geändert

Jede Aktion - aktivieren, deaktivieren, Konfiguration speichern, Bild hochladen oder löschen - wird in einer Log-Tabelle des Moduls gespeichert. In Umgebungen mit mehr als einem Administrator beantwortet diese Spur die Frage „Wer hat am Freitagabend das Logo getauscht?“, ohne sich auf das Gedächtnis verlassen zu müssen. Die Diagnoseabfrage:

-- Trilha de auditoria do modulo Branding: quem mudou a identidade visual e quando
SELECT l.date_creation  AS quando,
       u.name           AS usuario,
       l.action         AS acao,     -- save_config (envio e exclusao de imagem vao no detalhe), toggle_enable/disable
       l.detail         AS detalhe
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;

Fallstricke aus der Praxis

  • Favicon, das sich nicht ändert - der Browser cacht Favicons aggressiv, pro Tab und pro Sitzung. Nach dem Hochladen des neuen Icons helfen ein Hard Refresh (Strg+Umschalt+R) oder das Schließen und erneute Öffnen des Tabs; das ist kein Fehler des Moduls.
  • SVG wird nicht akzeptiert - seit Version 1.4.0 lehnt das Modul SVG für Logo und Favicon ab, weil das Format eingebettetes Script enthalten kann und die Bilder des Moduls ohne Anmeldung ausgeliefert werden. Verwenden Sie PNG mit transparentem Hintergrund (oder WEBP) für das Logo und PNG oder ICO für das Favicon; der Server prüft den tatsächlichen Inhalt der Datei, daher wird auch ein in .png umbenanntes SVG abgelehnt.
  • Fußzeile mit eingefügtem HTML - der benutzerdefinierte Fußzeilentext durchläuft eine Bereinigung, die nur eine Handvoll Tags erlaubt (a, b, strong, i, em, span, br). Ein kompletter Marketing-HTML-Block wird schlicht nicht so gerendert, wie Sie es erwarten.
  • Seitenverhältnis des Logos - feste Breite und Höhe ohne Rücksicht auf das ursprüngliche Seitenverhältnis verzerren das Bild. Das Modul wendet genau deshalb object-fit: contain an, um nichts zu strecken, aber eine Kontrolle auf dem Bildschirm lohnt sich.
  • Upgrade von 10 auf 11 - wenn der Kunde bereits manuelles Branding in GLPI 10 hatte, verschwindet es in 11 wegen der geänderten Selektoren. Behandeln Sie das Branding als Teil des Upgrade-Plans, nicht als Überraschung nach der Migration.

Möchten Sie das Corporate Design des GLPI in allen von Ihnen verwalteten Umgebungen vereinheitlichen, ohne das Thema bei jedem Update neu aufzurollen? Das Modul Branding ist kostenlos und wendet die Marke über native Hooks an. Und wenn Sie Einführung und Betrieb des GLPI lieber auslagern möchten: NexTool betreut Kundenumgebungen mit versioniertem, updatesicherem Branding.


Geprüft vom Team der NexTool Solutions.

Häufig gestellte Fragen

Weil die Anpassung direkt im Core vorgenommen wurde (CSS-Dateien, Bilder oder Templates) und das GLPI-Update diese Dateien überschreibt. Um ein Update zu überstehen, muss die Marke über Plugin-Hooks (display_login, add_css, add_javascript) angewendet werden, ohne den Core anzufassen - genau dafür gibt es das Modul Branding.

In GLPI 11 wurde das Template der Anmeldeseite neu geschrieben. Das Logo ist kein Hintergrundbild mehr, sondern ein <span class="glpi-logo"> mit content: var(--logo); aus dem body wurde body.welcome-anonymous und aus dem Container .page-anonymous. Wenn das CSS auf die Selektoren von GLPI 10 (.login-logo, body.login-page) zielt, existieren diese im DOM nicht mehr und die Regel greift nicht, ohne einen Fehler auszulösen.

Nein. Das Modul Branding wendet Favicon, Logos, Anmelde-Hintergrund, Fußzeile und Farben über die Oberfläche an, mittels nativer Hooks. Die Änderungen liegen nicht in Dateien des Core und überstehen daher das GLPI-Update.

Laden Sie auf dem Reiter Einstellungen des Moduls das Favicon-Bild hoch und geben Sie den gewünschten Titel ein. Das Modul schreibt <link rel="icon"> und document.title per JavaScript neu. Wenn das neue Icon nicht erscheint, liegt es am Browser-Cache: Ein Hard Refresh (Strg+Umschalt+R) oder das erneute Öffnen des Tabs hilft.

Nein. Seit Version 1.4.0 lehnt das Modul SVG für Logo und Favicon ab, weil das Format eingebettetes Script enthalten kann und die Bilder des Moduls ohne Anmeldung ausgeliefert werden. Verwenden Sie PNG mit transparentem Hintergrund (oder WEBP) für das Logo und PNG oder ICO für das Favicon. Der Upload prüft den tatsächlichen Inhalt der Datei, und der Dienst schützt vor Path Traversal.

Branding ist kostenlos und Teil von NexTool, läuft aber nur in GLPI 11: Eine Version für GLPI 10 gibt es nicht. Achtung beim Upgrade: Wenn es in 10 manuelles Branding gab, wird es nicht automatisch nach 11 übernommen (die Selektoren der Anmeldeseite haben sich geändert); wenden Sie es nach der Migration über das Modul erneut an.

Brauchen Sie Hilfe?