Critère {mots}

Permettre de sélectionner facilement des objets SPIP ayant un ou des mots clefs en communs.

Présentation

Il peut arriver parfois de vouloir sélectionner des objets SPIP (articles, rubriques, sites etc.), ayant un certains nombre de mot clefs connus.

Par exemple, je voudrais sélectionner les articles ayant les mots clefs “fruits” et “desserts”, mais pas ceux qui n’ont que “desserts” ou que “fruits”.

Une telle opération, bien que possible, est assez difficile en SPIP ... sauf si vous utilisez ce plugin.

Il s’installe comme n’importe quel plugin.

Il propose trois critères :
-  {mots}
-  {mots_selon_id}
-  {mots_selon_titre}

Il ne faut utiliser qu’une seule fois par boucle l’un de ces critères.

Le critère {mots}

Prenons un exemple :

<BOUCLE_art(ARTICLES){mots}>
#TITRE
</BOUCLE_art>

Cette boucle sélectionnera les articles ayant tous les mots clefs passés en paramètres d’environnement dans un tableau “mots”.

Comment passer ces mots-clefs en paramètres d’environnement ?

Typiquement, sur une page principale (non incluse), via des paramètres dans l’url. Par exemple : http://www.toto.fr/?page=toto&amp;amp;mots[0]=1&amp;amp;mots[1]=2.

Ici, j’ai passé dans le tableau ’mots’ les valeurs 1 et 2. Les articles associés, à la fois au mot dont l’id est 1 et à celui dont l’id est 2 seront sélectionnés [1].

Les valeurs du tableau ’mots’ peuvent être des identifiants de mots (1, 2) ou des titres de mots (“fruits”, “desserts”).

Attention au cas où des mots clefs sont uniquement sous forme de nombre ...

Le critère {mots_selon_id}

Il fonctionne exactement comme le critère {mots}, à ceci près que les valeurs du tableau ’mots’ sont forcément des identifiants de mots (1,2).

Le critère {mots_selon_titre}

Il fonctionne exactement comme le critère {mots}, à ceci près que les valeurs du tableau ’mots’ sont forcément des titres de mots (“fruits”,“desserts”).

Les paramètres supplémentaires

Les trois critères {mots},{mots_selon_id} et {mots_selon_titre} peuvent prendre trois paramètres : ’score’, ’tableau’, ’tri’. Sous la forme {mots score tableau}.

Le paramètre ’score’.

Par défaut, le critère {mots} prend les objets ayant tous les mots passés en paramètre. On peut décider de vouloir prendre ceux ayant au moins un certain nombre de mots passés paramètre, mais pas nécessairement tous. C’est à cela que sert le paramètre ’score’.

-  Si score est compris entre 0 et 1 (exclus), alors SPIP sélectionnera les objets ayant au moins ce pourcentage de mots [2] sur le total des mots passés en paramètre. Par exemple si j’écris {mots 0.5}, et que je passe 10 mots en paramètre, alors SPIP sélectionnera les objets ayant au moins 10*0.5 = 5 des mots passés en paramètre.
-  Si score est supérieur ou égale à 1 et suivi du signe “%”, alors SPIP sélectionnera les objets ayant au moins ce pourcentage sur le total des mots passés en paramètre. Par exemple si j’écris {mots 50%}, et que je passe 10 mots en paramètre, alors SPIP sélectionnera les objets ayant au moins 50% de 10 = 5 des mots passés en paramètre.
-  Si score est supérieur ou égale à 1, mais n’est pas suivi du signe “%”, alors SPIP sélectionnera les objets ayant au moins ’score’ mots passés en paramètres. Par exemple {mots 5} sélectionnera les objets ayant au moins 5 mots passés en paramètre.

Le paramètre ’tableau’.

Par défaut, SPIP prend comme tableau la variable d’environnement ’mots’. Mais on peut lui dire, via ce paramètre, de prendre un autre tableau.

Ce peut être un tableau :
-  calculé via #GET et #SET
-  inscrit en dur via #ARRAY
-  passé en variable d’environnement, et appelé via #ENV.

Ex : {mots 100% #ARRAY{0,2,1,1}} sélectionnera les objets ayant les mots clefs 2 et 1. Notez qu’il est obligatoire de donner une valeur au paramètre ’score’ pour utiliser ’tableau’, sinon SPIP les confond.

Le paramètre ’tri’

Ce paramètre, existant depuis la version 2.1 (sous SPIP 3) ou 1.3 (sous SPIP 2.1 et 2.0) peut prendre deux valeurs :
-  tri pour trier la boucle en fonction du nombre de mots du tableau associés, en commençant par le plus petit nombre.
-  !tri pour trier la boucle en fonction du nombre de mots du tableau associés, en commençant par le plus grand nombre.

Exemple :

L’article 1 est associé aux mots 1,2,3 ; l’article 2 est associé aux mots 2,3,4,5,6.

{mots 2 #LISTE{1,2,3} !tri} affichera d’abord l’article 1, puis l’article 2.
En effet, l’article 1 est associé à 3 mots dans la liste (1,2,3), tandis que l’article 2 n’est associé qu’à 2 mots dans la liste (2,3).

Formulaire de sélection

Avec la version 1.1 de ce plugin, une nouvelle possibilité s’offre à vous : faire appel à un formulaire bâtissant pour vous les critères dans l’url pour filtrer selon plusieurs mots clefs.

Connecté en tant que webmestre, vous pouvez tester avec la page de démonstration : /?page=demo/parmots.

Le formulaire présente dans un premier temps la liste de vos groupes de mots clefs.

Dès que vous en choisissez un dans la liste, automatiquement [3], la liste des mots clefs de ce groupe est affichée juste à côté.

Choisissez un mot clef, et ce dernier et ajouté à l’URL pour ne vous présenter que les articles ayant ce mot clef.

Et le processus peut être répété autant de fois que nécessaire.

Bonus : la liste des mots clefs déjà choisis est affichée sous le formulaire. Chaque mot est cliquable. Un clic le supprime de l’URL et de la liste.

Le formulaire critère mots en action
Le formulaire critère mots en action

Usage du formulaire

-  Sur une seule page

  • en affichant tous les groupes de mots :
    <div class="ajax">
    [(#FORMULAIRE_RECHERCHE_PAR_MOTS)]
    </div>
  • en n’affichant que certains groupes de mots :
    #SET{FiltreGroupes,#ARRAY}
    <BOUCLE_FiltreGroupes(GROUPES_MOTS){titre==^[^_]}>
    #SET{FiltreGroupes,
           #GET{FiltreGroupes}|push{#ID_GROUPE}}
    </BOUCLE_FiltreGroupes>
    <div class="ajax">
    [(#FORMULAIRE_RECHERCHE_PAR_MOTS{#GET{FiltreGroupes}})]
    </div>

    Ici, on a choisi de ne pas afficher les groupes de mots commençants par “_”.

-  On peut aussi utiliser le formulaire sur toute les pages du site pour renvoyer sur une page de résultats :

  1. [(#FORMULAIRE_RECHERCHE_PAR_MOTS{'',#URL_PAGE{pagederesultats}})]

NB :

  • le premier paramètre est un tableau d’identifiants de groupes, ou la chaine vide
  • le deuxième paramètre est l’URL de la page qui affiche les résultats.

Usage avec le plugin Mots arborescents

Par défaut, seul le mot-clé demandé est recherché.

Mais il est possible de trouver via n’importe quel mot-clé de la branche du mot-clé demandé en mettant dans mes_options.php :

if (!defined('_CRITERE_MOTS_ARBO_BRANCHE'))
    define('_CRITERE_MOTS_ARBO_BRANCHE', true); 

Footnotes

[1Pour des pages incluses, il suffit de passer {mots} comme paramètre d’inclusion.

[2Car un nombre entre 0 et 1 est un pourcentage

[3Si vous n’avez pas désactivé javascript

NOTA SPIP branche 2.*

Attention : la partie formulaire de ce plugin ne fonctionnera pas avec la version 2.0.10 de SPIP. Il faut :

On pourra utiliser le plugin pour, par exemple afficher les articles connexes.

updated on 15 July 2019

Discussion

71 discussions

  • 7

    Bonjour,

    J’ai besoin de ce plugins pour insérer un formulaire de recherche sur un site que je suis en train de réaliser.
    Voilà un bon moment que je me casse les dents dessus.

    Mon objectif :
    Sur une page réunissant plusieurs brèves, je souhaite que les visiteurs puissent effectuer un trie de ces brèves selon les mots clefs qu’ils auront choisie.
    J’ai 3 groupes de mots clefs et je souhaite que le trie soit effectué selon deux de ces groupes (le troisième me servant ailleurs, mais pas dans ce cas présent).
    Mes deux groupes comportes chacun plusieurs mots clefs :
    Il y a le groupe “Age” qui a pour mots clefs : “chaton”, “junior”, “adulte”, “senior”.
    Et le groupe “Sexe” qui a pour mots clefs : “mâle” et “femelle”

    Les visiteurs peuvent ne choisir que l’un des deux groupes s’il le souhaite (par exemple il recherche un chaton, mais n’ont pas de préférence sur le sexe), ou les deux (si par exemple ils recherchent précisement un chat adulte femelle).

    Je veux donc que sur un même page, par défaut toutes les brèves s’affichent, et que si le visiteur le désire, un tri soit effectué selon ses critères et que cela recharge la liste des brèves sur cette même page.

    Pour afficher mes brèves j’ai ce code :

    <B_breves>
    <ul>
    <BOUCLE_breves(BREVES) {id_rubrique} {!par date}}>
    <li class="adoption">
    <div class="breveleft">
    <a href="#URL_BREVE">[(#LOGO_BREVE|image_reduire{190,0}|image_recadre{140,140,center})]</a>
    </div>
    <div class="breveright">
    [<a href="#URL_BREVE"><span class="titre_chat">(#TITRE)<span></a>]
    [<span><strong>Sexe :</strong> (#LISTER_VALEURS{sexe})</span>]
    [<span><strong>Date de naissance :</strong> (#DATE_NAISSANCE|date_relative)</span>]
    [<span><strong>Lieu :</strong> (#LIEU)</span>]
    [<span>(#COURT_DESCRIPTIF)</span>]
    </div>
    <div class="nettoyeur"></div>
    </li>
    </BOUCLE_breves>
    </ul>
    </B_breves>

    Et mon formulaire ressemblerait à quelque chose comme ça (il n’est pas fonctionnel pour le moment) :

    Vous recherchez...
    <div class='ajax'>
    <form>
    <select>
    <BOUCLE_triesexe(MOTS) {type=sexe} ><option>#TITRE</option></BOUCLE_triesexe>
    </select>
    <select>
    <BOUCLE_trieage(MOTS) {type=age}><option>#TITRE</option></BOUCLE_trieage>
    </select>				
    <input type='submit' name='ok' value='ok' />
    </form>
    </div>

    J’ai essayée toute sorte de chose pour faire fonctionner le plugin critère mot, sans résultat.
    Juste pour info j’utilise SPIP 3.

    Et après vérification sur la page de démo du plugins, je peux choisir parmi mes 3 groupes de mots clefs (Age, Sexe et Date adoption - ce dernier groupe ne m’étant pas utile sur cette page -), mais ensuite, une fois un groupe sélectionné, je ne peux pas choisir de mot clef y correspondant (j’ai juste un “mot clef même groupe” affiché).

    Donc voilà ou j’en suis, si vous pouvez apporter de l’aide (et des explications) je suis preneuse, parce que là, je suis complètement bloquée et désespérée. Snif !

    Merci par avance.

    • Commençons par le formulaire. Je te conseille très fortement de lire une documentation sur comment fonctionnent les formulaires en HTML, parce que là ton formulaire, en l’état, ne peux rien faire.

      deja, virons le ajax, pour le moment. On verra cela plus tard.

      Ensuite, il faut que le formulaire poste quelque part, donc

      <form method="get" action="#SELF">

      On va repasser également tous les paramètres de la page, sauf mots qui change d’une fois sur l’autre. Pour cela on utilise le filtre |form_hidden appliqué sur un #SELF (url de la page) lui même filtré du paramètre “mots”:

      1. [(#SELF|parametre_url{mots,''}|form_hidden)]

      Il faut enfin préciser la variable où sera transmis la valeur de chaque menu déroulant, en l’occurance “mots[]” : <select name="mots[]">. Reste ensuite à indiquer la valeur passé pour chaque option du select : <option value="#ID_MOT">#TITRE</option>.

      En affinant un peu pour permettre que le formulaire propose de ne pas choisir dans un mot et utilise les précédentes valeurs comme valeurs par défaut, on obtient le formulaire suivant:

      <form method="get" action="#SELF">
      Vous recherchez...
      [(#SELF|parametre_url{mots,''}|form_hidden)]
      <B_triesexe>
      <select name="mots[]">
      	<option value=""></option>
      	<BOUCLE_triesexe(MOTS) {type=sexe} >
      		<option [(#ENV{mots}|find{#ID_MOT}|oui) selected="selected"] value="#ID_MOT">#TITRE</option>
      	</BOUCLE_triesexe>
      </select>
      </B_triesexe>
       
      <B_trieage>
      <select name="mots[]">
      	<option  value=""></option>
      	<BOUCLE_trieage(MOTS) {type=age}>
      		<option [(#ENV{mots}|find{#ID_MOT}|oui) selected="selected"]  value="#ID_MOT">#TITRE</option>
      	 </BOUCLE_trieage>
      </select>	
      </B_trieage>			
      <input type='submit' />
      </form>

      (Bon, il faudrait affiner pour avoir une structure html correcte. Voir http://www.spip.net/fr_article3791.html.

      Reste ensuite à passer le critère {mots} :

      <B_breves>
      <ul>
      <BOUCLE_breves(BREVES) {id_rubrique} {!par date}{mots}>
      <li class="adoption">
      <div class="breveleft">
      <a href="#URL_BREVE">[(#LOGO_BREVE|image_reduire{190,0}|image_recadre{140,140,center})]</a>
      </div>
      <div class="breveright">
      [<a href="#URL_BREVE"><span class="titre_chat">(#TITRE)<span></a>]
      [<span><strong>Sexe :</strong> (#LISTER_VALEURS{sexe})</span>]
      [<span><strong>Date de naissance :</strong> (#DATE_NAISSANCE|date_relative)</span>]
      [<span><strong>Lieu :</strong> (#LIEU)</span>]
      [<span>(#COURT_DESCRIPTIF)</span>]
      </div>
      <div class="nettoyeur"></div>
      </li>
      </BOUCLE_breves>
      </ul>
      </B_breves>
    • Un grand Merciiii Maïeul pour ton aide ! (En plus tu es super réactif !)

      Du coup si je comprends bien, avec ta solution on utilise pas le plugin enfin de compte ? En tout cas je ne vois pas la balise qui s’y rapporte ?

      Concernant mon formulaire, effectivement en l’état il n’était pas fonctionnel, je l’avais fais juste pour voir ce que ça donnerait sur la page web en question. Puis, de toute façon, je n’aurais pas su qu’il fallait utiliser la boucle SELF, les formulaires c’est effectivement pas ma spécialité comme tu peux constater. lol

      En gros, moi je me cassais les dents sur ça “[(#FORMULAIRE_RECHERCHE_PAR_MOTS)]” pensant que ce serait la clé de mon problème.

      Du coup encore merci pour le code, car non seulement il fonctionne mais en plus c’est bien expliqué pour que je comprenne (et puisse le réutiliser si besoin).

      J’aurais encore une question, comment afficher sur ma page par défaut toutes les brèves ?
      En gros, ce que je souhaite, c’est que si l’utilisateur n’utilise pas le formulaire (et donc ne passe pas de mot clef en URL), toutes les brefs soient par défaut afficher sur la page.
      Le formulaire ayant pour but juste de faire une sélection pour facilité les recherches de l’utilisateur, mais il reste facultatif.

    • C’est encore moi.

      J’ai trouvée la réponse à ma dernière question.

      Pour afficher par défaut toute les brèves j’ai utilisées un code alternatif avec la balise /B_nom_de_ma_boucle>, j’ai juste retirée le critère “mots” sur cette boucle qui est strictement identique à la première.
      Par contre, du coup, si je n’obtiens aucun résultat (imaginons que l’utilisateur cherche un chaton mâle et qu’il n’y en a pas, du coup le résultat affiche toutes les brèves).

      Du coup je ne pense pas que ce soit la solution idéale, car il faudrait que par défaut cela affiche toutes les brèves, mais que si le formulaire ne donne aucun résultat, cela affiche toutes les brèves, mais en affichant aussi un message du type “Aucun résultat” pour que l’utilisateur ne pense pas que le formulaire ne fonctionne pas.

      Du coup je ne sais pas comment procéder. Une idée ?

    • a ben si mon code utilise le plugin : c’est le critère {mots}. je ne suis pas responsable de la création du formulaire en question, et j’ignore comment il fonctionne.

      Pour ta question, les critères de spip peuvent avoir un ?, ce qui signifie qu’ils sont optionnels : si les paramètres nécessaires sont passés en environnement, alors le critère est utilisé, sinon non. Voir http://programmer.spip.net/Criteres-optionnels.

      Donc dans ton cas : {mots?}

    • Bonsoir,

      Alors j’ai testée le critère optionnel en remplaçant mots par mots? cela semble fonctionner, mais je n’ai pas le résultat attendu.
      En faite, je veux afficher par défaut toutes les brèves, puisque le formulaire reste optionnel (sinon les visiteurs ne vont pas comprendre pourquoi ils arrivent sur une page vide).

      Or, si j’utilise le critère mots? vu qu’aucun paramètre n’est passé en environnement quand on arrive sur la page, et bien je me retrouve effectivement avec une page vide.
      Par contre ça fonctionne bien, si jamais je lance une recherche sur le formulaire pour sélectionner par exemple des “chatons” “mâles” et qu’il y en a pas cela ne rend aucun résultat. Cependant, j’aimerais alors afficher toutes les brèves, mais en précisant que la recherche n’a pas donnée de résultat (histoire que les visiteurs ne pensent pas qu’il y a un problème avec le formulaire).

      Avec le code alternatif de la balise /B>, j’arrive à afficher par défaut l’ensemble de mes brèves, le formulaire est fonctionnel, cependant, si je lance une recherche qui ne donne aucun résultat, j’ai alors toutes mes brèves qui s’affichent (jusque là c’est ce que je veux) MAIS je n’ai pas possibilité de laisser un message pour dire que la recherche n’a aboutie sur aucun résultat (car si je mets ce message dans mon code alternatif, alors il apparaît aussi quand les visiteurs arrivent sur la page, sans même avoir utiliser le formulaire).

      Je sais pas si je suis claire dans mes explications, mais je ne vois pas tellement comment solutionner ce soucis.

    • si j’ai bien compris ton besoin, alors dans la parti optionell utilise

      [(#ENV{mots}|oui) texte à afficher si le formulaire a bien été rempli mais ne fournit pas de résultat].

    • Merci Maïeul, c’est exactement ce qu’il me fallait, ça marche niquel. Encore merci !

    Reply to this message

  • 20

    Le FORMULAIRE_RECHERCHE_PAR_MOTS permet de sélectionner les mots clés d’un groupe de mot.

    Cette sélection se fait assez lentement car il faut d’abord choisir 1 mot, le calcul se fait... les résultats s’affichent.

    Ensuite on peut choisir un autre mot, etc.

    Est il possible plutot qu’un menu déroulant d’afficher la liste des mots clés sous forme de liste à cocher afin d’effectuer une recherche multicritère en une seule fois ?

    ou à défaut permettre de sélectionner plusieurs mots clés dans le menu déroulant ?

    Pouvez vous m’aider à réaliser cela ?

    • tu connais les boucles de SPIP ou pas ? pour savoir quel degrees d’explication je dois fournir …

    • oui je connais le fonctionnement général.
      à mon sens il s’agirait de modifier la page recherche_par_mot.html ou d’en créer une autre à partir de celle ci recherche_par_mot2.html que je rangerais dans mon dossier squelette/formulaires ?

      ensuite suffit t’il de modifier le type de select ?

    • c’est ca. tu peux opter pour l’une ou l’autre des solutions, du moment que tu place tout cela dans ton dossier squelettes.

      Il suffit de modifier le squelette du formulaire et celui qui affiche les mots à la sortie du formulaire. Normalment la doc permet à une personne qui connaît les boucles de faire les modifs. Si tu bloque envoie moi ton code.

    • Bonjour, petit up pour ce post.
      Je souhaiterais moi aussi pouvoir avoir une liste à cocher plutôt qu’un/deux menu(s) déroulant et pouvoir choisir en même temps dans deux listes de mots clés. Les explications fournies ne suffisent pas à mon niveau!
      Pourrais-je avoir plus d’explications?

      Et pour ajouter une difficulté, je souhaiterais que d’abord tous les articles (de la rubrique concernée par ma recherche) apparaissent dans la page et qu’ensuite en sélectionnant les mots clés, la sélection devienne plus restrictive. Alors qu’actuellement seule la sélection de mots fait apparaitre une liste d’articles, en commençant par une page vide.

      J’espère être assez claire.
      Merci d’avance.

    • quelles connaissances SPIP avez vous?

    • Plutôt débutante!
      J’arrive à faire quelques boucles simples pour appeler des articles ou des documents dans mes squelettes mais je me base souvent sur les codes fournis pour essayer de les comprendre.

    • Bon, alors on va faire une chose simple: je vous donne un code qui marche. Ce qu’il fait:

      -  lister les mots clefs avec case à cocher
      -  afficher les articles avec ces mots clefs, sauf si aucun mot clefs n’a été choisi, dans ce cas il affiche tout.

      Vous testez ce code, et ensuite vous me faite un retour en m’indiquant lignes par lignes ce que fait le code. Comme cela je vous fournis un code déjà prêt ET en plus vous vous formez.

      Avec la doc de base de SPIP + du plugins + notions de HTML vous devrez le comprendre. Et sinon vous posez des questions.

      <B_mots>
      <div class="formulaire_spip formulaire_recherche_mot">
      <form method="post" action="#SELF">
      	[(#SELF|form_hidden)]
      	<ul>
      	<BOUCLE_mots(MOTS){par titre}{objet=article}>
      		<li>
      			<label for="mot#ID_MOT">#TITRE</label>
      			<input type="checkbox" class="checkbox" name="mots[]" id="mot#ID_MOT" value="#ID_MOT"[(#ID_MOT|in_array{#ENV{mots}}|oui) checked="checked"] />
      		</li>
      	</BOUCLE_mots>
      	</ul>
       
      <p class="boutons"><input type="submit" class="submit" value="<:bouton_enregistrer:>" /></p>
      </form>
      </div>
      </B_mots>
       
      <B_articles>
      	<ul>
      	<BOUCLE_articles(ARTICLES){mots?}{par titre}>
      		<li><a href="#URL_ARTICLE">#TITRE</a></li>
      	</BOUCLE_articles>
      	</ul>
      </B_articles>
    • Aie... déjà erreur à la 1e ligne!
      Spip m’indique:

      1 Erreur(s) dans le squelette (...)
      Critère inconnu = _mots

      Et sinon, tous les articles de mon site apparaissent.

    • heu, je vous assure que j’ai testé cela avant de vous envoyé.

      Quelle config de SPIP avez vous? où avez vous mis le code?

    • SPIP 2.1.23

      Et j’ai mis le code dans le fichier “recherche_par_mots.html” dans mon dossier squelettes. J’ai même testé de le mettre dans le dossier plugin directement. Rien à faire. J’ai l’impression que le critère “mots” n’est pas accepté! A chaque fois ça me renvoi un bug!

    • ne surtout jamais modifié le dossier squelette.

      A tout hasard, le plugin est bien activé?

      Sinon pour SPIP 2.1, il faut mettre

      <B_mots>
      <div class="formulaire_spip formulaire_recherche_mot">
      <form method="post" action="#SELF">
      	[(#SELF|form_hidden)]
      	<ul>
      	<BOUCLE_mots(MOTS spip_mots_articles){par titre}{id_article>0}>
      		<li>
      			<label for="mot#ID_MOT">#TITRE</label>
      			<input type="checkbox" class="checkbox" name="mots[]" id="mot#ID_MOT" value="#ID_MOT"[(#ID_MOT|in_array{#ENV{mots}}|oui) checked="checked"] />
      		</li>
      	</BOUCLE_mots>
      	</ul>
       
      <p class="boutons"><input type="submit" class="submit" value="<:bouton_enregistrer:>" /></p>
      </form>
      </div>
      </B_mots>
       
      <B_articles>
      	<ul>
      	<BOUCLE_articles(ARTICLES){mots}{par titre}>
      		<li><a href="#URL_ARTICLE">#TITRE</a></li>
      	</BOUCLE_articles>
      	</ul>
      </B_articles>
    • videz le cache le cas échéant ...

    • Ca y est presque!
      Juste ceci apparait au dessus de ma liste a choix multiple :

      Warning: in_array() [function.in-array]: Wrong datatype for second argument in /home/<toto>/www/ecrire/public/composer.php(69) : eval()'d code on line 45

    • quelle version de PHP (allez dans http://urldusite/ecrire/?exec=info pour savoir).

    • Excusez moi de la réponse tardive...
      PHP Version 5.2.17

      ne surtout jamais modifié le dossier squelette.

      Pas d’inquiétude, je ne modifie pas le dossier squelette dist, mais j’insère mes squelettes dans un dossier squelettes personnels :)

    • J’ai trouvé ceci dans cet article spip sur #ARRAY (dans les notes de bas de page) :

      « |find correspond à la fonction PHP in_array, à la différence que ce filtre ne produit pas le message d’erreur “Warning : in_array() [function.in-array] : Wrong datatype for second argument.” si la variable n’est finalement pas un tableau. En effet, lorsqu’une variable est générée dynamiquement, on ne sait pas toujours si elle existera et s’il s’agira bien d’un tableau. »

      Ca parle de mon problème, mais par contre, ça dépasse mes compétences là!

    • a mais oui,

      c’est le code

      1. [(#ID_MOT|in_array{#ENV{mots}}|oui) checked="checked"]

      qui est mauvais. Le but c’est de tester si le mot courant se trouve dans la liste des mots du précédent formulaire. Si oui, on coche la case.

      Mais sauf que ca va pas.

      Et donc la doc sur #ARRAY que vous avez trouvé donne la solution. Désolé un peu fatigué (et chez moi les messages d’erreurs sont désactivés.

      La solution est de remplacer par :

      1. [(#ENV{mots}|find{#ID_MOT}|oui) checked="checked"]
    • Super! Plus de message d’erreur!

      Une fois le mot clé sélectionné, la liste apparait bien.
      Par contre, vous disiez plus haut que ce code doit faire apparaitre tous les articles si aucun mot clé n’est sélectionné, ce n’est pas le cas.

    • oui, parce que dans mes testes suite au fait que le plugin n’était pas activé, j’ai oublié le ? dans {mots?}.

      Ca devrait aller mieux comme cela.

      Et maintenant, la réponse de l’exercice ;-)

    • C’est super!!

      J’ai ajouté {id_rubrique} pour permettre de faire la recherche uniquement dans la rubrique que je souhaite et le tour est joué.

      Un grand merci! :D

    Reply to this message

  • 5

    Pour ceux qui ont des problemes de performance avec ce plugin j’ai mis au point un systeme de boucles recursives qui fait le travail, mais au lieu d’une requete complexe ca decompose le probleme en requetes simples, ce qui evite les lenteurs pour certains, voire les crashs SQL pour ceux qui comme moi travaillent sur une base de donnees de grande taille. Ce systeme ne permet pas de specifier des pourcentages ou autres options de tri, ca affiche simplement les articles associes a TOUS les mots cles de la liste. Le principe est assez simple, j’ai decompose le code par etapes en mettant des commentaires pour que vous saisissiez facilement le principe. Nous avons un tableau #KW qui contient la liste des id_mots, un compteur “n” qui nous permet de progresser dans ce tableau, un tableau “tab2” qui sert aux traitements, et un tableau “tab” qui contiendra la liste finale des articles. Vous noterez que le tableau #KW peut directement provenir d’un tableau specifie dans l’URL de la sorte: ?kw[]=id_mot1&kw[]=id_mot2&kw=...

    • tu pourrais proposer un article ? là les infos sont coupées ...

    • le code:

      #SET{n,0}
      [(#SET{next_kw,[(#KW|table_valeur{#GET{n}})]})]
      #SET{tab,#ARRAY{0,0}}
      <BOUCLE_test_rec(MOTS){id_mot=#GET{next_kw}}{0,1}>        
                                      
          [(#REM) 
          --- on remplit tab2 avec tous les articles du mot en cours 
          ---]
          #SET{tab2,#ARRAY}        
          <BOUCLE_articles(ARTICLES){id_mot}>
              [(#SET{tab2,[(#GET{tab2}|array_merge{#ARRAY{0,#ID_ARTICLE}})]})]
          </BOUCLE_articles>
                                      
          [(#REM) 
          --- si c'est la premiere passe, on copie tab2 vers tab 
          --- sinon on place dans tab l intersection entre les deux tableaux 
          ---]
          [(#GET{n}|=={0}|?{
              #SET{tab,#GET{tab2}},
              [(#SET{tab,[(#GET{tab}|array_intersect{#GET{tab2}})]})]
          })]
                                      
          [(#REM) 
          --- on incremente le compteur et recupere le prochain mot cle 
          ---]
          #SET{n,#GET{n}|plus{1}}
          [(#SET{next_kw,[(#KW|table_valeur{#GET{n}})]})]
                                      
          [(#REM) 
          --- on apelle a nouveau la boucle en passant en parametre le nouveau id_mot
          --- c est ici que se fait la recursivite de la fonction
          ---]
          <BOUCLE_test_rec1(BOUCLE_test_rec){id_mot=#GET{next_kw}}{0,1}>
          </BOUCLE_test_rec1>
      </BOUCLE_test_rec>

      Ensuite il suffit d’utiliser le tableau “tab” dans une boucle article basique, cette fois ci avec un tri si on le souhaite car ca ne prend plus autant de ressources:

      <BOUCLE_page(ARTICLES){par date}{inverse}{id_article IN #GET{tab}}....
    • Mon code est vieux, et a l’epoque je n’avais pas connaissance de la boucle DATA sur les tableaux. On peut transformer cette solution en faisant une boucle sur le tableau de mots directement au lieu d’une boucle recursive. L’important c’est la decomposition de la requete faite par le plugin en requetes simples: les jointures se font principalement en PHP lors de l’intersection des tableaux, et les criteres de tri ne s’appliquent qu’a la fin, une fois la liste des articles bien etablie (plus de jointures dans la requete des lors).

    • Salut,

      Je lis ton message un peu tardivement...

      Tu trouveras une ancienne technique similaire (ancienne aussi) ici: article 1538 et qui est détaillée pour un usage similaire au critère mots ici: http://thread.gmane.org/gmane.comp.....

      Pour moi, ça s’est avéré environ 10x plus rapide à l’exécution que critère mots... Toutefois c’est moins souple (ou plus difficile à manipuler).

      Voici le code:

      [
      (#REM)
      	Une première boucle qui prépare
      	une pile avec doublons nommée liste_0
      	(Ici on peut rajouter des critères si on veut
      	choisir des articles en particulier à filtrer avec des mots)
       
      	Ça peut marcher aussi pour d'autres boucles que ARTICLES...
      ]
      <BOUCLE_Une_pile(ARTICLES){doublons liste_0} ></BOUCLE_Une_pile>
      [
      (#REM)
      	Ensuite pour chaque mot de mon tableau...
      	"ma_liste_de_mots" contient une liste de mots
      	qui servent de filtres
      ]
      <BOUCLE_Les_mots(MOTS){id_mot IN #GET{ma_liste_de_mots}}>
      [(#SET{moinsun,[(#_Les_mots:COMPTEUR_BOUCLE|moins{1})]})]
      	[
      	(#REM)
      		on choisi parmi les articles de la pile précédente
      		(liste_x où x est compteur_boucle-1) 
      		les articles qui sont rattachés au mot. Et on
      		les empile avec un doublons dans la pile suivante
      		(liste_y où y=compteur de boucle)
      	]
      	<BOUCLE_les_articles_du_mot(ARTICLES){id_mot}
      				{!doublons liste_#GET{moinsun}}
      				{doublons liste_#_Les_mots:COMPTEUR_BOUCLE} ></BOUCLE_les_articles_du_mot>
      </BOUCLE_Les_mots>
      [
      (#REM)
      	Au final, on a une pile
      	(nommée liste_z où z=nombre de tour de boucle "Les_mots")
      	qui contient bien seulement les articles qui ont
      	tous les mots du tableau
       
      	C'est ce que liste la boucle d'après.
      	(ça peut être l'occasion de les trier d'une
      	façon ou d'une autre...)
      ]
      <BOUCLE_Articles_empile(ARTICLES){!doublons
      liste_#_Les_mots:COMPTEUR_BOUCLE}>
      	#TITRE<br>
      </BOUCLE_Articles_empile>
    • Oups petite erreur de lien dans mon commentaire précédent: Afficher les articles connexes, triés par pertinence...

    Reply to this message

  • 3

    Bonjour,

    Je rencontre un problème très étrange de pagination erratique sur boucle imbriquée avec critère_mots.

    Je suis sur une page mot.html
    revue pour lister tous les articles d’une certaine rubrique, classés par familles.

    Mes familles sont dans un autre groupe de mot-clé

    Une première boucle récupère le nom d’une famille,
    Une seconde boucle imbriquée, récupère les article tagué à la fois par l’id_mot sur lequel on se trouve ET l’id_mot de la famille remontée par le premier niveau.

    Tout fonctionne sauf la pagination. Si j’essaie d’utiliser la pagin sur un des blocs de résultats, en fait elle affecte TOUS les blocs de résultats.

    Le code :

    <BOUCLE_mot_principal(MOTS){id_mot}>
    <h1>#TITRE</h1>
      <BOUCLE_familles(MOTS){id_groupe = 19}{par num titre}>
        
        <BOUCLE_affiche_famille(ARTICLES){id_rubrique=2}{mots 100% #ARRAY{0,#_mot_principal:ID_MOT,1,#_familles:ID_MOT}}{0,1}>
        <h3 class="header">#_familles:TITRE</h3>
        </BOUCLE_affiche_famille>
        
        [(#REM) Listes des formations mot + famille <!-- INCLURE{fond=liste/formations-resume,env}/ --> ]
        [(#REM) Articles de la rubrique Formations lies au mot-cle ]
        <B_list_formations>
          #ANCRE_PAGINATION
                <BOUCLE_list_formations(ARTICLES){id_rubrique=2}{mots 100% #ARRAY{0,#_mot_principal:ID_MOT,1,#_familles:ID_MOT}}{par num titre}{pagination 4}>
    
                      [<div class="h3"><a rel="bookmark" href="[(#URL_ARTICLE|url_absolue)]">(#TITRE)</a></div>]
    
                  </BOUCLE_list_formations>
    
            <p class="pagination">#PAGINATION{page_precedent_suivant}</p>
    
          </B_list_formations>
          	<p>Pas de formation disponible</p>
          <//B_list_formations>
          <div class="clear"></div> 
        
      </BOUCLE_familles>  	
      
    
      </BOUCLE_mot_principal>

    Si quelqu’un a une idée de où ca merdoie...

    Merci d’avance ;)

    Reply to this message

  • 10

    Bonjour,

    Est-il possible de limiter le résultat de la recherche à une rubrique ? La solution donnée sur le post du 27 mai 2011 à 15:59 ne semble pas fonctionner.

    • le critère s’appliquant à une boucle, il suffit de mettre le critère classique {id_rubrique=XXX} sur cette boucle.

    • Voici le formulaire :

      <form action="spip.php?page=recherche3" method="post" name="mot" >
       
      <select name="mots[0]">
      <BOUCLE_gr1(GROUPES_MOTS){id_groupe=4}>
      [<option>#TITRE</option>]
      <BOUCLE_mots4(MOTS){id_groupe}>
      <option value="#ID_MOT">#TITRE</option>
      </BOUCLE_mots4>
      </BOUCLE_gr1>
      </select>
       
      <select name="mots[1]">
      <BOUCLE_gr2(GROUPES_MOTS){id_groupe=5}>
      [<option>#TITRE</option>]
      <BOUCLE_mots5(MOTS) {id_groupe}>
      <option value="#ID_MOT">#TITRE</option>
      </BOUCLE_mots5>
      </BOUCLE_gr2>
      </select>
       
      <select name="mots[2]">
      <BOUCLE_gr3(GROUPES_MOTS){id_groupe=6}>
      [<option>#TITRE</option>]
      <BOUCLE_mots6(MOTS) {id_groupe}>
      <option value="#ID_MOT">#TITRE</option>
      </BOUCLE_mots6>
      </BOUCLE_gr3>
      </select>
       
      <input type="submit" value="chercher" name="ok">
      </form>

      Et voici la page de résultats :

      <BOUCLE_mot(MOTS){id_mot in #ENV{mots}}>#TITRE </BOUCLE_mot>
       
      <B_recherche_par>
      <div classe="liste">
      	<h3><:resultats_recherche:></h3>
       
      	<ul class="liste-items">
      	<BOUCLE_recherche_par(ARTICLES){mots}{pagination 5}>
      		<li class="item">
      			<a href="#URL_ARTICLE">#TITRE</a>
      		</li>
      	</BOUCLE_recherche_par>
      	</ul>
      <p id="pagination" class="clearfix pagination nettoyeur">
      	#PAGINATION
      </p><!-- #pagination -->
      </div>
       
      </B_recherche_par>
       

      J’ai deux problèmes :

      1. Le formulaire passe les mots via #ENV à la page de résultats (et les mots sont affichés sur cette page) mais les articles ne s’affichent pas, sauf si j’écris dans l’URL "&mot[]=10&mot[1]=3...

      2. Si j’ajoute {id_rubrique=XXX} à ma boucle “recherche_par”, il n’ a plus de résultat.

      Merci de toute lumière !

    • 1. Sans être expert en la question, je pense que tu devrait remplacer method="post" par method="get". Cela passera correctement les variables à l’URL.
      2. {id_rubrique=XXX} tu as bien remplacé XXX par la rubrique où tu veux limiter?

    • Merci du retour rapide.

      La méthode get me renvoie à la page d’accueil car l’url créée donne ceci :

      spip.php?mots%5B0%5D=12&mots%5B1%5D=17&mots%5B2%5D=2&ok=chercher

      Sinon oui, j’ai bien mis le numéro de rubrique.
      Petite précision, le site fonctionne avec zpip, cela peut éventuellement expliquer ces problèmes ?

    • Pour la rubrique, cela fonctionne, erreur d’étourderie ma part, il fallait mettre id_secteur=XXX, car les articles étaient dans des sous rubrique de la rubrique en question. Mais pour le passage des variables à l’URL, je ne vois pas comment faire...

    • il faut que tu mette l’url de page en hidden

      <input type="hidden" name="page" value="recherche3" />

      le fait d’être en zpip ne change rien à la question.

      (bon dans l’idéal faudrait faire un vrai form propre sous la forme de CVT)

    • Merci, cela appelle en effet la bonne page mais les crochets restent transformés dans l’URL ( &mots%5B2%5D=1), du coup la page résultats ne donne toujours rien.

    • les crochets ne sont pas responsables du problème. Ils sont normaux.

      Le pb doit venir d’ailleurs. Exemple là sur une page toto.html

      <form method="get">
      <input type="hidden" name="page" value="toto" />
      <B_mots>
      <select name="mots[1]">
      <BOUCLE_mots(MOTS){par titre}>
      	<option value="#ID_MOT">#TITRE</option>
      </BOUCLE_mots>
      </select>
      </B_mots>
       
      <BOUCLE_articles(ARTICLES){mots}{par titre}>
      #TITRE
      </BOUCLE_articles>	
      <input type="submit" value="chercher" name="ok">
      </form>

      Fonctionne parfaitement.

    • J’ai essayé avec cet exemple. Les crochets ne passent pas plus. Il sont systématiquement encodé en %5B et %5D dans l’Url. Test fait en local et sur serveur. Si quelqu’un a une piste....

    • je confirme avoir essayé cet exemple chez moi avant de te l’envoyer. Et même si les crochets sont encodés dans l’URL cela n’empêche pas le bon fonctionnement du critère.

      Du reste tu n’a qu’à vérifer en faisant [(#ENV{mots}|var_dump)] > tu verra que tu a bien affaire à un tableau.

      Ton pb doit venir d’ailleur, mais de quoi?

    Reply to this message

  • ce plugin de fou...

    J’ai passé des centaines d’heures pour réaliser divers moteurs multicritères ces dernières années. Et ce soir je tombe sur ce plugin, tout fait, tout simple, tout bête et en 5mn j’ai un moteur qui fonctionne...

    Pourquoi j’avais jamais cherché avant ??? Pourquoi ???

    Merci !!!!

    Reply to this message

  • 6

    Hello ! :)

    Bon... plus j’utilise ce plugin et plus je le trouve génial.

    Mais là j’ai un cas de conscience. Sur une page rubrique, je liste un *très* grand nombre d’articles paginés par 15 que je souhaite pouvoir trier par mot clés, lesquels appartiennent à 2 groupes. Le premier exemple me parait approprié :

    http://www.toto.fr/?page=toto&amp;amp;mots[0]=XX&amp;amp;mots[1]=YY.

    Mais je cherche à savoir si l’on peut obtenir la même transmission de variable au contexte avec des paramètres ajax (donc passés avec des !# plutôt que des ? et des &) ?

    soit une écriture du style

    http://www.toto.fr/ma-rubrique#!mots[0]=XX&amp;amp;mots[1]=YY.

    Dans le but d’éviter des duplications de contenus malheureuse, ce qui arrive quasi systématiquement dès que l’on joue avec les paramètres d’url

    Une idée ?

    Merci d’avance ;)

    • heu, je vois pas en quoi ajax change quoique ce soit à ce pb. L’ajax made in spip passe automatiquement les params get...

    • L’ajax made in spip passe automatiquement les params get...

      C’est à dire ?

      je vois pas en quoi ajax change quoique ce soit à ce pb

      En fait, si, ca change quand même pas mal de chose à mon niveau :)

      En substance, quand Google croise page.html, page.html?plop=pwet et page.html?truc=machin&bidule=schmurtz, pour lui ca fait 3 pages distinctes à indexer même si chaque paramètre ne change réellement que 2 mots dans la page (donc contenu dupliqué à plus de 99% pour autant de page qu’il y a de valeur à chaque paramètre = pas bon pour ton ref !

      Alors que page.html, page.html#!plop=pwet etc... ne seront bien reconnue que comme une seule et même page (les fragments indépendants s’affichant en mode noJS pouvant alors être facilement non indexés

      Je ne sais pas si je suis clair là ? :D )

    • oui tu es clair, mais alors c’est un pb plus général à l’ajaxation, pas spécifique ici. A mon avis tu devrais en discuter sur user.

    • Bah en fait non c’est vraiment pas un problème lié à l’ajax. Moi le fonctionement ajax me convient bien mieux que des params d’url classiques.

      Là justement, je cherche à savoir si on peut ajaxer un peu le fonctionnement de ce plugin en fait ?

    • je comprend rien à tes propos...

      c’est pas compliqué l’ajax avec spip : <INCLURE{toto}{ajax}{env}>. Il suffit juste que ton form de select des mots clef soit dans toto et ca roule ...

    • OK je vais creuser par là alors. Je sais pas pourquoi je m’étais immaginé un truc plus compliqué. Je vais voir ça, merci :)

    Reply to this message

  • Je viens de tester le cas où on applique plusieurs fois le critère {mots} sur la même boucle

    <BOUCLE_a(ARTICLES)
        {mots 1 #LISTE{1,2}}
        {mots 1 #LISTE{3,4}}
        {mots 1 #LISTE{5,6}}>
            <li>#ID_ARTICLE</li>
    </BOUCLE_a>

    Dans ce cas, seul le dernier critère ({mots 1 #LISTE{5,6}}) est pris en compte et les précédents ({mots 1 #LISTE{1,2}}{mots 1 #LISTE{3,4}}) sont ignorés.

    Peut-être pourrait-on ajouter un paragraphe pour le préciser.

    Reply to this message

  • Bonjour

    Je me sers de ce plugin efficace d’ailleurs, pour créer un moteur de recherche multicritères sur plusieurs groupes de mots clés. Je souhaiterai modifier le formulaire de sélection pour faire afficher directement les 4 groupes de mots clé que j’utilise :
    -  Groupe 1 -> menu déroulant avec les mots clés du groupe
    -  Groupe 2 -> menu déroulant avec les mots clés du groupe
    -  Groupe 3 -> menu déroulant avec les mots clés du groupe
    -  Groupe 4 -> menu déroulant avec les mots clés du groupe
    Actuellement il propose d’abord -> Dans le groupe : liste déroulante avec Groupe 1, Groupe 2, Groupe 3, etc. puis un autre choix, etc.

    J’ai regardé la page recherche_par_mot.html, mais je n’y arrive pas vraiment...
    Quelqu’un pourrait il m’aider ?

    Reply to this message

  • À noter : le critère {mots} ne s’applique pas à... la boucle MOTS ! Dans ce cas, il suffit de faire :

    <BOUCLE_mots(MOTS){id_mot IN #MOTS}>
            #TITRE
    </BOUCLE_mots>

    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