<?php
/
* Twenty Twenty-Five functions and definitions.
*
* @link https://developer.wordpress.org/themes/basics/theme-functions/
*
* @package WordPress
* @subpackage Twenty_Twenty_Five
* @since Twenty Twenty-Five 1.0
*/

Adds theme support for post formats.
if ( ! function_exists( 'twentytwentyfive_post_format_setup' ) ) :
/
* Adds theme support for post formats.
*
* @since Twenty Twenty-Five 1.0
*
* @return void
*/
function twentytwentyfive_post_format_setup() {
add_theme_support( 'post-formats', array( 'aside', 'audio', 'chat', 'gallery', 'image', 'link', 'quote', 'status', 'video' ) );
}
endif;
add_action( 'after_setup_theme', 'twentytwentyfive_post_format_setup' );

Enqueues editor-style.css in the editors.
if ( ! function_exists( 'twentytwentyfive_editor_style' ) ) :
/
* Enqueues editor-style.css in the editors.
*
* @since Twenty Twenty-Five 1.0
*
* @return void
*/
function twentytwentyfive_editor_style() {
add_editor_style( 'assets/css/editor-style.css' );
}
endif;
add_action( 'after_setup_theme', 'twentytwentyfive_editor_style' );

Enqueues style.css on the front.
if ( ! function_exists( 'twentytwentyfive_enqueue_styles' ) ) :
/
* Enqueues style.css on the front.
*
* @since Twenty Twenty-Five 1.0
*
* @return void
*/
function twentytwentyfive_enqueue_styles() {
wp_enqueue_style(
'twentytwentyfive-style',
get_parent_theme_file_uri( 'style.css' ),
array(),
wp_get_theme()→get( 'Version' )
);
}
endif;
add_action( 'wp_enqueue_scripts', 'twentytwentyfive_enqueue_styles' );

Registers custom block styles.
if ( ! function_exists( 'twentytwentyfive_block_styles' ) ) :
/
* Registers custom block styles.
*
* @since Twenty Twenty-Five 1.0
*
* @return void
*/
function twentytwentyfive_block_styles() {
register_block_style(
'core/list',
array(
'name' ⇒ 'checkmark-list',
'label' ⇒ ( 'Checkmark', 'twentytwentyfive' ),
'inline_style' ⇒ '
ul.is-style-checkmark-list {
list-style-type: “\2713”;
}

ul.is-style-checkmark-list li {
padding-inline-start: 1ch;
}',
)
);
}
endif;
add_action( 'init', 'twentytwentyfive_block_styles' );

Registers pattern categories.
if ( ! function_exists( 'twentytwentyfive_pattern_categories' ) ) :
/
* Registers pattern categories.
*
* @since Twenty Twenty-Five 1.0
*
* @return void
*/
function twentytwentyfive_pattern_categories() {

register_block_pattern_category(
'twentytwentyfive_page',
array(
'label' ⇒ ( 'Pages', 'twentytwentyfive' ),
'description' ⇒
( 'A collection of full page layouts.', 'twentytwentyfive' ),
)
);

register_block_pattern_category(
'twentytwentyfive_post-format',
array(
'label' ⇒ ( 'Post formats', 'twentytwentyfive' ),
'description' ⇒
( 'A collection of post format patterns.', 'twentytwentyfive' ),
)
);
}
endif;
add_action( 'init', 'twentytwentyfive_pattern_categories' );

Registers block binding sources.
if ( ! function_exists( 'twentytwentyfive_register_block_bindings' ) ) :
/
* Registers the post format block binding source.
*
* @since Twenty Twenty-Five 1.0
*
* @return void
*/
function twentytwentyfive_register_block_bindings() {
register_block_bindings_source(
'twentytwentyfive/format',
array(
'label' ⇒ _x( 'Post format name', 'Label for the block binding placeholder in the editor', 'twentytwentyfive' ),
'get_value_callback' ⇒ 'twentytwentyfive_format_binding',
)
);
}
endif;
add_action( 'init', 'twentytwentyfive_register_block_bindings' );

Registers block binding callback function for the post format name.
if ( ! function_exists( 'twentytwentyfive_format_binding' ) ) :
/**
* Callback function for the post format name block binding source.
*
* @since Twenty Twenty-Five 1.0
*
* @return string|void Post format name, or nothing if the format is 'standard'.
*/
function twentytwentyfive_format_binding() {
$post_format_slug = get_post_format();

if ( $post_format_slug && 'standard' !== $post_format_slug ) {
return get_post_format_string( $post_format_slug );
}
}
endif;

===== TAXONOMIE “Sources” =====
function journal_register_taxonomy_sources() {
$labels = array(
'name' ⇒ 'Sources',
'singular_name' ⇒ 'Source',
'search_items' ⇒ 'Rechercher des sources',
'all_items' ⇒ 'Toutes les sources',
'parent_item' ⇒ 'Source parente',
'parent_item_colon' ⇒ 'Source parente :',
'edit_item' ⇒ 'Modifier la source',
'update_item' ⇒ 'Mettre à jour la source',
'add_new_item' ⇒ 'Ajouter une nouvelle source',
'new_item_name' ⇒ 'Nom de la nouvelle source',
'menu_name' ⇒ 'Sources',
);

$args = array(
'labels' ⇒ $labels,
'public' ⇒ true,
'hierarchical' ⇒ true, parent/enfant
'show_ui' ⇒ true,
'show_admin_column' ⇒ true,
'show_in_rest' ⇒ true,
'rewrite' ⇒ array('slug' ⇒ 'sources'),
);

register_taxonomy('sources', array('post'), $args);
}
add_action('init', 'journal_register_taxonomy_sources');


===== FONCTION POUR AFFICHER UN ARBRE DE TAXONOMIE =====
function journal_afficher_arbre_taxonomie($taxonomy, $title) {
$terms = get_terms(array(
'taxonomy' ⇒ $taxonomy,
'hide_empty' ⇒ false,
));

if (empty($terms) || is_wp_error($terms)) {
return “<p>Aucun terme trouvé pour : ” . esc_html($taxonomy) . “</p>”;
}

Hiérarchie parent → enfants
$hierarchie = array();
foreach ($terms as $term) {
$hierarchie[$term→parent][] = $term;
}

$selected = array();
if (isset($_GET['tax_query'][$taxonomy]) && is_array($_GET['tax_query'][$taxonomy])) {
$selected = array_map('intval', $_GET['tax_query'][$taxonomy]);
}

$build_tree = function($parent_id) use (&$build_tree, $hierarchie, $selected, $taxonomy) {
if (!isset($hierarchie[$parent_id])) return ;

$html = '<ul class=“journal-arbre-taxo”>';
foreach ($hierarchie[$parent_id] as $term) {
$has_children = isset($hierarchie[$term→term_id]);
$checked = in_array($term→term_id, $selected) ? 'checked' :
;

$html .= '<li>';
$html .= $has_children ? '' : '';
$html .= '<input type=“checkbox” name=“tax_query['.esc_attr($taxonomy).'][]” value=“'.intval($term→term_id).'” '.$checked.'> '.esc_html($term→name).'';

if ($has_children) {
$html .= '

'.$build_tree($term→term_id).'

';
}
$html .= '</li>';
}
$html .= '</ul>';
return $html;
};

return '<h3>'.esc_html($title).'</h3>'.$build_tree(0);
}


===== SHORTCODE BLOG FILTRABLE =====
function journal_shortcode_blog_filtrable_relevanssi() {
$search_term = isset($_GET['bfrr_s']) ? sanitize_text_field($_GET['bfrr_s']) : ;
$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);
}

ob_start();

FORMULAIRE
$page_obj = get_post();
page actuelle
$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”>';
echo '<p><input type=“text” name=“bfrr_s” placeholder=“Recherche texte (optionnel)” value=“'.esc_attr($search_term).'” style=“width:100%; padding:6px;”></p>';
echo journal_afficher_arbre_taxonomie('category', 'Catégories');
echo journal_afficher_arbre_taxonomie('sources', 'Sources');
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',
'post_status' ⇒ 'publish',
'ignore_sticky_posts' ⇒ true,
's' ⇒ $search_term,
'paged' ⇒ $paged,
'posts_per_page' ⇒ 10,
);

if (!empty($tax_query)) $args['tax_query'] = $tax_query;

$query = new WP_Query($args);

echo '

';

  if ($query->have_posts()) {
      while ($query->have_posts()) {
          $query->the_post();
          echo '<article>';
          echo '<h4><a href="'.esc_url(get_permalink()).'">'.esc_html(get_the_title()).'</a></h4>';
          echo '<p>Publié le '.esc_html(get_the_date()).'</p>';
          echo '<div>'.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>
  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');

===== SHORTCODE [dernier_article] =====
Version : affiche seulement l'extrait + bouton “Lire l'article complet”

if ( ! function_exists( 'bfrr_dernier_article_shortcode' ) ) {

  function bfrr_dernier_article_shortcode() {
      $args  = [
          'post_type'      => 'post',
          'post_status'    => 'publish',
          'posts_per_page' => 1,
      ];
      $query = new WP_Query( $args );
      if ( ! $query->have_posts() ) {
          return '<p>Aucun article trouvé.</p>';
      }
      ob_start();
      while ( $query->have_posts() ) {
          $query->the_post();
          $post_id = get_the_ID();
          $permalink = get_permalink();
          echo '<article class="bfrr-dernier-article">';
          // Titre cliquable
          echo '<h2 class="bfrr-da-titre"><a href="' . esc_url( $permalink ) . '">' . esc_html( get_the_title() ) . '</a></h2>';
          // Date
          echo '<p class="bfrr-da-meta">Publié le ' . esc_html( get_the_date() ) . '</p>';
          // Catégories
          $cats_list = get_the_category_list( ', ' );
          if ( $cats_list ) {
              echo '<p class="bfrr-da-taxo bfrr-da-cats"><strong>Catégories : </strong>' . wp_kses_post( $cats_list ) . '</p>';
          }
          // Sources (taxonomie personnalisée)
          $sources = get_the_terms( $post_id, 'sources' );
          if ( $sources && ! is_wp_error( $sources ) ) {
              $sources_names = wp_list_pluck( $sources, 'name' );
              echo '<p class="bfrr-da-taxo bfrr-da-sources"><strong>Sources : </strong>' . esc_html( implode( ', ', $sources_names ) ) . '</p>';
          }
          // Étiquettes
          $tags_list = get_the_tag_list( '', ', ' );
          if ( $tags_list ) {
              echo '<p class="bfrr-da-taxo bfrr-da-tags"><strong>Étiquettes : </strong>' . wp_kses_post( $tags_list ) . '</p>';
          }
          // 🔹 EXTRAI T (et non plus le contenu complet)
          echo '<div class="bfrr-da-contenu">';
          echo wp_kses_post( wp_trim_words( get_the_excerpt(), 55, '...' ) );
          echo '</div>';
          // 🔹 Bouton "Lire l'article complet"
          echo '<p class="bfrr-da-bouton-wrapper">';
          echo '<a class="bfrr-da-bouton" href="' . esc_url( $permalink ) . '">Lire l’article complet</a>';
          echo '</p>';
          echo '</article>';
      }
      wp_reset_postdata();
      return ob_get_clean();
  }

}
add_shortcode( 'dernier_article', 'bfrr_dernier_article_shortcode' );
===== SHORTCODE [derniers_articles nb=“3”] =====
Affiche N derniers articles avec image mise en avant + métas + extrait + bouton + commentaires

if ( ! function_exists( 'bfrr_derniers_articles_shortcode' ) ) {

  function bfrr_derniers_articles_shortcode( $atts ) {
      // Attributs : nb = nombre d'articles à afficher (défaut = 3)
      $atts = shortcode_atts(
          [
              'nb' => 3,
          ],
          $atts,
          'derniers_articles'
      );
      $nb = max( 1, intval( $atts['nb'] ) );
      $args  = [
          'post_type'      => 'post',
          'post_status'    => 'publish',
          'posts_per_page' => $nb,
      ];
      $query = new WP_Query( $args );
      if ( ! $query->have_posts() ) {
          return '<p>Aucun article trouvé.</p>';
      }
      ob_start();
      echo '<div class="bfrr-derniers-articles-wrapper">';
      while ( $query->have_posts() ) {
          $query->the_post();
          $post_id   = get_the_ID();
          $permalink = get_permalink();
          echo '<article class="bfrr-dernier-article">';
          // Bloc image mise en avant (optionnel)
          if ( has_post_thumbnail( $post_id ) ) {
              echo '<div class="bfrr-da-thumbnail">';
              echo '<a href="' . esc_url( $permalink ) . '">';
              echo get_the_post_thumbnail( $post_id, 'medium_large', [ 'class' => 'bfrr-da-thumb-img' ] );
              echo '</a>';
              echo '</div>';
          }
          echo '<div class="bfrr-da-content">';
          // Titre cliquable
          echo '<h2 class="bfrr-da-titre"><a href="' . esc_url( $permalink ) . '">' . esc_html( get_the_title() ) . '</a></h2>';
          // Date
          echo '<p class="bfrr-da-meta">Publié le ' . esc_html( get_the_date() ) . '</p>';
          // Catégories
          $cats_list = get_the_category_list( ', ' );
          if ( $cats_list ) {
              echo '<p class="bfrr-da-taxo bfrr-da-cats"><strong>Catégories : </strong>' . wp_kses_post( $cats_list ) . '</p>';
          }
          // Sources (taxonomie personnalisée)
          $sources = get_the_terms( $post_id, 'sources' );
          if ( $sources && ! is_wp_error( $sources ) ) {
              $sources_names = wp_list_pluck( $sources, 'name' );
              echo '<p class="bfrr-da-taxo bfrr-da-sources"><strong>Sources : </strong>' . esc_html( implode( ', ', $sources_names ) ) . '</p>';
          }
          // Étiquettes
          $tags_list = get_the_tag_list( '', ', ' );
          if ( $tags_list ) {
              echo '<p class="bfrr-da-taxo bfrr-da-tags"><strong>Étiquettes : </strong>' . wp_kses_post( $tags_list ) . '</p>';
          }
          // Extrait
          echo '<div class="bfrr-da-contenu">';
          echo wp_kses_post( wp_trim_words( get_the_excerpt(), 55, '...' ) );
          echo '</div>';
          // Bouton vers l'article complet
          echo '<p class="bfrr-da-bouton-wrapper">';
          echo '<a class="bfrr-da-bouton" href="' . esc_url( $permalink ) . '">Lire l’article complet</a>';
          echo '</p>';
          // 🔹 Zone de commentaires sur la page d'accueil (ou la page du shortcode)
          echo '<div class="bfrr-da-comments-block">';
          echo '<h3>Laisser un commentaire sur cet article</h3>';
          $comment_args = [
              'title_reply'   => '',
              'label_submit'  => 'Envoyer le commentaire',
              'comment_field' =>
                  '<p class="comment-form-comment">
                      <label for="comment">Commentaire à propos de : ' . esc_html( get_the_title() ) . '</label>
                      <textarea id="comment" name="comment" cols="45" rows="5" aria-required="true"></textarea>
                   </p>',
          ];
          // Les commentaires seront liés à la page courante (la page où se trouve le shortcode)
          comment_form( $comment_args );
          echo '</div>'; // .bfrr-da-comments-block
          echo '</div>'; // .bfrr-da-content
          echo '</article>';
      }
      echo '</div>';
      wp_reset_postdata();
      return ob_get_clean();
  }

}
add_shortcode( 'derniers_articles', 'bfrr_derniers_articles_shortcode' );