Come sviluppare un widget per WordPress
Questa guida su come sviluppare un widget per WordPress è stata scritta inizialmente nel 2012 e prevedeva la creazione di un widget per visualizzare gli ultimi tweets, gestendo l’account di riferimento e il numero di aggiornamenti da visualizzare.
Ho dovuto però aggiornarla poiché il metodo utilizzato per ottenere la lista di tweets non è più supportato da Twitter ed ho preferito rivedere il precendente codice così da trasformare il vecchio widget e visualizzare una lista di articoli, pagine oppure un qualsiasi custom post type, come i prodotti WooCommerce, completi di titolo, immagine in evidenza e riassunto.
Se non hai idea di che cosa siano i widget, altro non sono che contenuti dinamici che si possono inserire all’interno della aree widget di WordPress chiamate sidebar, come gli ultimi commenti oppure dei banner pubblicitari.
La loro gestione avviene tramite un sistema di drag and drop andando in Aspetto successivamente Widget.
Da questa sezione puoi inserire tutti i widget che vuoi, di default WordPress ne ha circa una quindicina.
Per creare un widget hai due possibilità, svilupparlo all’interno del file “functions.php” di un tema WordPress oppure trattarlo come un plugin.
Nel secondo caso potrai utilizzarlo all’interno di un qualsiasi sito in WordPress.
Per fare questo è necessario estendere la classe WP_Widget di WordPress
class My_Widget extends WP_Widget { public function __construct() { // Costruttore di classe } public function form( $instance ) { // Form di gestione del Widget } public function update( $new_instance, $old_instance ) { // Processo di salvataggio delle opzioni } public function widget( $args, $instance ) { // Visualizzazione del contenuto. } }
Il primo metodo serve a creare la classe del nostro widget, in cui andremo ad impostare i parametri fondamentali:
- Nome univoco del Widget (tutto in minuscolo e senza spazi)
- Titolo del Widget
- Un array contenete varie opzioni, di cui noi utilizzeremo solo il campo “description”.
Inizia scrivendo:
class WIP_CPT_Widget extends WP_Widget { public function __construct() { parent::__construct( "WIP_CPT_Widget", "WIP Custom Post Type Widget", array("description" => "WIP Custom Post Type Widget")); }
Ora passa al modulo in cui inserire i vari parametri per far funzionare correttamente il widget.
public function form( $instance ) { $defaults = array( 'title' => '', 'items' => "-1", 'cpt' => 'post', ); $instance = wp_parse_args( (array) $instance, $defaults ); ?> <p> <label for="<?php echo $this->get_field_id( 'title' ); ?>"><?php esc_html_e( "Titolo"); ?>:</label> <input class="widefat" type="text" id="<?php echo $this->get_field_id( 'title' ); ?>" name="<?php echo $this->get_field_name( 'title' ); ?>" value="<?php echo esc_attr($instance['title']); ?>" /> </p> <p> <label for="<?php echo $this->get_field_id( 'items' ); ?>"> <?php esc_html_e( "Numero di elementi ( inserisci -1 per visualizzare tutti gli elementi. )"); ?>: </label> <input class="widefat" type="number" id="<?php echo $this->get_field_id( 'items' ); ?>" name="<?php echo $this->get_field_name( 'items' ); ?>" value="<?php echo esc_attr($instance['items']); ?>" /> </p> <p> <label for="<?php echo $this->get_field_id( 'cpt' ); ?>"><?php esc_html_e( "Seleziona un tipo post personalizzato"); ?></label> <select class="widefat" name="<?php echo $this->get_field_name( 'cpt' ); ?>" id="<?php echo $this->get_field_id( 'cpt' ); ?>"> <?php foreach ( get_post_types( array('public' => TRUE) ) as $cpt ) { if ($cpt == $instance['cpt'] ) { echo "<option value='".$cpt."' selected='selected' >".$cpt."</option>"; } else { echo "<option value='".$cpt."'>".$cpt."</option>"; }; } ?> </select> </p> <?php }
Questa parte è un pò più complessa, all’interno dell’array $defaults, vengono definiti i campi del form, indicando i valori di default che verranno visualizzati appena il widget verrà inserito e salvato all’interno di una barra laterale.
Successivamente, utilizzando la funzione wp_parse_args(), questi valori di default verrano elaborati, così da poterlo gestire tramite la variabile $instance.
La classe css widefat è una classe di default utilizzata da WordPress.
public function update( $new_instance, $old_instance ) { $instance = $old_instance; $instance['title'] = strip_tags( $new_instance['title'] ); $instance['items'] = strip_tags( $new_instance['items'] ); $instance['cpt'] = strip_tags( $new_instance['cpt'] ); return $instance; }
Il metodo update , si occuperà di aggiornare nel database i valori del widget, con quelli inseriti tramite il form.
public function widget( $args, $instance ) { extract( $args ); echo $before_widget; $title = apply_filters( 'widget_title', $instance['title'] ); if ( $title ) echo '<h4>' . esc_attr($title) . '</h4>' ; $query_args = array( 'post_type' => $instance['cpt'], 'posts_per_page' => $instance['items'], ); $query = new WP_Query( $query_args ); while ( $query->have_posts() ) : $query->the_post(); global $post; $thumb = wp_get_attachment_image_src( get_post_thumbnail_id(), 'full'); if (has_post_thumbnail()) the_post_thumbnail(); echo '<h3><a href="'.get_the_permalink().'">' . esc_attr(get_the_title()) . '</a></h3>'; echo get_the_excerpt(); endwhile; wp_reset_query(); wp_reset_postdata(); echo $after_widget; }
Il metodo widget invece, si occuperà di generare il codice HTML del widget.
Puoi utilizzare $args, per recuperare le informazioni relative alla sidebar in cui è stato inserito il widget, ovvero “before_widget, after_widget, before_title, after_title”, così da poterle visualizzare come preferisci.
Se lo desideri, puoi migliorare graficamente il widget tramite CSS.
if (!function_exists('wip_load_widgets')) { function wip_load_widgets() { register_widget( 'WIP_CPT_Widget' ); } add_action('widgets_init', 'wip_load_widgets'); }
Questa ultima parte è necessaria per registrare il widget. Se ora accedi nell’amministrazione di WordPress, troverai un nuovo widget pronto per essere caricato nella sidebar.
Ecco il codice completo che puoi aggiungere nel file functions.php, oppure creando un plugin per WordPress
class WIP_CPT_Widget extends WP_Widget { public function __construct() { parent::__construct( "WIP_CPT_Widget", "WIP Custom Post Type Widget", array("description" => "WIP Custom Post Type Widget")); } public function form( $instance ) { $defaults = array( 'title' => '', 'items' => "-1", 'cpt' => 'post', ); $instance = wp_parse_args( (array) $instance, $defaults ); ?> <p> <label for="<?php echo $this->get_field_id( 'title' ); ?>"><?php esc_html_e( "Titolo"); ?>:</label> <input class="widefat" type="text" id="<?php echo $this->get_field_id( 'title' ); ?>" name="<?php echo $this->get_field_name( 'title' ); ?>" value="<?php echo esc_attr($instance['title']); ?>" /> </p> <p> <label for="<?php echo $this->get_field_id( 'items' ); ?>"> <?php esc_html_e( "Numero di elementi ( inserisci -1 per visualizzare tutti gli elementi. )"); ?>: </label> <input class="widefat" type="number" id="<?php echo $this->get_field_id( 'items' ); ?>" name="<?php echo $this->get_field_name( 'items' ); ?>" value="<?php echo esc_attr($instance['items']); ?>" /> </p> <p> <label for="<?php echo $this->get_field_id( 'cpt' ); ?>"><?php esc_html_e( "Seleziona un tipo post personalizzato"); ?></label> <select class="widefat" name="<?php echo $this->get_field_name( 'cpt' ); ?>" id="<?php echo $this->get_field_id( 'cpt' ); ?>"> <?php foreach ( get_post_types( array('public' => TRUE) ) as $cpt ) { if ($cpt == $instance['cpt'] ) { echo "<option value='".$cpt."' selected='selected' >".$cpt."</option>"; } else { echo "<option value='".$cpt."'>".$cpt."</option>"; }; } ?> </select> </p> <?php } public function update( $new_instance, $old_instance ) { $instance = $old_instance; $instance['title'] = strip_tags( $new_instance['title'] ); $instance['items'] = strip_tags( $new_instance['items'] ); $instance['cpt'] = strip_tags( $new_instance['cpt'] ); return $instance; } public function widget( $args, $instance ) { extract( $args ); echo $before_widget; $title = apply_filters( 'widget_title', $instance['title'] ); if ( $title ) echo '<h4>' . esc_attr($title) . '</h4>' ; $query_args = array( 'post_type' => $instance['cpt'], 'posts_per_page' => $instance['items'], ); $query = new WP_Query( $query_args ); while ( $query->have_posts() ) : $query->the_post(); global $post; $thumb = wp_get_attachment_image_src( get_post_thumbnail_id(), 'full'); if (has_post_thumbnail()) the_post_thumbnail(); echo '<h3><a href="'.get_the_permalink().'">' . esc_attr(get_the_title()) . '</a></h3>'; echo get_the_excerpt(); endwhile; wp_reset_query(); wp_reset_postdata(); echo $after_widget; } } /*-----------------------------------------------------------------------------------*/ /* REGISTRO IL WIDGET */ /*-----------------------------------------------------------------------------------*/ if (!function_exists('wip_load_widgets')) { function wip_load_widgets() { register_widget( 'WIP_CPT_Widget' ); } add_action('widgets_init', 'wip_load_widgets'); }
Si tratta di un corso completo per lo sviluppo di temi e plugin per WordPress, seguendo tutti gli standard di codifica di WordPress.org.Acquista il corso o scarica gratuitamente un estratto
Ciò che hai appena visto serve come base per poter, in futuro, sviluppare widget più complessi, per qualsiasi domanda puoi lasciare un commento, ti risponderò il prima possibile.
Commenti
Dopo tanto cercare e sperimentare finalmente un codice che funziona alla perfezione! Grazie.
Io ho creato un widget nella cartella “widgets” inserita nella cartella del tema, ho aggiunto il file “widgets.php” ed al suo interno il seguente codice di inclusione del widget:
ed il codice per registrare il widget nel file funtions.php del tema
Mi manca di capire come tradurre il widget . Qualcuno l’ha già fatto ed ha suggerimenti?
Ciao Roberto, grazie a te.
Prova a seguire la sezione “Come localizzare un tema child WordPress” del seguente articolo e fammi sapere
https://www.wpinprogress.com/come-modificare-un-tema-wordpress/
Nel caso non si tratti di un tema child, puoi utilizzare load_theme_textdomain invece di load_child_theme_textdomain, ad esempio:
load_theme_textdomain(‘slug’, get_template_directory() . ‘/languages’);
A presto
Alessandro