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