In questo articolo entrerò nel dettaglio della demo che ho mostrato in alcuni miei interventi alle iniziative promosse dalla community di WordPress avente, come argomento, la costruzione di temi child.

Parto da un esempio molto semplice per mostrare le possibilità di personalizzazione che si hanno con la creazione di un tema child.

Il tema qui usato è Generatepress.

Le modifiche principali nel frontend

Ora vediamo le modifiche principali che ho fatto. Altre, come i titoli delle pagine Blog, di archivio e di ricerca le ometto per brevità.

Per prima cosa ho voluto facilitare il visitatore nella ricerca degli articoli, tramite parola chiave, affiancando al menù, presente nella barra in alto, un form apposito.

Successivamente mi sono dedicato agli articoli. Ho stampato un codice html custom per i metadati, al posto di quello del tema genitore, posizionandolo sotto il titolo di ogni articolo, nella pagina del singolo e nelle preview renderizzate nelle pagine Blog, di ricerca e di archivio (categorie e articoli dell’autore).

Gli articoli, in tutte le pagine prima citate, li ho avvolti un <div> che mi ha permesso di stilizzarli opportunamente.

Nel tema principale, sempre nelle stesse pagine, il Leggi tutto, dopo ogni preview, viene generato in automatico se il riassunto supera le 55 parole; io ho tolto quest’ultimo e ho fatto stampare un link Leggi tutto a sé stante, così che venga stampato a prescindere dal numero di parole della preview.

Le modifiche nel backend

Vediamo come ho ottenuto tutto quanto descritto sopra.

Ho creato il tema child per sovrascrivere Generatepress e ho messo le seguenti intestazioni nel file style.css:

/*
Theme Name:   GeneratePress Child
Description:  GeneratePress Child Theme
Author:       Andrea Ronchetti
Author URI:   https://www.andrearonchetti.it/
Template:     generatepress 
Text Domain:  generatepress-child
Version:      1.0.0
*/

Form di ricerca nella header

Ispezionando il tema parent, al fine di trovare il file preposto a renderizzare la header, mi sono imbattuto in generatepress/inc/structure/header.php e ho scoperto che gli sviluppatori del tema hanno creato un gancio apposito per aggiungere elementi nella header dopo il menù principale. Questo mi ha permesso di evitare di ricreare il file; ho generato il form tramite una funzione da agganciare a ‘generate_after_header_content’. Quindi nel functions.php del child ho messo queste righe di codice:

add_action('generate_after_header_content','add_search_form');

function add_search_form(){
    ?>
    <form id="header-search-form" action="<?php echo get_site_url();?>" method="get">
        <div>
            <input type="text" name="s" placeholder="Cerca nel blog...">
            <button type="submit">
                <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512">
                    <path d="M416 208c0 45.9-14.9 88.3-40 122.7L502.6 457.4c12.5 12.5 12.5 32.8 0 45.3s-32.8 12.5-45.3 0L330.7 376c-34.4 25.2-76.8 40-122.7 40C93.1 416 0 322.9 0 208S93.1 0 208 0S416 93.1 416 208zM208 352c79.5 0 144-64.5 144-144s-64.5-144-144-144S64 128.5 64 208s64.5 144 144 144z" fill="#fff">
                </svg>
            </button>
        </div>
    </form>
    <?php
}

Questa funzione altro non fa che stampare l’HTML del form. Nello style.css del tema child ho messo le formattazioni grafiche che qui non riporto per brevità.

Funzione per i metadati: rendiamo uniforme la formattazione ovunque

Per stampare i metadati in modo uniforme laddove ci devono essere ho creato la seguente funzione nel functions.php:

function print_meta_data($post){
    //name of author
    $author_name = get_the_author();
    //permalink for author's posts
    $author_url = get_author_posts_url(get_the_author_meta( 'ID' ));

    //category ID
    $cat_id = wp_get_post_categories(get_the_ID());
    //WP_Term object of current category
    $cat = get_category( $cat_id ); 
    //Current category archive permalink
    $cat_link = get_category_link( $cat_id ); 

    //html string for entry meta
    echo '<div class="entry-meta">'.the_date('','','',false).' <a href="'.$author_url.'">'.$author_name.'</a> | <a href="'.$cat_link.'">'.$cat->name.'</a></div>';
}

Ho richiamato in questo modo la funzione nel template del singolo articolo (content-single.php), a sua volta utilizzato nel single.php del tema parent.

if ( generate_show_title () ) {
    $params = generate_get_the_title_parameters ();
    the_title ( $params [ 'before' ], $params [ 'after' ] );

    //this function I added to print post meta in my format
    print_meta_data ( get_post() );

    the_post_thumbnail ( 'full' );
}

Più avanti, nello stesso script, ho commentato il codice che viene usato dal tema parent per stampare la categoria sotto il contenuto dell’articolo.

<?php
/** * generate_after_entry_content hook. * * @since 0.1 * * @hooked generate_footer_meta - 10 */
//this istrucion is commented to remove meta data printed by theme //do_action( 'generate_after_entry_content' );
/** * generate_after_content hook. * * @since 0.1 */
do_action( 'generate_after_content' ); ?>

Ho fatto lo stesso genere di operazioni nel content.php, che renderizza la preview di ogni articolo nelle pagine dove viene indicizzato.

if ( generate_show_entry_header() ) :
    ?>
    <header <?php generate_do_attr( 'entry-header' ); ?> >
        <?php
/** * generate_before_entry_title hook. * * @since 0.1 */
do_action( 'generate_before_entry_title' ); if ( generate_show_title() ) { $params = generate_get_the_title_parameters(); the_title( $params [ 'before' ], $params [ 'after' ] ); //this code generates meta data with function I created in functions.php if ( get_post()->post_type != 'page' ) { print_meta_data(get_post()); } }
/** * generate_after_entry_title hook. * * @since 0.1 * * @hooked generate_post_meta - 10 */
//this istrucion is commented to remove meta data printed by theme //do_action( 'generate_after_entry_title' ); ?> </header> <?php endif;

Anche qui, in un punto del codice successivo alla stampa del riassunto, ho tolto le categorie e il numero di commenti.

Renderizzazione delle preview degli articoli nella pagina Blog, di ricerca e di categoria

Al fine di poter stilizzare graficamente tutte le preview degli articoli ho fatto in modo che il risultato del loop venga stampato all’interno di un div con classe wrap-articles.

Nel file serch.php ho messo:

    echo '<div class="wrap-articles">';
    while ( have_posts() ) :

        the_post();

        generate_do_template_part( 'search' );

    endwhile;
    echo '</div>';

In archive.php ho messo:

    echo '<div class="wrap-articles">';
    while ( have_posts() ) :
    
        the_post();
//preview archive is replaced with index to make uniform with blog page // /demo-tema-child/wp-content/themes/generatepress/inc/theme-functions.php //generate_do_template_part( 'archive' );
generate_do_template_part( 'index' ); endwhile; echo '</div>';

In index.php ho messo:

    echo '<div class="wrap-articles">';
    while ( have_posts() ) :

        the_post();
        
        generate_do_template_part( 'index' );

    endwhile;
    echo '</div>';

Customizzazione del Leggi tutto

Dicevamo prima che il Leggi tutto viene stampato in automatico quando il riassunto supera le 55 parole, altrimenti non viene stampato. Questo non è ottimale in quanto rischiamo di avere alcune preview che hanno il Leggi tutto e altre no. Per evitare questo inconveniente ho tolto il link automatico e ne ho messo uno custom.

Anzitutto bisogna agganciarsi a un filtro, the_excerpt, fargli analizzare la preview del testo generata e rimuovere il link automatico tramite la ricerca della stringa dell’html del link; quest’ultima sarà rimpiazzata con una vuota mediante queste righe di codice inserite nel functions.php:

add_filter('the_excerpt',function($excerpt){
    return preg_replace('/<a.+?>.+<\/a>/m','',$excerpt);
});

Adesso che ho tolto il link automatico ne metto uno io nel content.php:

if ( generate_show_excerpt() ) :
    ?>
    <div class="entry-summary"<?php echo $itemprop; // phpcs:ignore -- No escaping needed.  ?> >
        <?php the_excerpt(); ?>

        <a href="<?php echo get_the_permalink(); ?>" class= "read-more" >Leggi tutto</a>
    </div>

<?php else : ?>
//continue…