Recherche sur le texte et/ou les mots clés

All contributions published for previous SPIP versions

Cette contrib décrit un squelette qui permet de faire une recherche dans la page de recherche en limitant la recherche soit à des mots contenus dans le texte et/ou à des mots-clés, avec un résultat paginé.

Problèmatique

Il s’agit de pouvoir faire une recherche dans le texte des articles, mais en limitant éventuellement la ’zone’ de recherche à l’aide de mots-clés.

Il faut aussi que, si un seul ou aucun mot-clé n’est sélectionné, ou s’il n’y a pas de recherche sur le texte, la recherche se fasse tout de même.

On cherche ici in fine à sélectionner les articles dans une unique rubrique en fonction des mots-clés qui leur sont attribués et de leur contenu.

Le tout doit être paginé par paquets de 5 réponses.

Cette boucle ne fonctionne pas pour un couple de mots clés (ici tranche + theme) qui n’a pas d’article.

Préliminaires

Ce squelette utilise une des avancées majeures de la 1.8, le critère #ENV . Lisez la documentation si vous voulez comprendre un petit peu se qu’il se passe. Notament la notation #ENV{Tranche,antiBug} qui permet, lorsqu’il n’y a pas d’élément dans #ENV{tranche}, d’éviter une erreur dans le squelette à cause d’une recherche sur un élément vide.

Notez que vous pouvez remplacer antiBug par le nom d’un mot clé existant afin de forcer par défaut la recherche sur ce mot clé.

Dans cet exemple, la recherche porte sur deux groupes de mots clés, Tranches (il s’agit de tranches d’âges) et theme_fiche (les fiches sont classées par thèmes).

Formulaire

Vous pouvez aller voir la page de référence sur les formulaires par le W3C pour aller plus loin.

Voici un exemple de formulaire de recherche pour ce squelette :

<form action="rubrique.php3" method="get" class="formrecherche">
 <input type="hidden" name="id_rubrique" value="#ID_RUBRIQUE">
 <B_liste_tranches>
  <select name="tranche" size="4" title="Sélection de la ou des tranches d'âges voulues">
 <BOUCLE_liste_tranches (MOTS) {type=tranche}>
  <BOUCLE_verifie_si_article_attaches_tranches (ARTICLES) {id_mot} {id_rubrique} {0,1}>
  </BOUCLE_verifie_si_article_attaches_tranches>
 <option <BOUCLE_compare_valeurs_tranche (MOTS) {id_mot} {titre==#ENV{tranche,antiBug}}>selected</BOUCLE_compare_valeurs_tranche>>#TITRE</option>
  </B_verifie_si_article_attaches_tranches>
 </BOUCLE_liste_tranches>
 </select>
 </B_liste_tranches>
 <B_liste_themes>
  <select name="theme" size="4" title="Sélection du ou des thêmes voulus">
 <BOUCLE_liste_themes (MOTS) {type=theme_fiche}>
  <BOUCLE_verifie_si_article_attaches_themes (ARTICLES) {id_mot} {id_rubrique} {0,1}>
  </BOUCLE_verifie_si_article_attaches_themes>
  <option <BOUCLE_compare_valeurs_theme (MOTS) {id_mot} {titre==#ENV{theme,antiBug}}>selected</BOUCLE_compare_valeurs_theme>>#TITRE</option>
  </B_verifie_si_article_attaches_themes>
 </BOUCLE_liste_themes>
 </select>
 </B_liste_themes>
 <input type="text" name="recherche" value="#RECHERCHE">
 <input type="submit" class="formrecherche" value="Rechercher">
</form>
<form action="rubrique.php3" method="get" class="formrecherche">
 <input type="hidden" name="id_rubrique" value="#ID_RUBRIQUE">
 <input type="submit" value="Effacer">
</form>

<form action="rubrique.php3" method="get" class="formrecherche"> : le formulaire appelle la page de destination. Ici il s’agit d’une rubrique. il suffit de changer le contenu de l’élément action pour changer la page de destination. On note que la méthode (get) fait que les paramétres de recherche sont passés dans l’URL.

<input type="hidden" name="id_rubrique" value="#ID_RUBRIQUE"> : c’est ce paramètre qui permet de rester sur la même page (ici une page rubrique).

<BOUCLE_liste_tranches (MOTS) {type=tranche}>
 <BOUCLE_verifie_si_article_attaches_tranches (ARTICLES) {id_mot} {id_rubrique} {0,1}>
 </BOUCLE_verifie_si_article_attaches_tranches>
 <option <BOUCLE_compare_valeurs_tranche (MOTS) {id_mot} {titre==#ENV{tranche,antiBug}}>selected</BOUCLE_compare_valeurs_tranche>>#TITRE</option>
 </B_verifie_si_article_attaches_tranches>
</BOUCLE_liste_tranches>
</select>
</B_liste_tranches>

Dans cette partie, on génére la liste des mots clés du groupe Tranches, afin de remplir la zone de sélection du formulaire. La boucle _liste_theme qui suit celle-ci fait exactement la même chose.

On pourra rajouter à l’élément select un champ size=“X” pour afficher X mots clés en même temps (un ascenseur permettra de faire défiler la liste des mots).

<input type="text" name="recherche" value="#RECHERCHE">
<input type="submit" class="formrecherche" value="Rechercher">

Cette partie est la reprise du code de formulaire_recherche.php3, qui se trouve dans le dossier formulaires de SPIP.

<form action="rubrique.php3" method="get" class="formrecherche">
 <input type="hidden" name="id_rubrique" value="#ID_RUBRIQUE">
 <input type="submit" value="Effacer">
</form>

Ce second forumaire permet de recharger la page de recherche en effaçant toutes les recherches pour reprendre à zéro.

Les boucles de recherche et de pagination

La boucle d’orientation

Cette boucle permet de savoir quel(s) champs de recherche sont remplis :

<BOUCLE_verifie_existence_reponse_a_recherche (ARTICLES) {recherche} {id_rubrique} {0,1}>
 <BOUCLE_verifie_existence_reponse_a_tranche_avec_recherche (ARTICLES) {id_rubrique} {type_mot=tranche} {titre_mot==#ENV{tranche,antiBug}} {0,1}>
  <BOUCLE_verifie_existence_reponse_a_theme_avec_tranche_avec_recherche (ARTICLES) {id_rubrique} {type_mot=theme_fiche} {titre_mot==#ENV{theme,antiBug}} {0,1}>
			
  recherche + tranche + theme
  </BOUCLE_verifie_existence_reponse_a_theme_avec_tranche_avec_recherche>
  </B_verifie_existence_reponse_a_theme_avec_tranche_avec_recherche>

   recherche + tranche	
   <//B_verifie_existence_reponse_a_theme_avec_tranche_avec_recherche>
 </BOUCLE_verifie_existence_reponse_a_tranche_avec_recherche>
 </B_verifie_existence_reponse_a_tranche_avec_recherche>
 <BOUCLE_verifie_existence_reponse_a_theme_sans_tranche_avec_recherche (ARTICLES) {id_article} {type_mot=theme_fiche} {titre_mot==#ENV{theme,antiBug}} {0,1}>
	
   recherche + theme
  </BOUCLE_verifie_existence_reponse_a_theme_sans_tranche_avec_recherche>
  </B_verifie_existence_reponse_a_theme_sans_tranche_avec_recherche>
			
   recherche
  <//B_verifie_existence_reponse_a_theme_sans_tranche_avec_recherche>
 <//B_verifie_existence_reponse_a_tranche_avec_recherche>
</BOUCLE_verifie_existence_reponse_a_recherche>
</B_verifie_existence_reponse_a_recherche>
 <BOUCLE_verifie_existence_reponse_a_tranche_sans_recherche (ARTICLES) {id_rubrique} {type_mot=tranche} {titre_mot==#ENV{tranche,antiBug}} {0,1}>
  <BOUCLE_verifie_existence_reponse_a_theme_avec_tranche_sans_recherche (ARTICLES) {id_rubrique} {type_mot=theme_fiche} {titre_mot==#ENV{theme,antiBug}} {0,1}>
		
   tranche + theme
  </BOUCLE_verifie_existence_reponse_a_theme_avec_tranche_sans_recherche>
  </B_verifie_existence_reponse_a_theme_avec_tranche_sans_recherche>

   tranche
  <//B_verifie_existence_reponse_a_theme_avec_tranche_sans_recherche>
  </BOUCLE_verifie_existence_reponse_a_tranche_sans_recherche>
  </B_verifie_existence_reponse_a_tranche_sans_recherche>
  <BOUCLE_verifie_existence_reponse_a_theme_sans_tranche_sans_recherche (ARTICLES) {id_rubrique} {type_mot=theme_fiche} {titre_mot==#ENV{theme,antiBug}} {0,1}>

   theme
  </BOUCLE_verifie_existence_reponse_a_theme_sans_tranche_sans_recherche>
 <//B_verifie_existence_reponse_a_tranche_sans_recherche>
<//B_verifie_existence_reponse_a_recherche>

Ce qui nous donne, une fois que l’on ajoute les boucles d’affichage et de pagination :

<BOUCLE_verifie_existence_reponse_a_recherche (ARTICLES) {recherche} {id_rubrique} {0,1}>
 <BOUCLE_verifie_existence_reponse_a_tranche_avec_recherche (ARTICLES) {id_rubrique} {type_mot=tranche} {titre_mot==#ENV{tranche,antiBug}} {0,1}>
  <BOUCLE_verifie_existence_reponse_a_theme_avec_tranche_avec_recherche (ARTICLES) {id_rubrique} {type_mot=theme_fiche} {titre_mot==#ENV{theme,antiBug}} {0,1}>
   recherche + tranche + theme
    <BOUCLE_reponse_recherche_tranche_theme (ARTICLES) {id_rubrique} {recherche} {par points} {type_mot=tranche} {titre_mot==#ENV{tranche,antiBug}}>
     <BOUCLE_affiche_reponse_recherche_tranche_theme (ARTICLES) {id_article} {type_mot=theme_fiche} {titre_mot==#ENV{theme,antiBug}} {debut_page,5}>
      <div>
      [<h3><a href="#URL_ARTICLE" hreflang="#LANG" [title="(#DESCRIPTIF|textebrut|attribut_html)"]>(#TITRE|supprimer_numero)</a></h3>#LOGO_ARTICLE][
      (#CHAPO)]<br>
      </div>
     </BOUCLE_affiche_reponse_recherche_tranche_theme>
    </BOUCLE_reponse_recherche_tranche_theme>
    <BOUCLE_reponse_recherche_tranche_theme_pagination (ARTICLES) {id_rubrique} {recherche} {par points} {type_mot=tranche} {titre_mot==#ENV{tranche,antiBug}}>
     <BOUCLE_affiche_reponse_recherche_tranche_theme_pagination (ARTICLES) {id_article} {type_mot=theme_fiche} {titre_mot==#ENV{theme,antiBug}}>
    </BOUCLE_affiche_reponse_recherche_tranche_theme_pagination>
    [<div id="pagination">(#TOTAL_BOUCLE|pagination{debut_page,5})</div>]
    </B_affiche_reponse_recherche_tranche_theme_pagination>
   </BOUCLE_reponse_recherche_tranche_theme_pagination>   </BOUCLE_verifie_existence_reponse_a_theme_avec_tranche_avec_recherche>
   </B_verifie_existence_reponse_a_theme_avec_tranche_avec_recherche>
    recherche + tranche
    <BOUCLE_affiche_reponse_recherche_tranche (ARTICLES) {id_rubrique} {recherche} {par points} {type_mot=tranche} {titre_mot==#ENV{tranche,antiBug}} {debut_page,5}>
     <div>
     [<h3><a href="#URL_ARTICLE" hreflang="#LANG" [title="(#DESCRIPTIF|textebrut|attribut_html)"]>(#TITRE|supprimer_numero)</a></h3>#LOGO_ARTICLE][
     (#CHAPO)]<br>
     </div>
    </BOUCLE_affiche_reponse_recherche_tranche>
    <BOUCLE_affiche_reponse_recherche_tranche_pagination (ARTICLES) {id_rubrique} {recherche} {par points} {type_mot=tranche} {titre_mot==#ENV{tranche,antiBug}}>
    </BOUCLE_affiche_reponse_recherche_tranche_pagination>
     [<div id="pagination">(#TOTAL_BOUCLE|pagination{debut_page,5})</div>]
    </B_affiche_reponse_recherche_tranche_pagination>
    <//B_verifie_existence_reponse_a_theme_avec_tranche_avec_recherche>
   </BOUCLE_verifie_existence_reponse_a_tranche_avec_recherche>
  </B_verifie_existence_reponse_a_tranche_avec_recherche>
 <BOUCLE_verifie_existence_reponse_a_theme_sans_tranche_avec_recherche (ARTICLES) {id_rubrique} {type_mot=theme_fiche} {titre_mot==#ENV{theme,antiBug}} {0,1}>
  recherche + theme
  <BOUCLE_affiche_reponse_recherche_theme (ARTICLES) {id_rubrique} {recherche} {par points} {type_mot=theme_fiche} {titre_mot==#ENV{theme,antiBug}} {debut_page,5}>
   <div>
   [<h3><a href="#URL_ARTICLE" hreflang="#LANG" [title="(#DESCRIPTIF|textebrut|attribut_html)"]>(#TITRE|supprimer_numero)</a></h3>#LOGO_ARTICLE][
   (#CHAPO)]<br>
   </div>
  </BOUCLE_affiche_reponse_recherche_theme>
  <BOUCLE_affiche_reponse_recherche_theme_pagination (ARTICLES) {id_rubrique} {recherche} {par points} {type_mot=theme_fiche} {titre_mot==#ENV{theme,antiBug}}>
  </BOUCLE_affiche_reponse_recherche_theme_pagination>
   [<div id="pagination">(#TOTAL_BOUCLE|pagination{debut_page,5})</div>]
  </B_affiche_reponse_recherche_theme_pagination>
 </BOUCLE_verifie_existence_reponse_a_theme_sans_tranche_avec_recherche>
 </B_verifie_existence_reponse_a_theme_sans_tranche_avec_recherche>
  Recherche
  <BOUCLE_affiche_reponse_recherche (ARTICLES) {id_rubrique} {recherche} {par points} {debut_page,5}>
   <div>
   [<h3><a href="#URL_ARTICLE" hreflang="#LANG" [title="(#DESCRIPTIF|textebrut|attribut_html)"]>(#TITRE|supprimer_numero)</a></h3>#LOGO_ARTICLE][
   (#CHAPO)]<br>
   </div>
  </BOUCLE_affiche_reponse_recherche>
  <BOUCLE_affiche_reponse_recherche_pagination (ARTICLES) {id_rubrique} {recherche} {par points} {debut_page,5}>
  </BOUCLE_affiche_reponse_recherche_pagination>
   [<div id="pagination">(#TOTAL_BOUCLE|pagination{debut_page,5})</div>]
  </B_affiche_reponse_recherche_pagination>
  <//B_verifie_existence_reponse_a_theme_sans_tranche_avec_recherche>
 <//B_verifie_existence_reponse_a_tranche_avec_recherche>
</BOUCLE_verifie_existence_reponse_a_recherche>
</B_verifie_existence_reponse_a_recherche>
 <BOUCLE_verifie_existence_reponse_a_tranche_sans_recherche (ARTICLES) {id_rubrique} {type_mot=tranche} {titre_mot==#ENV{tranche,antiBug}} {0,1}>
  <BOUCLE_verifie_existence_reponse_a_theme_avec_tranche_sans_recherche (ARTICLES) {id_rubrique} {type_mot=theme_fiche} {titre_mot==#ENV{theme,antiBug}} {0,1}>
   tranche + theme
   <BOUCLE_reponse_tranche_theme (ARTICLES) {id_rubrique} {type_mot=tranche} {titre_mot==#ENV{tranche,antiBug}}>
    <BOUCLE_affiche_reponse_tranche_theme (ARTICLES) {id_article} {type_mot=theme_fiche} {titre_mot==#ENV{theme,antiBug}} {debut_page,5}>
     <div>
     [<h3><a href="#URL_ARTICLE" hreflang="#LANG" [title="(#DESCRIPTIF|textebrut|attribut_html)"]>(#TITRE|supprimer_numero)</a></h3>#LOGO_ARTICLE][
     (#CHAPO)]<br>
     </div>
    </BOUCLE_affiche_reponse_tranche_theme>
   </BOUCLE_reponse_tranche_theme>
   <BOUCLE_reponse_tranche_theme_pagination (ARTICLES) {id_rubrique} {type_mot=tranche} {titre_mot==#ENV{tranche,antiBug}}>
    <BOUCLE_affiche_reponse_tranche_theme_pagination (ARTICLES) {id_article} {type_mot=theme_fiche} {titre_mot==#ENV{theme,antiBug}}>
    </BOUCLE_affiche_reponse_tranche_theme_pagination>
     [<div id="pagination">(#TOTAL_BOUCLE|pagination{debut_page,5})</div>]
    </B_affiche_reponse_tranche_theme_pagination>
   </BOUCLE_reponse_tranche_theme_pagination>
  </BOUCLE_verifie_existence_reponse_a_theme_avec_tranche_sans_recherche>
  </B_verifie_existence_reponse_a_theme_avec_tranche_sans_recherche>
   tranche
   <BOUCLE_affiche_reponse_tranche (ARTICLES) {id_rubrique} {type_mot=tranche} {titre_mot==#ENV{tranche,antiBug}} {debut_page,5}>
    <div>
    [<h3><a href="#URL_ARTICLE" hreflang="#LANG" [title="(#DESCRIPTIF|textebrut|attribut_html)"]>(#TITRE|supprimer_numero)</a></h3>#LOGO_ARTICLE][
    (#CHAPO)]<br>
    </div>
   </BOUCLE_affiche_reponse_tranche>
   <BOUCLE_affiche_reponse_tranche_pagination (ARTICLES) {id_rubrique} {type_mot=tranche} {titre_mot==#ENV{tranche,antiBug}}>
   </BOUCLE_affiche_reponse_tranche_pagination>
    [<div id="pagination">(#TOTAL_BOUCLE|pagination{debut_page,5})</div>]
   </B_affiche_reponse_tranche_pagination>
   <//B_verifie_existence_reponse_a_theme_avec_tranche_sans_recherche>
  </BOUCLE_verifie_existence_reponse_a_tranche_sans_recherche>
 </B_verifie_existence_reponse_a_tranche_sans_recherche>
 <BOUCLE_verifie_existence_reponse_a_theme_sans_tranche_sans_recherche (ARTICLES) {id_rubrique} {type_mot=theme_fiche} {titre_mot==#ENV{theme,antiBug}} {0,1}>
  theme
  <BOUCLE_affiche_reponse_theme (ARTICLES) {id_article} {type_mot=theme_fiche} {titre_mot==#ENV{theme,antiBug}} {debut_page,5}>
   <div>
   [<h3><a href="#URL_ARTICLE" hreflang="#LANG" [title="(#DESCRIPTIF|textebrut|attribut_html)"]>(#TITRE|supprimer_numero)</a></h3>#LOGO_ARTICLE][
   (#CHAPO)]<br>
   </div>
  </BOUCLE_affiche_reponse_theme>
  <BOUCLE_affiche_reponse_theme_pagination (ARTICLES) {id_article} {type_mot=theme_fiche} {titre_mot==#ENV{theme,antiBug}}>
  </BOUCLE_affiche_reponse_theme_pagination>
   [<div id="pagination">(#TOTAL_BOUCLE|pagination{debut_page,5})</div>]
  </B_affiche_reponse_theme_pagination>
 </BOUCLE_verifie_existence_reponse_a_theme_sans_tranche_sans_recherche>
 <//B_verifie_existence_reponse_a_tranche_sans_recherche>
<//B_verifie_existence_reponse_a_recherche>

Voir la contrib de James sur la pagination pour ce qui est de la pagination.

Comment fonctionnent ces boucles (le fonctionnement est stritement le même pour ce qui est des boucles de décompte des pagination et de celles d’affichage) ?

Une fois que la boucle d’orientation à permis de déterminer quels sont les champs qui contiennent des données, les boucles qu’elle contient permettent d’afficher les informations pertinentes.

Pour aller plus loin

-  Il est possible d’étendre ce principe à autant de mots clés que l’on veut, mais le nombre de test à réaliser devient considérable si on ne force pas l’utilisateur à sélectionner un mot clé dans chaque groupe.

Peut-être qu’il est possible de remplir #ENV avec une valeur bidon de telle manière qu’il sélectionne tous les articles correspondants au groupe considéré.

-  Trouver une méthode qui permette de signaler un couple de mot clés qui ne posséde pas d’article.

-  On peut étendre ces boucles aux sous rubriques de la rubrique de recherche en changeant {id_rubrique} en {branche} dans les boucles.

-  Il faudrait trouver une méthode pour entrer dans #ENV un tableau à la place d’une variable, ce qui permettrait de faire des sélects sur plusieurs mots clés d’une même groupe :<select name="Theme" multiple title="Sélection du ou des thêmes voulus">

updated on 9 December 2006

Discussion

Une discussion

  • 1

    un exemple? enfin ca fonctionne sur la 1.9? merci

    • Je suis en train de débugguer sous SPIP1.9.2b. Ca peut marcher à condition de changer rubrique.php3 et le hidden input du numéro de rubrique en utilisant la balise #URL_PAGEtoto,id_rubrique=#ID_RUBRIQUE

      Pour la suite, je vous tiens au courant.

    Reply to this message

Comment on this article

Who are you?
  • [Log in]

To show your avatar with your message, register it first on gravatar.com (free et painless) and don’t forget to indicate your Email addresse here.

Enter your comment here

This form accepts SPIP shortcuts {{bold}} {italic} -*list [text->url] <quote> <code> and HTML code <q> <del> <ins>. To create paragraphs, just leave empty lines.

Add a document

Follow the comments: RSS 2.0 | Atom