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

Ceci est une ARCHIVE, peut-être périmée. Vérifiez bien les compatibilités !

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">

Discussion

Aucune discussion

Ajouter un commentaire

Avant de faire part d’un problème sur un plugin X, merci de lire ce qui suit :

  • Désactiver tous les plugins que vous ne voulez pas tester afin de vous assurer que le bug vient bien du plugin X. Cela vous évitera d’écrire sur le forum d’une contribution qui n’est finalement pas en cause.
  • Cherchez et notez les numéros de version de tout ce qui est en place au moment du test :
    • version de SPIP, en bas de la partie privée
    • version du plugin testé et des éventuels plugins nécessités
    • version de PHP (exec=info en partie privée)
    • version de MySQL / SQLite
  • Si votre problème concerne la partie publique de votre site, donnez une URL où le bug est visible, pour que les gens puissent voir par eux-mêmes.
  • En cas de page blanche, merci d’activer l’affichage des erreurs, et d’indiquer ensuite l’erreur qui apparaît.

Merci d’avance pour les personnes qui vous aideront !

Par ailleurs, n’oubliez pas que les contributeurs et contributrices ont une vie en dehors de SPIP.

Qui êtes-vous ?
[Se connecter]

Pour afficher votre trombine avec votre message, enregistrez-la d’abord sur gravatar.com (gratuit et indolore) et n’oubliez pas d’indiquer votre adresse e-mail ici.

Ajoutez votre commentaire ici

Ce champ accepte les raccourcis SPIP {{gras}} {italique} -*liste [texte->url] <quote> <code> et le code HTML <q> <del> <ins>. Pour créer des paragraphes, laissez simplement des lignes vides.

Ajouter un document

Suivre les commentaires : RSS 2.0 | Atom