§ 28. Breadcrumbs: lo script in PHP per il WordPress

Nel paragrafo precedente avevo descritto lo sviluppo di uno script universale per la creazione del menu breadcrumbs su un sito qualsiasi.
Questa volta, invece, propongo una soluzione sviluppata appositamente per i siti basati sul CMS WordPress: una funzione in PHP del menu breadcrumbs. Naturalmente, una cosa del genere potrebbe anche essere realizzata con uno dei numerosissimi plugin, ma nessuno di questi ultimi potrà garantirvi un risultato personalizzabile al 100%. Di conseguenza, vi propongo un codice PHP che funziona ugualmente bene sui siti di ogni grado di complessità e di ogni tipologia. Il risultato del codice – il menu breadcrumbs, appunto, – può essere personalizzato nel suo aspetto grafico attraverso le istruzioni del file degli stili CSS. Inoltre, alcuni aspetti del menu generato possono essere modificati nel codice della funzione PHP proposta.
Nel listing che segue pubblico subito il codice completo della funzione PHP che va inserita nel file functions.php del vostro tema.
Ma prima di fare spensieratamente il «copia e incolla», leggete queste poche considerazioni necessarie sulla personalizzazione del codice (vi faranno risparmiare un po’ di tempo e forze):
– riga 5 del mio listing: viene impostato il simbolo che separa le voci del menu breadcrumbs l’una dall’altra; nel mio esempio si usa il simbolo «>» (home > pagina 1 > pagina 2 etc.), mente voi, volendo, potete anche sostituirlo con quello che vi piace più;
– riga 6 e riga 7 del mio listing: sono i nomi dell’id e del class del menu che servono per la personalizzazione del suo aspetto grafico con il CSS, quindi controllate che non ci siano altri elementi con gli stessi nomi nel codice delle pagine del sito;
– riga 8 del mio listing: viene impostata la voce del menu che sarà linkata con l’indirizzo della prima pagina del sito, quindi al posto di Home potete anche scrivere quello che preferite («Prima pagina», «Sito di Mario Rossi» etc.);
– riga 11 del mio listing: nella variabile vanno aggiunti i nomi delle vostre eventuali tassonomie personali (se non ne avete, lasciate pure questa riga così come è ora);
– riga 20 del mio listing: il menu breadcrumbs generato con la funzione in questione viene trasformato in un elenco <ul> di link, ma se preferite avere il menu nel formato di un semplice testo con dei link, togliete pure questa riga (e non dimenticatevi di togliere anche la chiusura del tag <ul> alla riga 212; ovviamente a questo punto vi tocca di togliere dal codice della funzione anche tutti i tag <li>);
– il codice che sto per proporvi genera il menu breadcrumbs sulla base di tutta la gerarchia delle pagine fino alla corrente (senza linkare il nome di quest’ultima), tenendo conto anche di tutta la tassonomia del sito (quindi, per esempio, anche dei tag e delle categorie); i nomi di tutte le pagine elencate nel menu vengono automaticamente prese dal database del WordPress (tranne, come abbiamo visto, il nome della prima pagina del sito).
Bene, ora potete copiare il codice, inserirlo nel functions.php e fare le eventuali modifiche desiderate.

// menu breadcrumbs
function custom_breadcrumbs() {
 
    // Impostazioni
    $separator          = '&gt;'; // il separatore delle voci del menu
    $breadcrums_id      = 'breadcrumbs'; // id del contenitore
    $breadcrums_class   = 'breadcrumbs'; // class dei breadcrumbs
    $home_title         = 'Home'; // il nome della prima pagina del sito nel menu breadcrumbs
 
    // Se avete delle vostre tipologie della tassonomia, aggiungete il codice nella variabile della riga sotto (per esempio, product_cat per il Woocommerce)
    $custom_taxonomy    = 'product_cat';
 
    // La pagina e la interrogazione
    global $post,$wp_query;
 
    // Non mostrare sulla prima pagina del sito
    if ( !is_front_page() ) {
 
        // Inizia il menu breadcrumbs
        echo '<ul id="' . $breadcrums_id . '" class="' . $breadcrums_class . '">';
 
        // La prima pagina del sito
        echo '<li class="item-home"><a class="bread-link bread-home" href="' . get_home_url() . '" title="' . $home_title . '">' . $home_title . '</a></li>';
        echo '<li class="separator separator-home"> ' . $separator . ' </li>';
 
        if ( is_archive() && !is_tax() && !is_category() && !is_tag() ) {
            echo '<li class="item-current item-archive"><strong class="bread-current bread-archive">' . post_type_archive_title($prefix, false) . '</strong></li>';
 
        } else if ( is_archive() && is_tax() && !is_category() && !is_tag() ) {
 
             // Se la pubblicazione dovesse essere un altro tipo di contenuto (non una pagina o un articolo)
            $post_type = get_post_type();
 
            if($post_type != 'post') {
                $post_type_object = get_post_type_object($post_type);
                $post_type_archive = get_post_type_archive_link($post_type);
 
                echo '<li class="item-cat item-custom-post-type-' . $post_type . '"><a class="bread-cat bread-custom-post-type-' . $post_type . '" href="' . $post_type_archive . '" title="' . $post_type_object->labels->name . '">' . $post_type_object->labels->name . '</a></li>';
                echo '<li class="separator"> ' . $separator . ' </li>';
            }
 
            $custom_tax_name = get_queried_object()->name;
            echo '<li class="item-current item-archive"><strong class="bread-current bread-archive">' . $custom_tax_name . '</strong></li>';
 
        } else if ( is_single() ) {
 
            // Se la pubblicazione dovesse essere un altro tipo di contenuto (non una pagina o un articolo)
            $post_type = get_post_type();
 
            if($post_type != 'post') {
                $post_type_object = get_post_type_object($post_type);
                $post_type_archive = get_post_type_archive_link($post_type);
 
                echo '<li class="item-cat item-custom-post-type-' . $post_type . '"><a class="bread-cat bread-custom-post-type-' . $post_type . '" href="' . $post_type_archive . '" title="' . $post_type_object->labels->name . '">' . $post_type_object->labels->name . '</a></li>';
                echo '<li class="separator"> ' . $separator . ' </li>';
            }
 
            // Categoria
            $category = get_the_category();
 
            if(!empty($category)) {
 
                // Ultima categoria della sequenza
                $last_category = end(array_values($category));
 
                // Categoria genitore
                $get_cat_parents = rtrim(get_category_parents($last_category->term_id, true, ','),',');
                $cat_parents = explode(',',$get_cat_parents);
 
                // La ricerca delle catyegorie-genitore e la loro raccolta nella variabile $cat_display
                $cat_display = '';
                foreach($cat_parents as $parents) {
                    $cat_display .= '<li class="item-cat">'.$parents.'</li>';
                    $cat_display .= '<li class="separator"> ' . $separator . ' </li>';
                }
            }
 
            // Se dovesse essere una pubblicazione personalizzata nella tassonomia personalizzata
            $taxonomy_exists = taxonomy_exists($custom_taxonomy);
            if(empty($last_category) && !empty($custom_taxonomy) && $taxonomy_exists) {
                $taxonomy_terms = get_the_terms( $post->ID, $custom_taxonomy );
                $cat_id         = $taxonomy_terms[0]->term_id;
                $cat_nicename   = $taxonomy_terms[0]->slug;
                $cat_link       = get_term_link($taxonomy_terms[0]->term_id, $custom_taxonomy);
                $cat_name       = $taxonomy_terms[0]->name;
 
            }
 
            // Verificare se il post appartiene alla categoria
            if(!empty($last_category)) {
                echo $cat_display;
                echo '<li class="item-current item-' . $post->ID . '"><strong class="bread-current bread-' . $post->ID . '" title="' . get_the_title() . '">' . get_the_title() . '</strong></li>';
 
            // Altrimenti, se appartiene alla tassonomia personalizzata
            } else if(!empty($cat_id)) {
 
                echo '<li class="item-cat item-cat-' . $cat_id . ' item-cat-' . $cat_nicename . '"><a class="bread-cat bread-cat-' . $cat_id . ' bread-cat-' . $cat_nicename . '" href="' . $cat_link . '" title="' . $cat_name . '">' . $cat_name . '</a></li>';
                echo '<li class="separator"> ' . $separator . ' </li>';
                echo '<li class="item-current item-' . $post->ID . '"><strong class="bread-current bread-' . $post->ID . '" title="' . get_the_title() . '">' . get_the_title() . '</strong></li>';
 
            } else {
 
                echo '<li class="item-current item-' . $post->ID . '"><strong class="bread-current bread-' . $post->ID . '" title="' . get_the_title() . '">' . get_the_title() . '</strong></li>';
            }
 
        } else if ( is_category() ) {
 
            // Sulla pagina della categoria
            echo '<li class="item-current item-cat"><strong class="bread-current bread-cat">' . single_cat_title('', false) . '</strong></li>';
 
        } else if ( is_page() ) {
 
            // Una pagina standard
            if( $post->post_parent ){
 
                // Se la pagina ha una pagina genitore
                $anc = get_post_ancestors( $post->ID );
 
                // Ottenere le pagine-genitore in un ordine corretto
                $anc = array_reverse($anc);
 
                // Il ciclo delle pagine-genitore
                if ( !isset( $parents ) ) $parents = null;
                foreach ( $anc as $ancestor ) {
                    $parents .= '<li class="item-parent item-parent-' . $ancestor . '"><a class="bread-parent bread-parent-' . $ancestor . '" href="' . get_permalink($ancestor) . '" title="' . get_the_title($ancestor) . '">' . get_the_title($ancestor) . '</a></li>';
                    $parents .= '<li class="separator separator-' . $ancestor . '"> ' . $separator . ' </li>';
                }
 
                // Mostrare le pagine-genitore della pagina
                echo $parents;
 
                // La pagina corrente
                echo '<li class="item-current item-' . $post->ID . '"><strong title="' . get_the_title() . '"> ' . get_the_title() . '</strong></li>';
 
            } else {
 
                // Mostrare solo la pagina corrente se non ci sono delle pagine-genitore
                echo '<li class="item-current item-' . $post->ID . '"><strong class="bread-current bread-' . $post->ID . '"> ' . get_the_title() . '</strong></li>';
            }
 
        } else if ( is_tag() ) {
 
            // La pagina del tag
 
            // Otteniamo le informazioni
            $term_id        = get_query_var('tag_id');
            $taxonomy       = 'post_tag';
            $args           = 'include=' . $term_id;
            $terms          = get_terms( $taxonomy, $args );
            $get_term_id    = $terms[0]->term_id;
            $get_term_slug  = $terms[0]->slug;
            $get_term_name  = $terms[0]->name;
 
            // Mostriamo il nome del tag
            echo '<li class="item-current item-tag-' . $get_term_id . ' item-tag-' . $get_term_slug . '"><strong class="bread-current bread-tag-' . $get_term_id . ' bread-tag-' . $get_term_slug . '">' . $get_term_name . '</strong></li>';
 
        } elseif ( is_day() ) {
 
             // ARCHIVIO DEL GIORNO
            // Archivio dellanno
            echo '<li class="item-year item-year-' . get_the_time('Y') . '"><a class="bread-year bread-year-' . get_the_time('Y') . '" href="' . get_year_link( get_the_time('Y') ) . '" title="' . get_the_time('Y') . '">' . get_the_time('Y') . ' Archives</a></li>';
            echo '<li class="separator separator-' . get_the_time('Y') . '"> ' . $separator . ' </li>';
 
            // Archivio del mese
            echo '<li class="item-month item-month-' . get_the_time('m') . '"><a class="bread-month bread-month-' . get_the_time('m') . '" href="' . get_month_link( get_the_time('Y'), get_the_time('m') ) . '" title="' . get_the_time('M') . '">' . get_the_time('M') . ' Archives</a></li>';
            echo '<li class="separator separator-' . get_the_time('m') . '"> ' . $separator . ' </li>';
 
            // Archivio del giorno
            echo '<li class="item-current item-' . get_the_time('j') . '"><strong class="bread-current bread-' . get_the_time('j') . '"> ' . get_the_time('jS') . ' ' . get_the_time('M') . ' Archives</strong></li>';
 
        } else if ( is_month() ) {
 
            // ARCHIVIO DEL MESE
            // Archivio dellanno
            echo '<li class="item-year item-year-' . get_the_time('Y') . '"><a class="bread-year bread-year-' . get_the_time('Y') . '" href="' . get_year_link( get_the_time('Y') ) . '" title="' . get_the_time('Y') . '">' . get_the_time('Y') . ' Archives</a></li>';
            echo '<li class="separator separator-' . get_the_time('Y') . '"> ' . $separator . ' </li>';
 
            // Archivio del mese
            echo '<li class="item-month item-month-' . get_the_time('m') . '"><strong class="bread-month bread-month-' . get_the_time('m') . '" title="' . get_the_time('M') . '">' . get_the_time('M') . ' Archives</strong></li>';
 
        } else if ( is_year() ) {
 
            // ARCHIVIO ANNO
            echo '<li class="item-current item-current-' . get_the_time('Y') . '"><strong class="bread-current bread-current-' . get_the_time('Y') . '" title="' . get_the_time('Y') . '">' . get_the_time('Y') . ' Archives</strong></li>';
 
        } else if ( is_author() ) {
 
            // Archivio autore
 
            // Le informazioni sullautore
            global $author;
            $userdata = get_userdata( $author );
 
            // Mostrare il nome dellautore
            echo '<li class="item-current item-current-' . $userdata->user_nicename . '"><strong class="bread-current bread-current-' . $userdata->user_nicename . '" title="' . $userdata->display_name . '">' . 'Author: ' . $userdata->display_name . '</strong></li>';
 
        } else if ( get_query_var('paged') ) {
 
            // Archivio diviso per pagine
            echo '<li class="item-current item-current-' . get_query_var('paged') . '"><strong class="bread-current bread-current-' . get_query_var('paged') . '" title="Page ' . get_query_var('paged') . '">'.__('Page') . ' ' . get_query_var('paged') . '</strong></li>';
 
        } else if ( is_search() ) {
 
            // I risultati della ricerca
            echo '<li class="item-current item-current-' . get_search_query() . '"><strong class="bread-current bread-current-' . get_search_query() . '" title="Search results for: ' . get_search_query() . '">Search results for: ' . get_search_query() . '</strong></li>';
 
        } elseif ( is_404() ) {
 
            // Pagina 404
            echo '<li>' . 'Error 404' . '</li>';
        }
        echo '</ul>';
    }
}

Come potete vedere dalla riga 17 del listing appena riportato, il menu breadcrumbs generato dal codice verrà visualizzato su tutte le pagine tranne la pagina principale del sito (perché non ha senso generarlo per una sola voce, la quale per logica non dovrebbe nemmeno essere linkata). Ma se volete proprio visualizzare quel menu anche sulla Home, inserite il seguente codice dopo la riga 213 del listing sovrastante:

else {
       echo 'Home';
     }

Ovviamente, anche in questo caso potete sostituire la parola «Home» con il testo che preferite: come, probabilmente, avete già fatto alla riga 8 del mio listing.
Ora, per visualizzare il menu breadcrumbs sulle pagine del sito, bisogna richiamare la funzione appena creata. A tale scopo, nel template delle pagine del tema (quindi page.php, single.php, archive.php etc.) – nel punto esatto dove vogliamo vedere il menu – va inserito il seguente codice:

<?php custom_breadcrumbs(); ?>

Benissimo, ora il menu breadcrumbs esiste, si vede e funziona. Ci resta solo perfezionare il suo aspetto grafico inserendo delle istruzioni nel file degli stili CSS. Quelle istruzioni vanno fatte tenendo conto del vostro design e delle vostre preferenze estetiche, quindi non trovo utile proporvi una mia soluzione particolarmente elaborata. Mi limito a elencare i nomi degli id e dei class utilizzati nel mio codice con delle istruzioni minime (tanto per farvi vedere su cosa bisogna intervenire):

#breadcrumbs{
    list-style: none;
    margin: 10px 0;
    overflow: hidden;
}
 
#breadcrumbs li{
    display: inline-block;
    vertical-align: middle;
    margin-right: 15px;
}
 
#breadcrumbs .separator{
    font-size: 18px;
    font-weight: 100;
    color: #CCCCCC;
}

A questo punto possiamo considerare fatto il nostro menu breadcrumbs per il WordPress.
Non dimenticatevi di caricare sul server tutti i file modificati, ahahaha

I commenti sono chiusi.