// ===== SHORTCODE BLOG FILTRABLE (paramétrable) =====
function journal_shortcode_blog_filtrable_relevanssi( $atts = array() ) {
// 🔹 Paramètres du shortcode
$atts = shortcode_atts(
array(
'post_type' => 'post', // type de contenu (par défaut : articles)
'taxonomies' => 'category,sources', // taxonomies à afficher/filtrer
'per_page' => 10, // nb d’articles par page
),
$atts,
'blog_filtrable_relevanssi'
);
$post_type = sanitize_text_field( $atts['post_type'] );
$per_page = max( 1, intval( $atts['per_page'] ) );
$taxonomies = array();
// Liste des taxonomies à gérer, en tableau
foreach ( explode( ',', $atts['taxonomies'] ) as $tx ) {
$tx = trim( $tx );
if ( $tx !== '' ) {
$taxonomies[] = $tx;
}
}
// 🔹 Terme de recherche
$search_term = isset($_GET['bfrr_s']) ? sanitize_text_field($_GET['bfrr_s']) : '';
// 🔹 Construction du tax_query global
$tax_query = array();
if ( isset($_GET['tax_query']) && is_array($_GET['tax_query']) ) {
foreach ( $_GET['tax_query'] as $taxonomy => $terms ) {
$terms = array_filter( array_map( 'intval', (array) $terms ) );
if ( ! empty( $terms ) ) {
$tax_query[] = array(
'taxonomy' => $taxonomy,
'field' => 'term_id',
'terms' => $terms,
'operator' => 'IN',
);
}
}
}
if ( count( $tax_query ) > 1 ) {
$tax_query = array_merge( array( 'relation' => 'AND' ), $tax_query );
}
// --- Préparation du texte "Filtre appliqué" ---
$filtre_applique = array();
// Texte pour CHAQUE taxonomie déclarée dans $taxonomies
foreach ( $taxonomies as $tx ) {
if ( isset( $_GET['tax_query'][ $tx ] ) && is_array( $_GET['tax_query'][ $tx ] ) ) {
$ids = array_filter( array_map( 'intval', $_GET['tax_query'][ $tx ] ) );
if ( ! empty( $ids ) ) {
$terms_tx = get_terms( array(
'taxonomy' => $tx,
'include' => $ids,
) );
if ( ! is_wp_error( $terms_tx ) && ! empty( $terms_tx ) ) {
$noms = wp_list_pluck( $terms_tx, 'name' );
// Label lisible : on met le nom de la taxonomie en première lettre majuscule
$label = ucfirst( $tx );
$filtre_applique[] = $label . ' : ' . implode( ', ', $noms );
}
}
}
}
// Texte global
if ( empty( $filtre_applique ) && empty( $search_term ) ) {
$filtre_applique_texte = 'Aucun filtre : tous les articles';
} else {
$parts = array();
if ( ! empty( $search_term ) ) {
$parts[] = 'Texte : « ' . $search_term . ' »';
}
if ( ! empty( $filtre_applique ) ) {
$parts = array_merge( $parts, $filtre_applique );
}
$filtre_applique_texte = 'Filtre appliqué : ' . implode( ' | ', $parts );
}
ob_start();
// 🔹 FORMULAIRE
$page_obj = get_post(); // page actuelle
if ( ! $page_obj ) {
return ''; // sécurité
}
$form_action = get_permalink( $page_obj->ID );
$form_action = strtok( $form_action, '?' ); // enlever query string
echo '<form method="get" action="' . esc_url( $form_action ) . '" class="journal-arbre-form">';
// Champ texte
echo '<p><input type="text" name="bfrr_s" placeholder="Recherche texte (optionnel)" value="' . esc_attr( $search_term ) . '" style="width:100%; padding:6px;"></p>';
// Arbres pour chaque taxonomie déclarée
foreach ( $taxonomies as $tx ) {
// On essaie de récupérer un label poli
$tax_obj = get_taxonomy( $tx );
$title = $tax_obj && ! empty( $tax_obj->labels->name ) ? $tax_obj->labels->name : ucfirst( $tx );
echo journal_afficher_arbre_taxonomie( $tx, $title );
}
// Bouton Rechercher (le bouton Vider est injecté par le JS en footer)
echo '<p><input type="submit" value="Rechercher"></p>';
echo '</form>';
// 🔹 REQUÊTE FILTRÉE
$paged = max(
1,
get_query_var( 'paged' )
? get_query_var( 'paged' )
: ( isset( $_GET['paged'] ) ? intval( $_GET['paged'] ) : 1 )
);
$args = array(
'post_type' => $post_type,
'post_status' => 'publish',
'ignore_sticky_posts' => true,
's' => $search_term,
'paged' => $paged,
'posts_per_page' => $per_page,
);
if ( ! empty( $tax_query ) ) {
$args['tax_query'] = $tax_query;
}
$query = new WP_Query( $args );
// Intégration Relevanssi si actif et si recherche texte
if ( function_exists( 'relevanssi_do_query' ) && ! empty( $search_term ) ) {
relevanssi_do_query( $query );
}
echo '<div class="journal-resultats">';
// 🔹 Affichage du filtre appliqué
echo '<p class="journal-filtre-applique">' . esc_html( $filtre_applique_texte ) . '</p>';
if ( $query->have_posts() ) {
while ( $query->have_posts() ) {
$query->the_post();
echo '<article class="journal-resultat-article">';
echo '<h3 class="journal-resultat-titre"><a href="' . esc_url( get_permalink() ) . '">' . esc_html( get_the_title() ) . '</a></h3>';
echo '<div class="journal-resultat-extrait">' . wp_kses_post( wp_trim_words( get_the_excerpt(), 30, '...' ) ) . '</div>';
echo '</article>';
}
echo paginate_links( array(
'total' => $query->max_num_pages,
'current' => $paged,
) );
} else {
echo '<p>Aucun article trouvé.</p>';
}
echo '</div>';
wp_reset_postdata();
// Script pour ouvrir/fermer les branches de l’arbre (inchangé)
?>
<script>
document.addEventListener("DOMContentLoaded", function() {
document.querySelectorAll(".toggle-node").forEach(function(node) {
node.addEventListener("click", function() {
const subtree = this.parentNode.querySelector(".sub-tree");
if (!subtree) return;
if (subtree.style.display === 'none') {
subtree.style.display = 'block';
this.textContent = 'â–¼';
} else {
subtree.style.display = 'none';
this.textContent = 'â–º';
}
});
});
});
</script>
<?php
return ob_get_clean();
}
add_shortcode( 'blog_filtrable_relevanssi', 'journal_shortcode_blog_filtrable_relevanssi' );