Je me demande si c'est moi ou autre chose mais la boucle suivante ne me renvoie rien, alors que quand je la débugue avec ?var_mode=debug, elle sort un code MySQL valide et qui renvoie bien un résultat dans PHPMyAdmin :
- Boucle :
<BOUCLE_article(ARTICLES spip_mots_articles spip_mots) {titre_mot=(#DATE|saison)} {id_rubrique}{par hasard}{0,1}> #TITRE
</BOUCLE_article>
- Code MySQL :
SELECT rand() AS alea, articles.id_article, articles.titre, articles.texte, articles.descriptif, articles.chapo, articles.lang
FROM spip_articles AS `articles`
INNER JOIN spip_mots_articles AS L1 ON ( L1.id_article = articles.id_article )
INNER JOIN spip_mots AS L2 ON ( L2.id_mot = L1.id_mot )
WHERE (articles.statut = 'publie')
AND (articles.date < '2138-01-01 00:00:00')
AND (L2.titre = 'été')
AND (articles.id_rubrique = 5)
GROUP BY articles.id_article
ORDER BY alea
LIMIT 0,1
Sur un Spip 2.1.10 [17657]
J'en ai parlé sur la liste spip et j'ai cherché sur le web, mais rien trouvé...
Je me demande si c'est moi ou autre chose mais la boucle suivante ne
me renvoie rien, alors que quand je la débugue avec ?var_mode=debug,
elle sort un code MySQL valide et qui renvoie bien un résultat dans
PHPMyAdmin :
- Boucle :
<BOUCLE_article(ARTICLES spip_mots_articles spip_mots)
{titre_mot=(#DATE|saison)} {id_rubrique}{par hasard}{0,1}> #TITRE
</BOUCLE_article>
- Code MySQL :
SELECT rand() AS alea, articles.id_article, articles.titre,
articles.texte, articles.descriptif, articles.chapo, articles.lang
FROM spip_articles AS `articles`
INNER JOIN spip_mots_articles AS L1 ON ( L1.id_article =
articles.id_article )
INNER JOIN spip_mots AS L2 ON ( L2.id_mot = L1.id_mot )
WHERE (articles.statut = 'publie')
AND (articles.date < '2138-01-01 00:00:00')
AND (L2.titre = 'été')
AND (articles.id_rubrique = 5)
GROUP BY articles.id_article
ORDER BY alea
LIMIT 0,1
Sur un Spip 2.1.10 [17657]
J'en ai parlé sur la liste spip et j'ai cherché sur le web, mais rien
trouvé...
Si quelqu'un a une idée, je suis preneur
Sylvain
Salut,
Je ne sais pas si çà peut aider mais la boucle ARTICLES accepte le critère
titre_mot sans nécessité de jointure
Visiblement, la requête SQL ne correspond pas au but recherché, puisque le SQL
produit contient un test qui sera toujours vrai avant le 1er janvier 2138 sur
le champ date de la table articles en lieu et place du test désiré sur le
titre du mot clé.
Le problème vient probablement du critère {titre_mot=(#DATE|saison)}
Il faudrait pouvoir mettre {titre_mot=[(#DATE|saison)]} ou, si ça ne passe
pas, faire ça en deux temps :
1) stocker le critère avec la balise #SET : #SET{critere,[(#DATE|saison)]}
2) le récupérer comme critère dans la boucle : {titre_mot=#GET{critere}}
D'autre part, et comme le dit une autre réponse, les jointures sont superflues
et ralentissent cette boucle inutilement.
Je me demande si c'est moi ou autre chose mais la boucle suivante ne
me renvoie rien, alors que quand je la débugue avec ?var_mode=debug,
elle sort un code MySQL valide et qui renvoie bien un résultat dans
PHPMyAdmin :
- Boucle :
<BOUCLE_article(ARTICLES spip_mots_articles spip_mots)
{titre_mot=(#DATE|saison)} {id_rubrique}{par hasard}{0,1}> #TITRE
</BOUCLE_article>
- Code MySQL :
SELECT rand() AS alea, articles.id_article, articles.titre,
articles.texte, articles.descriptif, articles.chapo, articles.lang
FROM spip_articles AS `articles`
INNER JOIN spip_mots_articles AS L1 ON ( L1.id_article =
articles.id_article )
INNER JOIN spip_mots AS L2 ON ( L2.id_mot = L1.id_mot )
WHERE (articles.statut = 'publie')
AND (articles.date < '2138-01-01 00:00:00')
AND (L2.titre = 'été')
AND (articles.id_rubrique = 5)
GROUP BY articles.id_article
ORDER BY alea
LIMIT 0,1
Sur un Spip 2.1.10 [17657]
Visiblement, la requête SQL ne correspond pas au but recherché, puisque le SQL
produit contient un test qui sera toujours vrai avant le 1er janvier 2138 sur
le champ date de la table articles en lieu et place du test désiré sur le
titre du mot clé.
Ce test est rajouté par Spip automatiquement...
Le test que je demande sur le titre du mot clé est bien présent aussi.
La requête produit bien le résultat recherché : je l'ai exécuté dans
PHPMyAdmin et ça me sort le bon résultat.
Le problème vient probablement du critère {titre_mot=(#DATE|saison)}
Il faudrait pouvoir mettre {titre_mot=[(#DATE|saison)]} ou, si ça ne passe
pas, faire ça en deux temps :
1) stocker le critère avec la balise #SET : #SET{critere,[(#DATE|saison)]}
2) le récupérer comme critère dans la boucle : {titre_mot=#GET{critere}}
Essayé et ça ne change rien : la requête SQL est bonne mais la boucle ne
donne rien.
D'autre part, et comme le dit une autre réponse, les jointures sont superflues
et ralentissent cette boucle inutilement.
En effet ce n'est pas nécessaire de mettre explicitement les jointures
dans la boucle : elles sont rajoutées automatiquement par Spip avec le
paramètre titre_mot.
Mais elles se retrouvent automatiquement dans le SQL, sinon MySQL ne
pourrait pas faire la jointure, donc je ne pense pas que ça ralentisse
la requête MySQL. Le parsing de la boucle par le moteur Spip, peut-être ?
ne serait-il pas possible que l'encodage de la base de données
ne corresponde pas à ce qui est demandé par la boucle dans son
critère {titre_mot=(#DATE|saison)} ?
en particulier pour 'été' et ses accents
il faudrait alors regarder l'adéquation entre le charset du squelette
et l'interclassement de la table spip_mots
ne serait-il pas possible que l'encodage de la base de données
ne corresponde pas à ce qui est demandé par la boucle dans son
critère {titre_mot=(#DATE|saison)} ?
en particulier pour 'été' et ses accents
il faudrait alors regarder l'adéquation entre le charset du squelette
et l'interclassement de la table spip_mots
Etant donné que la requête MySQL donne le bon résultat dans PHPMyAdmin,
je n'avais pas pensé à regarder par là, mais je vais regarder.
Je ne sais pas si c’est un bug ou un comportement normal, mais cela m’a bien titillé pendant 5min.
Je voulais faire une boucle récupérant la liste des rubriques n’ayant pas le mots-clefs n°12 (par exemple). Je fais donc :
<BOUCLE_rubriques(RUBRIQUES){id_mot != 12}>
Ce qui génère comme requête SQL :
SELECT rubriques.titre, rubriques.lang FROM spip_rubriques AS rubriques INNER JOIN spip_mots_rubriques AS L1 ON ( L1.id_rubrique = rubriques.id_rubrique ) WHERE (rubriques.statut = ‘publie’) AND NOT((L1.id_mot = 12))
Mais là, point de résultats ! Probablement à cause de la jointure (je recherche après tout des rubriques dont l’id_rubrique n’est PAS dans spip_mots_rubriques).
En fait la syntaxe correctes pour faire cela semble être :
<BOUCLE_rubriques(RUBRIQUES){!id_mot== 12}>
Ce qui génère comme requête SQL plus “bourrine” :
SELECT rubriques.titre, rubriques.lang FROM spip_rubriques AS rubriques WHERE (rubriques.statut = ‘publie’) AND NOT((rubriques.id_rubrique IN ( SELECT L1.id_rubrique FROM spip_mots_rubriques AS L1 WHERE (L1.id_mot REGEXP 12)))) GROUP BY rubriques.id_rubrique
Je ne sais pas si c’est un bug ou un comportement normal, mais cela m’a bien titillé pendant 5min.
Je voulais faire une boucle récupérant la liste des rubriques n’ayant pas le mots-clefs n°12 (par exemple). Je fais donc :
<BOUCLE_rubriques(RUBRIQUES){id_mot != 12}>
Depuis toujours, cette boucle sélectionne les rubriques ayant un mot clé différent de id_mot=12 puisqu’elle fait une jointure sur la boucles mots et cherche un mot clé !=12
C’est différent de ce que tu veux.
Traditionnellement source de confusion pour ceux qui cherchent a exclure les objets liés à un mot clé,
la syntaxe alternative {!id_mot=12} à été introduite en version SPI P 2.0 (de mémoire).
Elle se lit « qui n’ont pas id_mot=12 » et correspond effectivement à ce que tu cherches
…
<BOUCLE_rubriques(RUBRIQUES){!id_mot== 12}>
Ici tu utilises == ce qui est un test de REGEXP et non d’égalité, donc tu va aussi exclure les rubriques associées au mot clé 120 ou 512 par exemple.
A ceci près c’est bien la syntaxe qu’il faut utiliser pour ce que tu veux faire.
La différence de comportement entre {id_xx!=y} et {!id_xx=y} s’entend uniquement en cas de jointure n-n car dans le cas d’une jointure 1-1 ou de non jointure,
le comportement est équivalent.
C’est une subtilité des jointures, donc, et SPIP propose deux syntaxes qui permettent de faire les deux choses.
Merci de cette précision, je ne connaissais pas cette distinction. Pour le ==, c’est ma faute, trop de jonglage entre les CVT en PHP et les templates SPIP.