Recherche avancée sous SPIP

Ajoutez un formulaire de recherche permettant de se limiter à une rubrique, à un mot clé, à une date... affichage Google_like...

Présentation

Vous avez déjà remarqué l’option recherche avancée dans votre moteur de recherche favori... elle vous permet de limiter votre recherche à un certain nombre d’options... Malheureusement, votre SPIP en est dépourvu en standard. Cette contribution va remédier à cet état de fait.

Comment ça marche ?

La recherche de SPIP

Tout d’abord, remarquons que la recherche de SPIP (fichier dist/rechercher.html) est basé sur une boucle :

<BOUCLE_articles(ARTICLES) {recherche} {par points} {inverse} {pagination}>

Restreindre la zone de recherche

Il suffit donc d’y ajouter un argument rubrique pour limiter la recherche à la rubrique en question :

<BOUCLE_articles(ARTICLES){recherche}{par points}{inverse}{rubrique?}{pagination}>

Le « ? » permet de conserver le fonctionnement du squelette d’origine (si aucune rubrique n’est précisée). En fait, on utilisera plutôt {branche?} pour une recherche dans la rubrique et ses sous-rubriques.

Vous pouvez faire l’essai : copier le fichier de la dist dans votre répertoire « squelettes », modifiez le, et lancez une recherche en ajoutant à la fin de la ligne &id_rubrique=1 pour vous limiter à la rubrique 1.

Usage de mot clef

De la même manière, on peut restreindre la recherche à un mot clé que l’on précisera lors de l’appel : {id_mot?}

Selon la durée

Maintenant, cherchons à introduire une condition sur la durée : c’est le critère age qui intervient, mais {age?} ne marchera pas, à moins que l’on ne veuille une date en particulier. On cherche plutôt à avoir tous les articles parus après une date donnée, donc quelque chose comme {age<#ENV{depuis}}depuis a été passé en argument dans la recherche. Mais on perd le comportement initial du squelette (si on ne précise pas l’age en question). J’ai donc choisis une valeur par défaut : {age<#ENV{depuis,1E100}} en espérant que personne n’aura écrit un article il y a plus de 1E100 jours ;-)

Par points

Enfin, notons que la recherche est triée par points, mais que l’on peut assez facilement utiliser un tri différent : {par #ENV{tri, points}} en utilisant une variable passée dans l’environnement.

On peut donc facilement ajouter quelques critères à sa recherche SPIP.

Il reste à définir un formulaire pour envoyer la requête facilement...

Un formulaire de recherche avancée

Le formulaire en question est utilisé en lieu et place du formulaire standard dans le squelette de la recherche, à condition que l’option avancee=1 lui ait été envoyée. Il se présente ainsi :

Formulaire de recherche avancée

Il a été placé dans le fichier formulaires/recherche-avancee.html afin que vous puissiez le modifier plus facilement et introduire les spécificités propres à votre site, car suivant la configuration de celui-ci, le nombre de rubriques ou de mots clé, vous aurez peut-être à le modifier, au risque d’avoir des menus à rallonge ou des critères qui ne vous satisferont pas.

Et pour y accéder plus facilement, j’ai placé un lien dans le fichier formulaires/recherche.html de la dist.

Finalisation

Mais que serait une bonne recherche sans une bonne présentation ? Pour cela, j’y ai introduit un filtre google_like (voir Google Like et Google Like II) et j’ai transformé les points SPIP en pourcentage plus lisible pour le commun des mortels.

Il ne restait plus qu’à ajouter deux image pour donner un peu de couleurs, faire un fichier de style pour une meilleur intégration dans votre site, mettre une icône dans la barre de recherche standard, un fichier de langue pour les traductions et à empaqueter le tout dans un plugin pour faciliter l’installation...

Et voilà le résultat ...

Remerciements

Merci à J-Ph Guihard pour la validation du code html, css et le passage en SPIP v2.xx, suite aux remarques sur le forum


Dernière mise à jour :
-  04/10/2010 Validation html et css, mise à jour du code pour SPIP 2.xx par J-Ph Guihard
-  19/01/2009 Ajout d’options sur les mots-clés (par groupe ou sans le mot clé...)
-  04/05/2008 Bug dans le fichier recherche_avancee_fonctions.php
-  05/09/2007 Problème d’affichage en version 1.9.3 dev
-  29/08/2007 Gestion des Résultats dans la langue de la requête suite aux remarques d’Abelass.
-  13/08/2007 Première version (1.9.2b)

Attention, ce plugin reprend et modifie les fichiers recherche.html et formulaires/recherche.html de la dist, veillez donc à ne pas les avoir déjà surchargés dans votre répertoire « squelettes »...

Discussion

50 discussions

  • 1

    bonjour à tous,
    félicitation pour ce plugin. Je voudrais savoir comment on peut modifier les critères de recherche et sur quel fichier devra-t-on intervenir pour personnaliser et intégrer le formulaire dans nos squelettes ?

    Autre chose, Quand on met #FORMULAIRE_RECHERCHE est ce qu’il y a moyen de ne pas faire appparaître la mention « recherche avancée » ?

    En vous remerciant d’avance, bonne continuation...

    • Bonjour,

      Le fichier à modifier (recopiez le dans votre squelette) est le fichier formulaires/recherche-avancee.html (pour modifier le formulaire) et recherche.html (pour modifier la boucle de recherche et la présentation des résultats).

      Pour ne pas faire apparaître ’recherche avancée’, il faut mettre un display:none dans votre css.

      <style>
      .recherche_avancee { display:none; }
      </style>

      @+

    Répondre à ce message

  • 2
    Tropicaloo

    Bonsoir,

    Ce formulaire reprend un code du plugin Google Like. Qu’en est-il de la faille de sécurité évoquée dans Google Like par rapport au plugin Recherche Avancée ?

    • Bonjour,

      Pas vraiment d’idée là dessus :-(

      J’avait modifié le filtre d’origine. A priori, le filtre commence par faire une conversion en texte brut, ce qui devrait éviter ce genre de problème...

      @+

    • Tropicaloo

      Jean-Marc, merci pour ta réponse.

    Répondre à ce message

  • Génial !

    Merci beaucoup !

    Ca marche !

    Par contre, pour info, en validant mon html sur w3c, il m’a déniché pas mal d’erreurs sur le formulaire, essentiellement liées à des majuscules par ci par là dans les balises !

    C’est toujours bon à savoir !

    Pour ma part, je fonctionne sans le plug-in, et j’ai remodifié les fichiers donc je n’ai pas la version corrigée mais je vous laisse ma version, si ça peut aider quelqu’un !

    <div class="formul2">
    
    		<form action="spip.php?page=recherche" method="get">
    		<fieldset>
    			   
    			<input name='page' value='recherche' type='hidden' />
    			<input name='avancee' value='1' type='hidden' />
    			
    
    	<!-- la chaine cherchee -->
    			<div>
    			<label>Contenant</label>
    			</div>
    			<div>
    			<input type="text" class="forml" name="recherche" id="recherche2" value="#RECHERCHE" />
    			</div>
    
    		
    
    
    	<!-- DATE -->
    			<div>
    			<label>Date limite</label>
    			</div>
    			<div>
    			<select name="depuis">
    				<option value="">aucune</option>
    				<option value="7" [(#ENV{depuis}|=={91}?{"SELECTED"})]>1 semaine</option>
    				<option value="30" [(#ENV{depuis}|=={91}?{"SELECTED"})]>1 mois</option>
    				<option value="91" [(#ENV{depuis}|=={91}?{"SELECTED"})]>3 mois</option>
    				<option value="182" [(#ENV{depuis}|=={182}?{"SELECTED"})]>6 mois</option>
    				<option value="365" [(#ENV{depuis}|=={365}?{"SELECTED"})]>1 an</option>
    				<option value="730" [(#ENV{depuis}|=={365}?{"SELECTED"})]>2 ans</option>
    				<option value="1095" [(#ENV{depuis}|=={365}?{"SELECTED"})]>3 ans</option>
    				<option value="1460" [(#ENV{depuis}|=={365}?{"SELECTED"})]>4 ans</option>
    				<option value="1825" [(#ENV{depuis}|=={365}?{"SELECTED"})]>5 ans</option>
    			</select>
    			</div>
    			
    	<!-- RUBRIQUE -->
        <B_surrub>
        <div>
    			<label>Département</label>
    		</div>
    		<div>
    			<select name="id_rubrique">
    				<option value="">tous</option>
    				<BOUCLE_surrub(RUBRIQUES){racine}>
    					<option value="#ID_RUBRIQUE"[(#ENV{id_rubrique}|=={#ID_RUBRIQUE}?{"SELECTED"})]>#TITRE</option>
    				</BOUCLE_surrub>
    			</select>
    		</div>
        </B_surrub>
    
    	<!-- MOT-CLE -->
       
    
       
        <div>
    			<label>Limiter au mot</label>
    		</div>
    		<div>
    			<select name="id_mot" id="Select1">
    				<option value="">tous</option>
    				<BOUCLE_groupes2(GROUPES_MOTS){par titre}{titre!=niveaurub}>
    				<optgroup label="#TITRE">
    				<BOUCLE_surmot(MOTS){id_groupe}>
    				<BOUCLE_art2 (ARTICLES) {id_mot}>
    				</BOUCLE_art2>
    					<option value="#ID_MOT"[(#ENV{id_mot}|=={#ID_MOT}?{"SELECTED"})]>#TITRE </option>
    				</B_art2>
    				</BOUCLE_surmot>
    				</optgroup>
    				</BOUCLE_groupes2>
    			</select>
    		</div>
     
    
    	
         <div>
    			<label>Exclure le mot</label>
    		</div>
    		<div>
    			<select name="id_nomot">
    				<option value="">aucun</option>
    				<BOUCLE_groupes(GROUPES_MOTS){par titre}{titre!=niveaurub}>
    				<optgroup label="#TITRE">
    				<BOUCLE_nomot(MOTS){id_groupe}>
    				<BOUCLE_art (ARTICLES) {id_mot}>
    				</BOUCLE_art>
    					<option value="#_nomot:ID_MOT"[(#ENV{id_nomot}|=={#_nomot:ID_MOT}?{"SELECTED"})]>#_nomot:TITRE</option>
    				</B_art>
    				</BOUCLE_nomot>
    				</optgroup>
    				</BOUCLE_groupes>
    			</select>
    		</div>
       
    
    	<!-- TRIE -->
         <div>
    			<label>Trier par</label>
    		</div>
    		<div>
    			<select name="tri">
    				<option value="points">pertinence</option>
    				<option value="date" [(#ENV{tri}|=={date}?{"SELECTED"})]>date</option>
    				<option value="id_rubrique" [(#ENV{tri}|=={id_rubrique}?{"SELECTED"})]>département</option>
    				<option value="popularite" [(#ENV{tri}|=={popularite}?{"SELECTED"})]>popularité</option>
    			</select>
    		</div>
    
        
    			<input type="submit" class="bouton" value="Rechercher" />
    
    	</fieldset>	
    		</form>
    
    </div>		

    NB : attention il n’y a plus le tri par groupe car il ne m’était pas util (tous les articles, sur mon site ont un et un seul mot de chaque groupe)

    Répondre à ce message

  • 2

    Salut !

    Tout d’abord merci pour ta réponse !

    Je crois qu’il y a un bug avec la fonction exclure mot clé !

    Chez moi le paramètre n’agit pas, les articles contenant ce mot apparaissent tout de même !
    Pourtant la fonction limiter à un mot fonctionne très bien.

    J’ai retourné le problème dans tous les sens, à mon humble niveau, mais tout me semble bien codé pourtant.

    Suis-je seul à avoir constaté le pb ?

    Merci à vous de procéder à un test.

    Je vous tiens si je trouve une solution !

    je vais me coucher !!!!

    • Bonjour,

      En fait, « exclure mot » ne marche que si l’aticle n’est associé qu’a ce mot clé uniquement, s’il est associé à un autre mot clé dont on demande la sélection, il est sélectionné...

      désolé...

    • re-bonjour,

      En fait, pour exclure vraiment un mot clé (même s’il est associé à d’autres mots clés), il faudrait faire une boucle avant <B_articles> dans le fichier recherche.html avec un critère doublons.

       <BOUCLE_exclure(ARTICLES){id_mot=#ENV{id_nomot}}{doublons}></BOUCLE_exclure>

      et rajouter le critère {doublons} dans la boucle de recherche : BOUCLE_articles.

      Mais cela devient un peu lourd...

      @+

    Répondre à ce message

  • 1

    Salut !

    je viens de découvrir ta contrib !

    Très bon boulot !

    J’ai cependant deux questions afin d’adapter un peu à mes besoins !

    1) Tous d’abord, sur mon site, toussont associés à un et un seul mot de chaque groupe.
    La recherche par groupe n’est donc pas pertinente chez moi.
    Par contre, serait-il possible de faire une recherche sur plusieurs mots clés en même temps ?

    exemple : j’ai un groupe de mots type et un groupe promotion
    Tous mes articles ont un mot clé du groupe type et un du groupe promotion . (un et un seul)
    Mais j’aimerais récupérer les articles par exemple de type mp3 et de la promotion 2008.

    Est-ce faisable, dans la mesure où une boucle article avec id_mot1id_mot2id_mot3 recoupe bien la préseence des 3 mots.

    2) Je reprends une question précédemment posée : la recherche vide ne renvoie aucun résultat.
    Serait-il possible que, dans le cas d’une recherche vide, on obtienne les articles correspondant aux autres caractéristiques ?

    Merci d’avance pour les réponses.

    • Bonjour,

      En fait, c’est plus compliqué :
      -  Pour 1), il faut faire une recherche du type id_mot IN (id_mot1,id_mot2,.... Du coup, si on ne précise plus de id_mot, cela ne marche plus (l’option id_mot ? n’est plus disponible)...
      -  Pour 2, ce n’est plus une recherche au sens de SPIP...

      Il faudrait écrire une fonction spécifique (une boucle sans l’option recherche et avec plusieurs id_mot). Désolé...
      jmv

    Répondre à ce message

  • 3
    Maitresinh

    wow, ça c’est du répondant, merci :)

    le plugin est installé mais apparemment il ne remplace pas par défaut le moteur de rechercher existant ?

    En tout cas, rien n’apparait chez moi.

    J’utilise des blocs ( via magusine) mais a priori cela ne change rien

    • Attention, ce plugin reprend et modifie les fichiers recherche.html et formulaires/recherche.html de la dist.

      Vérifiez bien que magusine ne surcharge pas ces fichiers dans votre répertoire « squelettes »...

      Sinon, supprimer les du répertoire squellettes de votre site... (ou renommez les en .old pour faire un test ;-) et faite un recalculer ou vider le cache comme il se doit !

    • Maitresinh

      en fait j’ai l’impression qu’il les cours-circute en les remplacant par des« blocs ». un bloc appelle effectivement #FORMULAIRE_RECHERCHE

      mais seul le formulaire habituel apparait. a moins de pouvoir appeler un #FORMULAIRE_RECHERCHE_AVANCEE

      il est possible de creer un bloc recherche avancée, mais ça demande d’avoir un code/ boucle a inserer et donc dépluginiser...

      bouuu :/ c’etait trop beau...( puis je récupérer le code de la boucle seule et l’inserer ?)

      une boucle simplifiée alternative sans plugin ?

    • Maitresinh

      je me repond partiellement pour tout ceux qui voudraient l’inclure a magusine :

      Magusine remplace les deux fichiers de recherche par les siens.

      il suffit de les « ecraser » avec ceux du plugin, dans le repertoire plugins/magusine a leur emplacement respectif.

      Malheureusement si cela marche, la page de resultat elle ne correspond pas au squelette pas defaut de magusine. Reste a trouver ou ça coince....(peut etre supprimer le formatage du plugin ?)

      En tout cas merci de ce beau plugin qui permet de facto de transformer des mots clefs en outil performants.

      juste une question :

      et si je veux faire une recherche vide ?

      C’est a dire chercher tous les articles correspondant a : mot clef1 ET mot Clef2 ( avec ou sans selectionner de rubrique ou d’autres criteres ), quelquesoit leur contenu ? ( cela suppose au passage de pouvoir choisir 2 mots clefs)

      j’ai essayé, mais une recherche vide ne renvoie...rien. Ce qui est logique d’une certaine maniere.

    Répondre à ce message

  • 2
    Maitresinh

    oh le beau plugin !

    je voudrais l’adapter pour faire uniquement des recherches multicriteres sur mots clefs (tous les mots clefs selectionnés par defaut) , en affichant le menu deroulant pour chaque groupe....

    quelqu’un a-t-il une idée ?

    • Cela doit pouvoir se faire...

      Dans le fichier recherche.html, il faut reprendre la BOUCLE_articles en remplaçant le paramètre {id_mot?} par {id_goupe?} pour que la recherche se face par groupe de mot.

      Pour l’affichage de la recherche, il faut reprendre la BOUCLE_surmot{MOTS} et la remplacer par une BOUCLE_surmot{GROUPES_MOTS} en remplaçant ID_MOT par ID_GROUPE...

      Bon, je dis ça, mais je n’ai pas vraiment testé...

      @+

    • J’ai mis une nouvelle version qui permet une recherche par groupe de mots.

      à tester ;-)

    Répondre à ce message

  • 5
    Surfingjack

    Bonjour, merci pour le plugin.
    Il m’est très utile, mais j’aimerais rendre la recherche plus précise dans le temps.
    Comment faire pour proposer une recherche limitée entre 2 dates choisies par le visiteur ?

    • Bonjour,

      Pour cela, il vous faut rajouter des champs au formulaire : dans le fichier formulaires/recherche-avancee.html (à recopier et modifier dans squelettes/recherche-avancee.html) ajoutez les lignes (après la ligne 28) :

      <tr><td>
       <label class="forml"> date 1 </label>
      </td><td>
       <input type="text" class="forml" name="date1" id="date1" value=""/>
      </td></tr>
      <tr><td>
       <label class="forml"> date 2 </label>
      </td><td>
       <input type="text" class="forml" name="date2" id="date2" value=""/>
      </td></tr>

      Il vous faut alors prendre en compte ces champs dans le fichier recherche.html : ligne 57 dans la BOUCLE_articles(ARTICLES), rajoutez les paramètres :

      {date>=#ENV{date1}} {date<=#ENV{date2,"3000-01-01"}}

      pour chercher les articles entre date1 et date2. La valeur par défaut « 3000-01-01 » assure que si date2 n’est pas rempli, on cherche les articles publié avant le 1er janvier 3000...

      Attention, vous devez entrer les dates sous la forme : année-mois-jour (2007-11-14).

      Bon SPIP,
      jmv

    • Surfingjack

      Merci, ça fonctionne nickel.
       ;-)

    • bgcolor

      Bravo pour ce plugin fort utile.

      Dans le même ordre d’idées, je voudrais introduire deux autres champs :

      Prix : de [somme1] à [somme2]

      Année : de [année1] à [année2]

      Merci !

    • Bonjour,

      Pour l’année, c’est assez facile, il suffit de remplacer dans l’exemple ci dessus les dates par :

      {date>="#ENV{date1}-01-01} {date<="#ENV{date2}-01-01"}

      Pour le prix, il faut que celui-ci soit définit dans la table des articles et qu’on puisse y accéder dans la boucle SPIP des articles. Dans ce cas, le principe est le même...

      @+

    • bgcolor

      J’ai oublié de préciser que pour l’année, il s’agit d’une année définie en mot clé et non avec la date classique de SPIP.

      Pour le prix, c’est pareil. Je sens que je vais devoir creuser encore.

      Merci

      @+

    Répondre à ce message

  • 2

    Bonjour

    J’essaye d’utiliser la recherche avancee sur les documents rattaches aux rubriques sachant que ces documents utilisent des mots cles du plugin mots partout.

    Je n’arrive pas a limiter la recherche a une rubrique ou a un mot cle. Est-ce possible ou ca ne peut s’appliquer qu’aux articles ?

    Merci d’avance

    George

    • La recherche SPIP est une boucle sur les articles...
      Mais on peut également l’appliquer aux rubriques, brèves et forums.
      (voir sur spip.net)

      Mais a priori, pas pour les documents...

    • Merci pour la reponse mais chez moi la recherche marche sur les titres et descriptifs des documents. Seulement je n’arrive pas a limiter a une rubrique particuliere ou a un mot cle particulier

    Répondre à ce message

  • 3

    Bonjour !!
    nous créeons un site avec un squelette minigrispip et nous avons installer le plugin de recherche avancée. Mais lorsque nous lancons une rechereche avancée, nous nous retrouvons avec ca

     : 1) // Chaine avant $avant = substr($tab[$i][0],-$cc,$cc) ; $mots = split(« « ,$avant,2) ; if (count($mots)>1) $avant = $mots[1] ; // Chaine apres $apres = substr($tab[$i][2],0,$cc) ; $apres = preg_replace(’@(.+)\s\S+@s’, ’\1’, $apres) ; // Concatener if ($string_re==’’) $string_re = »[...] » ; $string_re .= « $avant ».$tab[$i][1].« $apres [...] «  ; // Si rien trouve : renvoyer les premiers mots en resume if ($resume !=’’ && $string_re==’’) $mots = split( » »,$string,40) ; for ($i = 0 ; $i < count($mots)-1 ; $i++) $string_re .= $mots[$i]." " ; if (strlen($string_re)>2*$cc) break ; $string_re .= « [...] » ; return $string_re ;  ?>

    au dessus de notre bandeau......
    Quelqun a t’il une solution ?????
    merci davance !!!!!!!!!

    • Il semble y avoir un problème avec le code du filtre google_like (du fichier recherche_avancee_fonction.php)... (conflit avec un autre plugin ou le squelette ?)

      Comme cela, je n’ai pas d’idée, peut-être le remplacer par un autre ou le supprimer, pour commencer...

      @+

    • ladyweb

      peut-être mettre sur la 1re ligne mettre

      <?php au lieu de <?
      dans le fichier recherche_avancee_fonctions.php
    • OOoops vous avez raison...

      merci

    Répondre à ce message

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