Doublons dans inclure... existe-t-il des solutions ?

Bonjour,

Je voulais savoir si quelqu'un a une astuce pour transmettre un doublons à un inclure, ou quelque chose d'équivalent... (version 1.9.3 dev svn)

Grosso modo, si j'ai dans la même page :
(#INCLURE ou <INCLURE>, n'importe !)

#INCLURE{fond=derniers_articles}{nombre=2}
#INCLURE{fond=les_autres_articles}

Comment faire pour que les premiers ne se réaffichent pas ?
Y a-t-il seulement un moyen ?

J'ai tenté de passer un doublons, un {env} aussi, mais ça ne fait rien...
J'ai aussi essayé de passer un argument pour faire dans la boucle dans l'inclure l'équivalent de <BOUCLE_xxx(ARTICLES){2, 10}>, avec {#ENV{debut_article} #ENV{nombre}}, mais, si #ENV{nombre} fonctionne, #ENV{debut_article} lui est pris pour un critère (# Erreur(s) dans le squelette * criteres, ENV)

Du coup, je ne sais si c'est possible.
Merci de vos éclaircissements !

Marcimat.

Matthieu Marcillaud a écrit :

Je voulais savoir si quelqu'un a une astuce pour transmettre un doublons à un inclure, ou quelque chose d'équivalent... (version 1.9.3 dev svn)

Bon, c'est renato qui m'a bien aidé en me fournissant ces 2 balises et quelques instructions :

function balise_SET_DOUBLONS($p) {
   $p->code = "vide(\$GLOBALS['recherche_doublons'] = \$doublons)";

   return $p;
}

function balise_MERGE_DOUBLONS($p) {
   $p->code = "vide(\$doublons=array_merge(\$doublons,\$GLOBALS['recherche_doublons']))";

   return $p;
}

Cependant... bien, ça ne fonctionnait pas, ou je n'ai pas trouvé comment; j'ai du adapter un peu...
Donc, éclaircissement de ce que je voulais (grosso grosso modo) :
- quand j'inclus B.html, il affiche les 3 derniers articles
- et idem quand j'inclus C.html... (mais les 3 suivants...)

dans A.html
[(#INCLURE{fond=B}{mm_doublons = toto})]
[(#INCLURE{fond=C}{mm_doublons = toto})]

dans B.html
<BOUCLE_B(ARTICLES){par date}{inverse}{0,3}{doublons [(#ENV{mm_doublons})]>
- #TITRE<br />
</BOUCLE_B>

dans C.html
<BOUCLE_B(ARTICLES){par date}{inverse}{0,3}{doublons [(#ENV{mm_doublons})]>
- #TITRE<br />
</BOUCLE_B>

Pour y arriver, j'ai placé dans mes_fonctions.php les nouvelles balises suivantes :

/* balises pour doublons entre inclure (_renato_) */
function balise_SET_DOUBLONS($p) {
   $p->code = "vide(\$GLOBALS['recherche_doublons'] = \$doublons)";

   return $p;
}

function balise_GET_DOUBLONS($p) {
if(!isset($GLOBALS['recherche_doublons'])){$GLOBALS['recherche_doublons'] = array();}

   $p->code = "vide(\$doublons = \$GLOBALS['recherche_doublons'])";

   return $p;
}

function balise_MERGE_DOUBLONS($p) {
if(!isset($GLOBALS['recherche_doublons'])){$GLOBALS['recherche_doublons'] = array();}

   $p->code .= "vide(\$GLOBALS['recherche_doublons']=\$doublons=array_merge(\$doublons,\$GLOBALS['recherche_doublons']))";

   return $p;
}

J'ai ajouté des choses par rapport au code de renato :
- pas besoin de charger #SET_DOUBLONS obligatoirement, #GET_DOUBLONS ou #MERGE_DOUBLONS peuvent être appelés sans générer d'erreur sur array_merge (second argument is not an array).

- #MERGE_DOUBLONS sauvegarde aussi le résultat dans la globale.

Fonctionnement :
dans B.html
#GET_DOUBLONS
<BOUCLE_B(ARTICLES){par date}{inverse}{0,3}{doublons [(#ENV{mm_doublons})]}>
- #TITRE<br />
</BOUCLE_B>
#MERGE_DOUBLONS

dans C.html
#GET_DOUBLONS
<BOUCLE_B(ARTICLES){par date}{inverse}{0,3}{doublons [(#ENV{mm_doublons})]}>
- #TITRE<br />
</BOUCLE_B>
#MERGE_DOUBLONS

Rien d'autre à faire pour que cela fonctionne.

#SET_DOUBLONS : enregistre dans une variable globale le tableau de doublons actuel (sur le squelette en cours, ou plutôt, sur la noisette en cours, bref, dans le fichier dans lequel il est placé)

#GET_DOUBLONS : fait exactement l'inverse : il replace la globale dans la variable $doublons de SPIP, toujours simplement dans le fichier dans lequel il est placé.

#MERGE_DOUBLONS : fusionne les deux tableaux ($doublons et la variable globale) et les sauvegarde le résultat dans les 2 tableaux... En gros :
$doublons = $GLOBALS['recherche_doublons'] = $doublons + $GLOBALS['recherche_doublons']

Quelques exemples de possibilités dans
A.html
[(#INCLURE{fond=B}{mm_doublons = toto})] // inclus 3 premiers articles
[(#INCLURE{fond=B}{mm_doublons = toto})] // inclus les 3 suivants

[(#INCLURE{fond=B}{mm_doublons = xxxx})] // réinclus les 3 premiers articles...
[(#INCLURE{fond=C}{mm_doublons = xxxx})] // devinez ?!

Autre remarque : il se peut que vous ne souhaitiez pas passer de doublons au fichier inclus... mais dans ce cas, il va stocker tout de même un doublons, dans nom : {doublons}, ce qui pourrait poser des problèmes avec d'autres inclusions comme cela...

Un détour possible avec microtime pour désigner un nom aléatoire :

B.html
[(#SET{doublons, [(#ENV{mm_doublons}|sinon{[(#REM|microtime|replace{' ',''}|replace{'0\.',''})]})]})]
#GET_DOUBLONS
<BOUCLE_B(ARTICLES){par date}{inverse}{0,3}{doublons [(#GET{doublons})]}>
- #TITRE<br />
</BOUCLE_B>
#MERGE_DOUBLONS

Voilà pour ce soir...
Il faut que je teste un peu mieux la chose encore, mais ça semble bien fonctionner.

Bien sûr, ça marche aussi simplement comme cela :

dans A.html
#INCLURE{fond=B}
#INCLURE{fond=C}

dans B.html
#GET_DOUBLONS
<BOUCLE_B(ARTICLES){par date}{inverse}{0,3}{doublons toto}>
- #TITRE<br />
</BOUCLE_B>
#MERGE_DOUBLONS

dans C.html
#GET_DOUBLONS
<BOUCLE_B(ARTICLES){par date}{inverse}{0,3}{doublons toto}>
- #TITRE<br />
</BOUCLE_B>
#MERGE_DOUBLONS

MM.

Matthieu Marcillaud a écrit :

Quelques exemples de possibilités dans

Qui ne marchent pas !!!

A.html
[(#INCLURE{fond=B}{mm_doublons = toto})] // inclus 3 premiers articles
[(#INCLURE{fond=B}{mm_doublons = toto})] // inclus les 3 suivants

On me souffle à l'oreille, à juste titre, que ça ne fonctionne pas dans certains cas, et non des moindres...

Dans ce cas présent, par exemple, c'est 3 fois le même résultat qui est affiché, car le cache se fait en fonction est paramètres passés à l'inclure. Comme les paramètres sont les mêmes, spip réutilisé le cache du premier appel.

On me souffle encore qu'il faudrait passer le tableau des doublons dans le inclure {tableau_doublon=#qqc}, mais je n'ai pas réussi à faire un balise qui renvoie les bonnes données...

L'ideal, selon fil, c'est de créer (difficilement) un critère {doublons} à passer aux inclures...

----
Par ailleurs, il y avait des cas ou les tests isset() n'allaient pas... Donc retour à la balise #SET_DOUBLONS dans le fichier A.html par exemple (avant get ou merge)

/* balises pour doublons entre inclure (renato) */
function balise_SET_DOUBLONS($p) {
   $p->code = "vide(\$GLOBALS['recherche_doublons'] = \$doublons)";

   return $p;
}

function balise_GET_DOUBLONS($p) {
   $p->code = "vide(\$doublons = \$GLOBALS['recherche_doublons'])";

   return $p;
}

function balise_MERGE_DOUBLONS($p) {
   $p->code = "vide(\$GLOBALS['recherche_doublons']=\$doublons=array_merge(\$doublons,\$GLOBALS['recherche_doublons']))";

   return $p;
}

Reste que cette solution est loin d'être idéale ...
un #CACHE{0} dans les fichiers inclus peut corriger certaines choses (notamment pour l'exemple du dessus)... en créant d'autres problèmes de recalculs gourmands !

c'eût été trop beau que ça marche facilement !!

MM.

Matthieu Marcillaud a écrit :

Matthieu Marcillaud a écrit :

Quelques exemples de possibilités dans

Qui ne marchent pas !!!

A.html
[(#INCLURE{fond=B}{mm_doublons = toto})] // inclus 3 premiers articles
[(#INCLURE{fond=B}{mm_doublons = toto})] // inclus les 3 suivants

Dans ce cas présent, par exemple, c'est 3 fois le même résultat qui est affiché, car le cache se fait en fonction est paramètres passés à l'inclure. Comme les paramètres sont les mêmes, spip réutilisé le cache du premier appel.

Normal, et c'est très bien ainsi.
Mais alors il suffit d'ajouter {appel=1} au 1er appel,
puis {appel=2} puis{appel=3} aux suivants
pour que ça égraine les suivants.
JLuc

From: JLuc <jluc@no-log.org>
Subject: Doublons dans inclure... des solutions

Pour le couteau suisse ?

/* balises pour doublons entre inclure (renato) */
function balise_SET_DOUBLONS($p) {
   $p->code = "vide(\$GLOBALS['recherche_doublons'] = \$doublons)";
   return $p;
}

function balise_GET_DOUBLONS($p) {
   $p->code = "vide(\$doublons = \$GLOBALS['recherche_doublons'])";
   return $p;
}

function balise_MERGE_DOUBLONS($p) {
   $p->code =
"vide(\$GLOBALS['recherche_doublons']=\$doublons=array_merge(\$doublons,\$GLOBALS['recherche_doublons']))";
   return $p;
}

JL

oui, c'est une idée bien pratique en effet...
Je vois aussi que la conversation n'est peut-être pas terminée sur la liste et surtout qu'une doc s'impose. Peut-être quelques tests encore en perspective ?

Ajouter des balises au couteau suisse est très très simple !

  - créer un fichier outils/doublons_fonctions.php (et y mettre les fonctions de balise)

  - ajouter une entrée dans config_outils.php :
  add_outil( array(
    'id' => 'doublons',
    'categorie' => 'spip',
  ));
  - ajouter une entrée dans lang/cout_fr.php :
  'doublons:nom' => 'De belles balises pour les doublons',
  'doublons:description' => 'Une belle description de ces balises',

  - ecrire une doc sur spip-contrib !

Pat

> Pour le couteau suisse ?

Une fois qu'on aura une solution qui marche on la mettra dans le core, plutôt :slight_smile:

-- Fil

Fil a écrit :

Pour le couteau suisse ?

Une fois qu'on aura une solution qui marche on la mettra dans le core, plutôt :slight_smile:

oh oui!!

-- Fil

Fil a écrit :

Pour le couteau suisse ?

Une fois qu'on aura une solution qui marche on la mettra dans le core, plutôt :slight_smile:

respect, alors !
Pat

Pat a écrit :

Fil a écrit :

Pour le couteau suisse ?

Une fois qu'on aura une solution qui marche on la mettra dans le core, plutôt :slight_smile:

Ouais... d'ici là, voici encore quelque chose d'à peu près fonctionnel.
Reste un soucis dans la gestion des différences <INCLURE> et #INCLURE, mélangées dans une page.

J'ai lutté...
Pour comprendre pourquoi ce fichu array_merge ne mergeait pas (deux doublons aux noms identiques) : si les clés de tableau sont identiques, il prend la dernière passée et ne combine pas leurs valeurs respectives... ennuyant pour le tableau $doublons qui a des clé avec les noms des doublons...

Il existe array_merge_recursive, mais comble pour cette fonction, elle m'a renvoyé un warning : "recursion detected"... j'ai pas cherché plus loin...

Donc, là, on a (faudrait trouver des noms de balises corrects ) ...

#LOAD_DOUBLONS : charge dans $doublons le tableau de doublons stocké dans $globals, à placer au début un fichier qui doit utiliser les doublons (enfin les mêmes que d'autres fichiers)

#SAVE_DOUBLONS : fait l'inverse, à placer à la fin d'un fichier inclus pour stocker les valeurs de doublons...

#GET_DOUBLONS : renvoie un serialize() du tableau de doublons global, à passer en paramètre des inclure {_unique #GET_DOUBLONS}, afin de gérer un cache pour chaque appel avec des valeurs doublons différentes.

Fichier B.html :
---------
#LOAD_DOUBLONS
<BOUCLE_B(ARTICLES){par date}{inverse}{0,3}{doublons #ENV{mm_doublons}}>
- #TITRE<br />
</BOUCLE_B>
#SAVE_DOUBLONS
<hr />

Fichier A.html (différents tests) :
------------
OK :

[(#INCLURE{fond=B}{_unique = #GET_DOUBLONS})]

OK :

[(#INCLURE{fond=B}{_unique = #GET_DOUBLONS})]
[(#INCLURE{fond=B}{_unique = #GET_DOUBLONS}{mm_doublons=toto})]

OK :

  <INCLURE{fond=B}{_unique = #GET_DOUBLONS}>

OK :

  <INCLURE{fond=B}{_unique = #GET_DOUBLONS}>
  <INCLURE{fond=B}{_unique = #GET_DOUBLONS}{mm_doublons=toto}>

Raté ! : (<INCLURE> calculé après #INCLURE ; mauvais ordre)

<INCLURE{fond=B}{_unique = #GET_DOUBLONS}> 7,8,9
<INCLURE{fond=B}{_unique = #GET_DOUBLONS}> 10,11,12
<hr />
[(#INCLURE{fond=B}{_unique = #GET_DOUBLONS})] 1,2,3
[(#INCLURE{fond=B}{_unique = #GET_DOUBLONS})] 4,5,6

Non testé : la gestion des documents dans les articles...

Voilà voilà...
Ca permet de faire certaines choses :wink:
Y a du progrès non ?

Le code des balises :

/* balises pour doublons entre inclure (idee _renato_)*/
function balise_SAVE_DOUBLONS($p) {
   $p->code = "vide(\$GLOBALS['recherche_doublons'] = \$doublons)";

   return $p;
}

function balise_LOAD_DOUBLONS($p) {
   if(!isset($GLOBALS['recherche_doublons'])) $GLOBALS['recherche_doublons'] = array();
   $p->code = "vide(\$doublons = \$GLOBALS['recherche_doublons'])";

   return $p;
}

function balise_GET_DOUBLONS($p) {
   $p->code = "serialize(\$GLOBALS['recherche_doublons']))";
   $p->interdire_scripts = false;

   return $p;
}

MM.

Matthieu Marcillaud a écrit :

function balise_GET_DOUBLONS($p) {
   $p->code = "serialize(\$GLOBALS['recherche_doublons']))";
   $p->interdire_scripts = false;

   return $p;
}

Oups ! mauvais décollage ; c'est :

function balise_GET_DOUBLONS($p) {
    $p->code = "serialize(\$GLOBALS['recherche_doublons'])";

    return $p;
}

Bonjour,

Je vais m'arrêter là sur l'exploration doublonographique, car j'arrive à un truc qui fonctionne pour ce que je veux, mais plein d'imperfections :

- on ne peux pas vraiment dire que ça fonctionne avec <INCLURE>, car dans ce cas, #HASH_DOUBLONS (j'ai préféré à get_doublons) renvoie systématiquement un hash d'un NULL, donc le _unique, n'est pas unique :
<INCLURE{fond=B}{_unique = #HASH_DOUBLONS}>

Cependant, les inclusions sont bien faites avec les doublons pris en compte... il y aura un problème de cache alors ?

- j'aurais voulu pouvoir faire un hash unique, en fonction d'une partie du tableau doublons comme #HASH_DOUBLONS{toto}, pour faire des caches en fonctions du nom des doublons utilisés dans les fichiers inclus, et pas en fonction de toutes les valeurs du tableau doublons, mais... je n'ai pas réussi...

Récapitula-tif-tif :

#LOAD_DOUBLONS : charge dans $doublons le tableau de doublons stocké dans $globals, à placer au début un fichier qui doit utiliser les doublons (enfin les mêmes que d'autres fichiers)

#SAVE_DOUBLONS : fait l'inverse, à placer à la fin d'un fichier inclus pour stocker les valeurs de doublons...

#HASH_DOUBLONS : (ou #id_doublons?) renvoie un md5(serialize()) du tableau de doublons global, à passer en paramètre des inclure {_unique #HASH_DOUBLONS}, afin de gérer un cache pour chaque appel avec des valeurs doublons différentes.

md5() pour que la chaine soit pas trop longue si beaucoup de doublons...

Fichier B.html :
---------
#LOAD_DOUBLONS
<BOUCLE_B(ARTICLES){par date}{inverse}{0,3}{doublons #ENV{mm_doublons}}>
- #TITRE<br />
</BOUCLE_B>
#SAVE_DOUBLONS
<hr />

Fichier A.html (différents tests) :
------------
OK :

[(#INCLURE{fond=B}{_unique = #GET_DOUBLONS})]

OK :

[(#INCLURE{fond=B}{_unique = #GET_DOUBLONS})]
[(#INCLURE{fond=B}{_unique = #GET_DOUBLONS}{mm_doublons=toto})]

mes_fonctions.php :

/* balises pour doublons entre inclure (idee _renato_)*/
function balise_SAVE_DOUBLONS($p) {
   $p->code = "vide(\$GLOBALS['recherche_doublons'] = \$doublons)";

   return $p;
}

function balise_LOAD_DOUBLONS($p) {
   if(!isset($GLOBALS['recherche_doublons'])) $GLOBALS['recherche_doublons'] = array();
   $p->code = "vide(\$doublons = \$GLOBALS['recherche_doublons'])";

   return $p;
}

/*
  * Genere un id unique pour le tableau de doublons #ID_DOUBLONS,
  */
function balise_HASH_DOUBLONS($p) {
   $p->code = "md5(serialize(\$GLOBALS['recherche_doublons']))";

   return $p;
}

Matthieu Marcillaud a écrit :

- on ne peux pas vraiment dire que ça fonctionne avec <INCLURE>, car dans ce cas, #HASH_DOUBLONS (j'ai préféré à get_doublons) renvoie systématiquement un hash d'un NULL, donc le _unique, n'est pas unique :
<INCLURE{fond=B}{_unique = #HASH_DOUBLONS}>

Cependant, les inclusions sont bien faites avec les doublons pris en compte... il y aura un problème de cache alors ?

Hé hé, je confirme, pas glop :wink:
C'est pris en compte la première fois ?var_mode=calcul... mais ensuite, si on force pas le calcul, non, ça marche plus pour <INCLURE>

#inclure semble ok, c'est déjà ça !

MM.

(17 ans plus tard) Ça ne peut pas marcher comme ça pour les <INCLURE> probablement car sauf si var_mode=calcul, les calculs du squelette appelant et appelé ne se font pas en même temps, pas dans le même hit…