Theming 1200x628

Icinga Web 2 é un potente framework PHP per applicazioni web, caratterizzato da un design minimale. É veloce, responsive, user-friendly e facilmente estensibile attraverso l’installazione di moduli. Puó essere facilmente installato seguendo la veloce procedura di configurazione che si trova sul repository ufficiale (vedi riferimento alla fine del blog).

In aggiunta alle configurazioni di sitema, ogni utente puó settare delle personalizzazioni come la lingua, la time-zone ed il tema preferito. Lo scopo di questo articolo é quello di illustrare come creare un nuovo tema completamente custom, che permetta di personalizzare l’interfaccia di Icinga e renderla esattamente come desideriamo.

Iniziamo dalla basi. Uno stile é un insieme di attributi che caratterizzano l’aspetto e il formato di una schermata o di una finestra. Uno stile puó determinare attributi quali altezza, padding, colore e grandezza del testo, colore di sfondo e molto altro. Un tema é uno stile applicato all’intero software o app. Quando uno stile viene utilizzato come tema, ogni schermata nel prodotto sará caratterizzata dalle regole che lo compongono.

Icinga Web 2 si basa su Less. Less é un linguaggio di pre-processing per CSS, ció significa che estende il classico CSS aggiungendo features come le variabili, i mixins (parti di codice che possono essere riutilizzati e inclusi in altri elementi), le funzioni e moltre altre tecniche che permettono di rendere la scrittura di codice CSS piú facile da estendere, da utilizzare per la creazione di temi e da migliorare nel tempo. Icinga Web 2 compilerá in automatico i file .less, che saranno quindi letti e processato dal browser come normali file CSS.

La cartella /themes/

Tutti i file di tema di Icinga Web 2 sono contenuti nella cartella /public/, suddivisi nella diverse sottocartelle: css, js, font e images. Nella cartella /public/css/themes/ potrai trovare il tema principale che viene automaticamente caricato dal sistema. Creare un nuovo .less file nella cartella themes é probabilmente il modo piú semplice per personalizzare la propria interfaccia. Questo metodo é l’ideale se si vogliono semplicemente cambiare i colori e il logo nell’interfaccia web. In questo caso basterá copiare ed incollare le variabili utilizzate per i colori e il logo e settare i valori che si preferisce.

@icinga-blue: #4CAF50;
@gray-lighter: #BDBDBD;
@link-color: #388E3C; 

#icinga-logo {   
    background-image: url('../img/your_theme/your_logo.png');
}

Per esempio, se creiamo un file chiamato nostro_tema.less e copiamo e incollamo in tale file il codice sopra indicato, potremo facilmente ottenera una versione verde dell’interfaccia di Icinga. In altre parole partendo da

Icinga blue

otterrai

Icinga green

Ti consiglio di utilizzare il singolo file di tema per piccole personalizzazioni. Ma nel caso in cui volessi completamente modificare la grafica?!

Importazione di piú file di tema

In un grande progetto CSS é importante strutturare il codice in maniera ordinata e chiara. Per questo motivo ti consiglio di creare una cartella personalizzata in /public/css/ con il nome del nuovo tema e salvare in questa tutti i file di stile. In questo caso peró Icinga non includerá in automatico i file di tema.

Diversamente da quanto il linguaggio Less permette di fare, in nel progetto di Icinga Web la funzione @import é stata disabilitata. Questo significa che ti servirá caricare manualmente i nuovi file di stile. A questo scopo risulta necessario modificare il file StyleSheet.php. Questo file si trova nella cartella /usr/share/php/Icinga/Web/ e contiene un lungo array all’interno del quale sono inseriti tutti i file di tema.

 /**
 * Array of core LESS files Web 2 sends to the client
 *
 * @var string[]
 */
 protected static $lessFiles = array(
 '../application/fonts/fontello-ifont/css/ifont-embedded.css',
 'css/vendor/normalize.css',
 'css/vendor/tipsy.css',
 'css/icinga/base.less',
 'css/icinga/badges.less',
 'css/icinga/mixins.less',
 'css/icinga/grid.less',
 'css/icinga/nav.less',
 'css/icinga/main.less',
 'css/icinga/animation.less',
 'css/icinga/layout.less',
 'css/icinga/layout-structure.less',
 'css/icinga/menu.less',
 'css/icinga/tabs.less',
 'css/icinga/forms.less',
 'css/icinga/setup.less',
 'css/icinga/widgets.less',
 'css/icinga/login.less',
 'css/icinga/about.less',
 'css/icinga/controls.less',
 'css/icinga/dev.less',
 'css/icinga/spinner.less',
 'css/icinga/compat.less',
 'css/icinga/print.less',
 'css/icinga/responsive.less',
 );

Ti sará sufficiente aggiungere in coda i file del tema custom.

/**
 * Array of core LESS files Web 2 sends to the client
 *
 * @var string[]
 */
 protected static $lessFiles = array(
 '../application/fonts/fontello-ifont/css/ifont-embedded.css',
 'css/vendor/normalize.css',
 'css/vendor/tipsy.css',
 'css/icinga/base.less',
 'css/icinga/badges.less',
 'css/icinga/mixins.less',
 'css/icinga/grid.less',
 'css/icinga/nav.less',
 'css/icinga/main.less',
 'css/icinga/animation.less',
 'css/icinga/layout.less',
 'css/icinga/layout-structure.less',
 'css/icinga/menu.less',
 'css/icinga/tabs.less',
 'css/icinga/forms.less',
 'css/icinga/setup.less',
 'css/icinga/widgets.less',
 'css/icinga/login.less',
 'css/icinga/about.less',
 'css/icinga/controls.less',
 'css/icinga/dev.less',
 'css/icinga/spinner.less',
 'css/icinga/compat.less',
 'css/icinga/print.less',
 'css/icinga/responsive.less',

 'css/your_theme/mixins.less',
 'css/your_theme/nav.less',
 'css/your_theme/base.less',
 'css/your_theme/menu.less',
 'css/your_theme/layout.less',
 'css/your_theme/tabs.less',
 'css/your_theme/main.less',
 'css/your_theme/forms.less',
 'css/your_theme/login.less',
 'css/your_theme/controls.less',
 );

Struttura per un tema custom

Ti suggerisco di mantenere la stessa struttura utilizzata nel tema di Icinga Web. In altre parole, dovresti creare dei file con lo stesso nome utilizzato nel tema Icinga e inserire in essi le regole di stile per gli elementi ad essi assegnati da Icinga.

Per fare questo basta intercettare il tag HTML utilizzato dal sistema e cercare dove viene creato lo stile per l’elemento. Per riuscire ad analizzare facilmente gli elementi dell’interfaccia web ti consiglio di disabilitare il reload automatico della pagina: posizionati sulla barra di ricerca, premi SHIFT + TAB finché non ti comparirá il messaggio “Disable auto refresh”, a questo punto premendo INVIO il reload sará disabilitato.

In questo modo ti sará piú facile individuare dove lo stile dei diversi componenti viene creato, mantenere una struttura del codice piú ordinata e sará piú facile capire la struttura del tema.

Per esempio nelle immagini seguenti si possono vedere le sostanziali differenze fra il tema di default di Icinga e il tema che ho creato per il NetEye.

Icinga vs NetEye

Per creare questa customizzazione avanzata ho utilizzato il file menu.less. Il mockup grafico prevedeva un completo restyling della sezione user del menu: in particolare la voce user-settings sarebbe dovuta diventare un’icona ad ingranaggio e il menu di logout un classico bottone on/off, i due sotto menu sarebbero dovuti apparire come sempre visibili accanto al nome utente. La sezione utente in altre parole sarebbe diventata il “footer” della sidebar e sopra di essa sarebbe dovuto comparire il logo NetEye.

Analizziamo ora il codice creato a questo scopo. Questo ci permetterá di capire cosa io intenda per “resettare” lo stile di Icinga e ristrutturare i diversi elementi del tema.

// This first level part is used for styling the <ul class="nav nav-level-1"><li class="nav-item user-nav-item"> element
.first-level-item {
    position: fixed;
    bottom: 0;
    height: 3.5em;
    width: 16em;
    padding: 0 .5em;
    display: flex;
    align-items: center;
    justify-content: space-between;

    border-left: none; // remove border for the .active state
    border-right: 1px solid @menu-user-settings-border; // Custom color variables
    border-top: 1px solid @menu-user-settings-border;
    background-color: @menu-user-settings-background;
    &:before { // hide the triangle
        display: none;
    }
    > a {
        .ellipsis(); // used for cutting long username
        display: inline-block;
        padding: 0 .5em 0 0;
        font-size: 12px;
		// hiding icon and other images
        .icon-user {
            display: none;
        }
        &::before {
            display: none;
        }
    }
}

// The second level class attaches the settings and logout sub-menu
// <ul class="nav nav-level-2"><li class="nav-item no-icon">

.second-level {
    // resetting Icinga style
    position: static;
    width: auto;
    padding: 0;
    background-color: transparent;
    color: inherit;
    line-height: initial;

    display: inline-block;
    white-space: nowrap;
    a::before {
        display: none;
    }
}
.second-level-item {
    // resetting Icinga style
    display: inline-block;
    width: auto;
    margin: 0;
    background-color: transparent;
	// account & logout links
    > a {
        width: 27px;
        height: 24px;
        padding: 5px;

        // hiding item label
        text-indent: 200%;
        overflow: hidden;
        background-repeat: no-repeat;
        background-origin: content-box;
        &:before{
            display: none;
        }
    }
    &:nth-child(1) a {
		// setting the cog image (base 64) as background for the settings link
        background-image: url("data:image/svg xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 200 160'%3E%3Cpath d='...' fill='%23afafaf'%3E%3C/path%3E%3C/svg%3E");
    }
    &:nth-child(2) a {
		// setting the shutdown button as background for logout button
        background-image: url("data:image/svg xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 200 160'%3E%3Cpath d='...' fill='%23e65456'%3E%3C/path%3E%3C/svg%3E");
    }
}

// applying the before define style to Icinga menu elements
body #menu .nav-level-1 > .user-nav-item {
    .first-level-item();
    &.hover, &.active, &:hover {
        .first-level-item();
        .nav-level-2 {
            .second-level();
            .nav-item {
                .second-level-item();
            }
        }
    }
    .nav-level-2 {
        .second-level();
        .nav-item {
            .second-level-item();
        }
    }
}

Come si puó vedere dal codice sopra riportato, attraverso questo theming avanzato potrai portare Icinga ad avere un’interfaccia grafica che davvreo soddisfi le tue necessitá. Personalizzare l’interfaccia solo attraverso l’uso di codice css, rispetto alla modifica diretta della struttura delle pagine PHP, permette una piú facile manutenzione del prodotto, infatti in caso di aggiornamenti o modifiche delle funzioni core del sistema non ci si dovrá occupare di riportare le personalizzazioni apportate a livello di interfaccia.

Differenti versioni per il tuo nuovo tema custom

E se il mockup grafico prevedesse diversi temi/colori? A questo punto ti suggerisco di utilizzare della variabili custom per i colori. Come puoi vedere dal codice seguente, io ho sostituito le variabili default di Icinga con alcuni valori personalizzati:

menu.less
#header-logo-container {
 background-color: @customer-logo-background;
 border-bottom: 1px solid @customer-logo-border;
 border-right: 1px solid @customer-logo-border;
}
#header-logo {
 background-image: url( @customer-logo-url );
}
/* Customer logo end */

#menu {
 height: 100%;
 background-color: @menu-background;
 border-right: 1px solid @menu-border;
}

In questo modo si potranno aggiungere tanti temi quanti si desidera nella cartella /public/css/themes/ e passare da uno all’altro in modo facile e veloce attraverso le impostazioni utente di Icinga. Di seguito un esempio dei temi light e dark che ho creato: in questi casi ho semplicemente assegnato colori diversi alle variabili. Allo stesso modo é possibile variare il logo, se fosse necessario avere differenti combinazioni di colori in base al tema scelto.

light-theme.less
// Customer logo style
@customer-logo-url: "../img/your-theme/logo-light.svg";
@customer-logo-background: @white;
@customer-logo-border: @gray-lighter;

// Menu general style
@menu-background: @white;
@menu-border: @gray-lighter;
dark-theme.less
// Customer logo style
@customer-logo-url: "../img/your-theme/logo-dark.svg";
@customer-logo-background: @icinga-blue;
@customer-logo-border: @icinga-blue;

// Menu general style
@menu-background: @grey-dark;
@menu-border: @grey-dark;

Ora tocca a te!

Ora conosci il procedimento necessario per la customizzazione dell’interfaccia:

  1. Analizza l’elemento che desideri personalizzare
  2. Identifica il corrispondente tag
  3. Individua lo stile di questo elemento dei file di tema (.less) di Icinga
  4. Crea la cartella per il tuo tema, contenente i file con lo stesso nome utilizzato da Icinga
  5. Aggiungi questi file allo StyleSheet.php file
  6. Personalizza l’interfaccia come desideri

Ripeti la medesima procedura per ogni componente che desideri modificare.

… Benfatto! Hai finalmente personalizzato il template di Icinga. Spero che questa breve guida ti possa aiutare nei tuoi futuri lavori. La personalizzazione qui presentata puó risultare abbastanza semplice, ma ricorda: il processo di modifica e customizzazione é sempre lostesso, non importa quanto complicato possa sembrare il mockup grafico da riprodurre.

Risorse

Icinga Web 2 Repository:

https://docs.icinga.com/icinga2/latest/doc/icingaweb/chapter/installation

Valentina Da Rold

Valentina Da Rold

Hi, I'm Valentina and I'm a Frontend Developer at Wuerth Phoenix. I started out my career applying my Cryptography skills to coding, but really quickly fell in love with the web. I have been making websites and applications since 2012 and I still can't get enough of it. Along the way I found a passion for front-end development, and I use this passion to create interfaces that solve problems. When I'm not creating beautiful solutions, I enjoy cooking or doing sport, while listening to beautiful music.
Valentina Da Rold

Latest posts by Valentina Da Rold (see all)

Tags: , , , , , ,