FEATURE Refining search behaviour
All checks were successful
continuous-integration/drone/push Build is passing

This commit is contained in:
Nonimart 2025-10-15 14:52:00 +02:00
parent 999dd1a55d
commit 8a057c15a9
4 changed files with 138 additions and 13 deletions

View File

@ -297,7 +297,7 @@ function get_post_likes_count($post_id)
*/
function display_likes_count($post_id, $show_icon = true)
{
$likes_count = get_likes_count($post_id);
$likes_count = get_post_likes_count($post_id);
$icon = $show_icon ? '❤️ ' : '';
return $icon . $likes_count . ' like' . ($likes_count > 1 ? 's' : '');
@ -435,3 +435,85 @@ function generate_og_meta_tags()
return implode("\n\t", $meta_tags);
}
/**
* Génère un extrait de recherche avec le terme surligné
*
* Cette fonction cherche le terme de recherche dans le contenu du post
* et retourne un extrait avec le terme mis en évidence.
*
* @param int $post_id L'ID du post
* @param string $search_term Le terme à rechercher et surligner
* @param int $context_length Nombre de caractères de contexte autour du terme (défaut: 150)
* @return string L'extrait avec le terme surligné en HTML
*/
function get_search_snippet($post_id, $search_term, $context_length = 150)
{
if (empty($search_term)) {
return wp_trim_words(get_the_excerpt($post_id), 30);
}
// Récupérer le contenu complet
$content = get_post_field('post_content', $post_id);
$title = get_the_title($post_id);
// Nettoyer le contenu des balises HTML et shortcodes
$content = wp_strip_all_tags($content);
$content = strip_shortcodes($content);
// Recherche insensible à la casse
$search_term_escaped = preg_quote($search_term, '/');
$position = stripos($content, $search_term);
// Si le terme n'est pas trouvé dans le contenu, chercher dans le titre
if ($position === false) {
$position_in_title = stripos($title, $search_term);
if ($position_in_title !== false) {
// Si trouvé dans le titre, retourner juste le début du contenu
$snippet = substr($content, 0, $context_length * 2);
$snippet = wp_trim_words($snippet, 30);
// Surligner dans le titre et le snippet
$highlighted_title = preg_replace(
'/(' . $search_term_escaped . ')/i',
'<mark class="search-highlight">$1</mark>',
$title
);
return '<strong>' . $highlighted_title . ':</strong> ' . $snippet;
}
// Si vraiment pas trouvé, retourner l'excerpt normal
return wp_trim_words(get_the_excerpt($post_id), 30);
}
// Calculer les positions de début et fin de l'extrait
$start = max(0, $position - $context_length);
$end = min(strlen($content), $position + strlen($search_term) + $context_length);
// Extraire le snippet
$snippet = substr($content, $start, $end - $start);
// Ajouter des points de suspension si nécessaire
if ($start > 0) {
$snippet = '...' . $snippet;
}
if ($end < strlen($content)) {
$snippet = $snippet . '...';
}
// Surligner tous les termes de recherche (supporte les recherches multiples)
$search_terms = explode(' ', $search_term);
foreach ($search_terms as $term) {
if (strlen(trim($term)) > 2) { // Ignorer les mots trop courts
$term_escaped = preg_quote(trim($term), '/');
$snippet = preg_replace(
'/(' . $term_escaped . ')/i',
'<mark class="search-highlight">$1</mark>',
$snippet
);
}
}
return $snippet;
}

View File

@ -37,6 +37,17 @@
@apply bg-white p-8 border border-primary;
@apply transition-shadow hover:shadow-lg;
&__title {
line-height: 1.2;
}
.content-meta {
}
&__type {
@apply inline-block mb-3 px-3 py-1 font-semibold;
@apply text-primary;
}
h2 {
@apply mb-4;
@ -49,6 +60,10 @@
@apply inline-block mt-4 text-primary font-semibold;
@apply hover:underline;
}
.search-highlight {
@apply text-primary bg-carhop-green-50 font-bold;
}
}
.search-results-pagination {

View File

@ -23,16 +23,48 @@
<?php if (have_posts()) : while (have_posts()) : the_post(); ?>
<div class="search-results-card">
<?php
$post_type = get_post_type();
$post_type_object = get_post_type_object($post_type);
$post_type_label = $post_type_object->labels->singular_name;
?>
<h2 class="search-results-page__results-container__item__content__title">
<a href="<?php the_permalink(); ?>"><?php the_title(); ?></a>
</h2>
<div class="search-results-page__results-container__item__content__excerpt">
<?php the_excerpt(); ?>
<div class="content-meta">
<span class="content-meta__type content-meta__type--<?php echo $post_type; ?>"><?php echo $post_type_label; ?></span>
</div>
<a href="<?php the_permalink(); ?>" class="search-results-card__link">
<?php echo __('Lire la suite', 'homegrade-theme__texte-fonctionnel'); ?>
</a>
<!-- <span class="search-results-card__type"><?php echo esc_html($post_type_label); ?></span> -->
<h2 class="search-results-card__title">
<a href="<?php the_permalink(); ?>">
<?php
$title = get_the_title();
$search_query = get_search_query();
if (!empty($search_query)) {
$search_terms = explode(' ', $search_query);
foreach ($search_terms as $term) {
if (strlen(trim($term)) > 2) {
$term_escaped = preg_quote(trim($term), '/');
$title = preg_replace(
'/(' . $term_escaped . ')/i',
'<mark class="search-highlight">$1</mark>',
$title
);
}
}
}
echo $title;
?>
</a>
</h2>
<div class="search-results-page__search-snippet">
<?php echo get_search_snippet(get_the_ID(), get_search_query()); ?>
</div>
<?php get_template_part('template-parts/components/cta--go', null, array(
'url' => get_the_permalink(),
'label' => 'Lire la suite',
'target' => '_self',
)); ?>
</div>
<?php endwhile; ?>

View File

@ -6,10 +6,6 @@
<input class="search-module__search-form__input" type="text" name="s" id="search" value="<?php the_search_query(); ?>" placeholder="<?php echo __('Rechercher dans la revue Dynamiques', 'homegrade-theme__texte-fonctionnel') ?>" />
<!-- Ou pour plusieurs types : -->
<input type="hidden" name="post_type[]" value="articles">
<input type="hidden" name="post_type[]" value="revues">
<button type="submit">
<span><?php echo __('Rechercher', 'homegrade-theme__texte-fonctionnel') ?></span>