Files
elementor-category-grid-widget/widgets/category-grid-widget.php
2025-05-23 09:54:50 +00:00

273 lines
10 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<?php
if ( ! defined( 'ABSPATH' ) ) {
exit; // Empêche l'accès direct.
}
/**
* Classe Elementor_Category_Grid_Widget.
*
* Widget Elementor personnalisé qui affiche une grille de catégories d'articles.
* Chaque catégorie est affichée sous forme de carte avec son nom, son image et un lien vers son archive.
*/
class Elementor_Category_Grid_Widget extends \Elementor\Widget_Base {
/**
* Identifiant unique du widget.
*
* @return string Slug du widget.
*/
public function get_name(): string {
return 'category-grid';
}
/**
* Titre du widget affiché dans l'interface Elementor.
*
* @return string Titre du widget.
*/
public function get_title(): string {
return esc_html__( 'Grille de Catégories', 'category-grid-widget' );
}
/**
* Icône du widget (bibliothèque d'icônes Elementor).
*
* @return string Classe de l'icône du widget.
*/
public function get_icon(): string {
return 'eicon-posts-grid';
}
/**
* Catégories Elementor dans lesquelles le widget apparaîtra.
*
* @return array Catégories du panneau Elementor.
*/
public function get_categories(): array {
return [ 'general' ];
}
/**
* Mots-clés facilitant la recherche du widget.
*
* @return array Mots-clés du widget.
*/
public function get_keywords(): array {
return [ 'category', 'catégorie', 'grid', 'grille' ];
}
/**
* Enregistrer les contrôles du widget (champs configurables dans Elementor).
*/
protected function register_controls(): void {
/* Section "Contenu" pour le choix des catégories et options de requête */
$this->start_controls_section(
'section_content',
[
'label' => esc_html__( 'Catégories', 'category-grid-widget' ),
'tab' => \Elementor\Controls_Manager::TAB_CONTENT,
]
);
// Contrôle : Sélection des catégories à afficher (multisélection).
$options = [];
$categories = get_categories( [ 'hide_empty' => false ] );
foreach ( $categories as $cat ) {
$options[ $cat->term_id ] = $cat->name;
}
$this->add_control(
'categories',
[
'label' => esc_html__( 'Catégories à afficher', 'category-grid-widget' ),
'type' => \Elementor\Controls_Manager::SELECT2,
'multiple' => true,
'label_block' => true,
'options' => $options,
'description' => esc_html__( 'Sélectionnez les catégories darticles à afficher.', 'category-grid-widget' ),
]
);
// Contrôle : Inclure les sous-catégories.
$this->add_control(
'show_subcategories',
[
'label' => esc_html__( 'Afficher les sous-catégories', 'category-grid-widget' ),
'type' => \Elementor\Controls_Manager::SWITCHER,
'label_on' => esc_html__( 'Oui', 'category-grid-widget' ),
'label_off' => esc_html__( 'Non', 'category-grid-widget' ),
'return_value' => 'yes',
'default' => 'yes',
'description' => esc_html__( 'Inclure aussi les sous-catégories des catégories sélectionnées.', 'category-grid-widget' ),
]
);
// Contrôle : Trier par (critère de tri des catégories).
$this->add_control(
'order_by',
[
'label' => esc_html__( 'Trier par', 'category-grid-widget' ),
'type' => \Elementor\Controls_Manager::SELECT,
'options' => [
'name' => esc_html__( 'Nom (alphabétique)', 'category-grid-widget' ),
'count' => esc_html__( 'Nombre darticles', 'category-grid-widget' ),
'id' => esc_html__( 'ID (date de création)', 'category-grid-widget' ),
],
'default' => 'name',
]
);
// Contrôle : Ordre croissant/décroissant.
$this->add_control(
'order',
[
'label' => esc_html__( 'Ordre', 'category-grid-widget' ),
'type' => \Elementor\Controls_Manager::SELECT,
'options' => [
'ASC' => esc_html__( 'Croissant (A-Z / 0-9)', 'category-grid-widget' ),
'DESC' => esc_html__( 'Décroissant (Z-A / 9-0)', 'category-grid-widget' ),
],
'default' => 'ASC',
]
);
$this->end_controls_section();
/* Section "Mise en page" pour les options d'affichage (colonnes, taille d'image) */
$this->start_controls_section(
'section_layout',
[
'label' => esc_html__( 'Mise en page', 'category-grid-widget' ),
'tab' => \Elementor\Controls_Manager::TAB_CONTENT,
]
);
// Contrôle : Nombre de colonnes de la grille.
$this->add_control(
'columns',
[
'label' => esc_html__( 'Nombre de colonnes', 'category-grid-widget' ),
'type' => \Elementor\Controls_Manager::SELECT,
'options' => [
1 => '1',
2 => '2',
3 => '3',
4 => '4',
5 => '5',
6 => '6',
],
'default' => 3,
]
);
// Contrôle : Taille des images affichées.
$this->add_control(
'image_size',
[
'label' => esc_html__( 'Taille des images', 'category-grid-widget' ),
'type' => \Elementor\Controls_Manager::SELECT,
'options' => [
'thumbnail' => esc_html__( 'Miniature (thumbnail)', 'category-grid-widget' ),
'medium' => esc_html__( 'Moyen (medium)', 'category-grid-widget' ),
'large' => esc_html__( 'Grand (large)', 'category-grid-widget' ),
'full' => esc_html__( 'Plein (full)', 'category-grid-widget' ),
],
'default' => 'medium',
]
);
$this->end_controls_section();
}
/**
* Générer l'affichage du widget côté front-end.
*/
protected function render(): void {
$settings = $this->get_settings_for_display();
// Récupérer les ID des catégories sélectionnées.
$selected_ids = [];
if ( ! empty( $settings['categories'] ) ) {
// S'assurer d'avoir un tableau d'ID (entiers).
$selected_ids = is_array( $settings['categories'] ) ? $settings['categories'] : [ $settings['categories'] ];
$selected_ids = array_map( 'intval', $selected_ids );
}
if ( empty( $selected_ids ) ) {
// Aucune catégorie sélectionnée : ne rien afficher.
return;
}
// Déterminer les catégories à afficher (inclure les sous-catégories si demandé).
$category_ids_to_show = $selected_ids;
if ( ! empty( $settings['show_subcategories'] ) && $settings['show_subcategories'] === 'yes' ) {
// Ajouter les sous-catégories de chaque catégorie sélectionnée.
foreach ( $selected_ids as $cat_id ) {
$child_ids = get_term_children( $cat_id, 'category' );
if ( is_array( $child_ids ) && ! empty( $child_ids ) ) {
$category_ids_to_show = array_merge( $category_ids_to_show, $child_ids );
}
}
// Éliminer les doublons d'ID au cas où.
$category_ids_to_show = array_unique( $category_ids_to_show );
}
// Préparer les arguments de requête pour récupérer les termes.
$term_args = [
'taxonomy' => 'category',
'include' => $category_ids_to_show,
'hide_empty' => false,
];
// Appliquer les options de tri.
if ( ! empty( $settings['order_by'] ) ) {
$term_args['orderby'] = $settings['order_by'];
}
if ( ! empty( $settings['order'] ) ) {
$term_args['order'] = $settings['order'];
}
// Obtenir les termes de catégories à afficher.
$categories = get_terms( $term_args );
if ( is_wp_error( $categories ) || empty( $categories ) ) {
return;
}
// Calculer la classe CSS pour le nombre de colonnes (pour usage dans le CSS).
$columns = ! empty( $settings['columns'] ) ? (int) $settings['columns'] : 3;
$grid_class = 'columns-' . $columns;
// Début du markup HTML de la grille.
echo '<div class="elementor-category-grid ' . esc_attr( $grid_class ) . '">';
foreach ( $categories as $term ) {
$term_name = $term->name;
$term_link = get_term_link( $term );
if ( is_wp_error( $term_link ) ) {
continue; // Ignorer si le lien d'archive pose un problème.
}
// Récupérer l'image de la catégorie via sa méta 'thumbnail_id' (image mise en avant de la catégorie).
$image_url = '';
$thumbnail_id = get_term_meta( $term->term_id, 'thumbnail_id', true );
if ( $thumbnail_id ) {
$size = ! empty( $settings['image_size'] ) ? $settings['image_size'] : 'medium';
$image_url = wp_get_attachment_image_url( $thumbnail_id, $size );
}
echo '<div class="category-card">';
// Rendre la carte cliquable vers l'archive de la catégorie.
echo '<a href="' . esc_url( $term_link ) . '">';
// Image de la catégorie (si disponible).
if ( $image_url ) {
echo '<div class="category-card-image">';
echo '<img src="' . esc_url( $image_url ) . '" alt="' . esc_attr( $term_name ) . '" />';
echo '</div>';
}
// Nom de la catégorie.
echo '<div class="category-card-name">' . esc_html( $term_name ) . '</div>';
echo '</a>';
echo '</div>'; // .category-card
}
echo '</div>'; // .elementor-category-grid
// Astuce : ajouter du CSS (feuille de style ou balise <style>) pour styliser la grille.
// Par exemple, .elementor-category-grid.columns-3 .category-card { width: 33.33%; float: left; } pour disposer 3 colonnes.
}
}