Comment créer un widget pour afficher ses derniers CPT ?
Dans ce petit mémo, je donne un exemple d’un widget censé afficher les derniers custom post type.
Ce que contient le widget
Ce widget devra contenir :
un titre
Une case à cocher pour afficher les posts de manière aléatoire
Un champ select pour choisir la taxonomie (catégorie) du CPT
Un champ texte pour le choix du nombre de post à afficher.
Le rendu du widget
Voici un exemple de rendu en front, avec une vignette
Et au niveau du rendu des options en backoffice
03
Le code du widget
Ce code est à placer dans functions.php ou tout autre fichier dédié
class Cc_Last_Formation_Posts_Widget extends WP_Widget { /* * Register widget with WordPress. */ function __construct() { parent::__construct( 'cc_last_formation_posts_widget ', __( 'Cc Last formation posts', 'text_domain' ), array( 'description' => __( 'Shows last formation posts.', 'text_domain' ), ) ); } /** * Front-end display of widget. */ public function widget( $args, $instance ) { echo $args['before_widget']; // Catch result $tax_id = absint( $instance['tax_id'] ) ; $random = $instance['rand'] ? true : false; $number = ( ! empty( $instance['number'] ) ) ? absint( $instance['number'] ) : 5; if ( ! $number ) { $number = 3; } if( true === $random ) { $loop = new WP_Query( array( 'post_type' => 'formation', 'orderby' => 'rand', 'posts_per_page' => $number, ) ); }else{ $loop = new WP_Query( array( 'post_type' => 'formation', 'posts_per_page' => $number, 'tax_query' => array( array( 'taxonomy' => 'categories-formations', 'field' => 'term_id', 'terms' => array($tax_id), ) ) ) ); } if( $loop->have_posts() ) { echo '<h2 class="heading">'. esc_html( $instance['title'] ) .'</h2>'; echo '<div id="related-formation-post"><div class="flex-row">'; while ($loop->have_posts()){ $loop->the_post(); ?> <div class="flex-col-sm-4"> <article id="post-<?php the_ID(); ?>" <?php post_class('related-formation-post'); ?>> <div class="isotope-thumbnail"> <?php if ( has_post_thumbnail() ) { the_post_thumbnail('masonryLayout'); } ; ?> </div> <div class="entry-header isotope-title"> <h3><?php the_title(); ?></h3> </div> <div class="entry-meta"> <?php $duree = get_field_object('duree'); if($duree){ echo '<div><span class="isotope-duree">' . $duree['value'] . '</span></div>'; } ?> </div> <div class="isotope-excerpt"> <?php echo get_post_meta(get_the_ID(), '_yoast_wpseo_metadesc', true); ?> </div> <div class="isotope-cta"> <a href="<?php esc_url( the_permalink() );?>" rel="bookmark">Voir</a> </div> </article> </div> <?php } echo '</div></div>'; wp_reset_query(); echo $args['after_widget']; } } /** * Sanitize widget form values as they are saved. * * @see WP_Widget::update() * * @param array $new_instance Values just sent to be saved. * @param array $old_instance Previously saved values from database. * * @return array Updated safe values to be saved. */ public function update( $new_instance, $old_instance ) { $instance = array(); $instance['title'] = ( ! empty( $new_instance['title'] ) ) ? strip_tags( $new_instance['title'] ) : ''; $instance['tax_id'] = ( ! empty( $new_instance['tax_id'] ) ) ? strip_tags( $new_instance['tax_id'] ) : ''; $instance['rand'] = ( ! empty( $new_instance['rand']) ) ? strip_tags( $new_instance['rand'] ) : ''; $instance['number'] =( ! empty( (int) $new_instance['number']) ) ? strip_tags( (int) $new_instance['number'] ) : ''; return $instance; } /** * Back-end widget form. */ public function form( $instance ) { $title = ''; if( !empty( $instance['title'] ) ) { $title = $instance['title']; } $tax_id = ''; if( !empty( $instance['tax_id'] ) ) { $tax_id = absint( $instance['tax_id'] ) ; } $number = isset( $instance['number'] ) ? absint( $instance['number'] ) : 3; $random = isset( $instance['rand'] ) ? $instance['rand'] : false; ?> <p> <label for="<?php echo $this->get_field_id( 'title' ); ?>"><?php _e( 'Title:' ); ?></label> <input class="widefat" id="<?php echo $this->get_field_id( 'title' ); ?>" name="<?php echo $this->get_field_name( 'title' ); ?>" type="text" value="<?php echo esc_attr( $title ); ?>"> </p> <p> <label for="<?php echo $this->get_field_id( 'number' ); ?>"><?php _e( 'Number of posts to show:' ); ?></label> <input id="<?php echo $this->get_field_id( 'number' ); ?>" name="<?php echo $this->get_field_name( 'number' ); ?>" type="text" value="<?php echo $number; ?>" size="3" /> </p> <p> <label for="<?php echo $this->get_field_id('tax_id'); ?>"><?php _e( 'Taxonomy Name:' )?></label> <select id="<?php echo $this->get_field_id('tax_id'); ?>" name="<?php echo $this->get_field_name('tax_id'); ?>"> <?php $custom_terms = get_terms('categories-formations'); foreach($custom_terms as $custom_term) { $selected = ( $custom_term->term_id == esc_attr( $tax_id ) ) ? ' selected = "selected" ' : ''; $option = '<option '.$selected .'value="' . $custom_term->term_id; $option = $option .'">'; $option = $option .$custom_term->name; $option = $option .'</option>'; echo $option; } ?> </select> </p> <p> <label for="<?php echo $this->get_field_id('rand'); ?>"><?php _e( 'Show random posts' ); ?></label> <?php $checked = ( $random ) ? ' checked=\"checked\" ' : ''; ?> <input type="checkbox" id="<?php echo $this->get_field_id( 'rand' ); ?>" name="<?php echo $this->get_field_name( 'rand' ); ?>" value="true" <?php echo $checked; ?> /> </p> <?php } }
Ici plusieurs choses sont à remarquer :
Pour la fonction du constructeur, rien de particulier
Pour la fonction widget d’affichage en front : on commence par afficher un nombre par défaut d’articles, si jamais l’utilisateur ne remplit pas le champ
if ( ! $number ) { $number = 3; }
dans notre boucle, on crée une condition pour afficher les post soit dans un ordre aléatoire
if( true === $random ) { $loop = new WP_Query( array( 'post_type' => 'formation', 'orderby' => 'rand', 'posts_per_page' => $number, ) ); }
Soit en fonction d’une taxonomie sélectionnée. C’est l’attribut tax_query qui va nous permettre d’aller chercher la taxonomie et la sous taxonomie ou « term » choisie.
$loop = new WP_Query( array( 'post_type' => 'formation', 'posts_per_page' => $number, 'tax_query' => array( array( 'taxonomy' => 'categories-formations', 'field' => 'term_id', 'terms' => array($tax_id), ) ) ) );
J’entoure le title d’une classe pour pouvoir la styliser directement
echo '<h2 class="heading">'. esc_html( $instance['title'] ) .'</h2>';
Dans mon code, j’utilise aussi un template_tag d’ACF pour aller cherche la valeur du post_object « durée ».
Ensuite comme extrait, je choisis d’afficher l’extrait de Yoast plutôt que l’extrait classique. Celui de Yoast étant plus court, je trouve ca plus pratique.
echo get_post_meta(get_the_ID(), '_yoast_wpseo_metadesc', true);
La fonction update, rien de particulier
Puis la fonction form dans laquelle je construit le champ select. Je prends ici en compte les taxonomies dans mon foreach
<p> <label for="<?php echo $this->get_field_id('tax_id'); ?>"><?php _e( 'Taxonomy Name:' )?></label> <select id="<?php echo $this->get_field_id('tax_id'); ?>" name="<?php echo $this->get_field_name('tax_id'); ?>"> <?php $custom_terms = get_terms('categories-formations'); foreach($custom_terms as $custom_term) { $selected = ( $custom_term->term_id == esc_attr( $tax_id ) ) ? ' selected = "selected" ' : ''; $option = '<option '.$selected .'value="' . $custom_term->term_id; $option = $option .'">'; $option = $option .$custom_term->name; $option = $option .'</option>'; echo $option; } ?> </select> </p>
Enfin la case à cocher pour l’affichage aléatoire
<p> <label for="<?php echo $this->get_field_id('rand'); ?>"><?php _e( 'Show random posts' ); ?></label> <?php $checked = ( $random ) ? ' checked=\"checked\" ' : ''; ?> <input type="checkbox" id="<?php echo $this->get_field_id( 'rand' ); ?>" name="<?php echo $this->get_field_name( 'rand' ); ?>" value="true" <?php echo $checked; ?> /> </p>
Voilà, à vous ensuite de styliser le rendu de vos CPT !
N’hésitez pas, si vous avez des idées d’amélioration ou des corrections à apporter à ce tuto !
03/04/2020
Mis à jour le 07/04/2020
Par Copier coller | Dans wordpress