[spip-dev] Filtre |foreach, sans contexte on ira pas loin dans les boucles d'interface -> proposition de patch

Bonjour,

Je travaille pour la première fois avec le filtre foreach (pour ne pas risquer de me compromettre avec la boucle POUR dont on sait qu'elle est dérogatoire), car j'ai besoin de faire un squelette qui boucle sur un tableau.

Ce filtre prend justement en entrée un tableau et se propose de le faire boucler en appelelant itérativement un modèle, selon la méthode officielle SPIP, super en somme.

Sauf qu'on ne peut pas passer de contexte au modèle utilisé !! Ce qui n'est évidement pas pratique dès qu'on fait des itérations un peu sérieuses pour faire des squelettes.

Voici donc une proposition de patch, qui permet d'ajouter un paramètre en plus au filtre |foreach{modele,param=valeur}. Si cela vous parait une bonne piste, je peux essayer d'ajouter plusieurs paramètres, voir carrement {env}.

// http://doc.spip.org/@filtre_foreach_dist
// permettre de passer un parametre pour le contexte du modele avec

foreach{page,param=valeur}

function filtre_foreach($balise_deserializee, $modele = 'foreach',$parametre='') {
  $texte = '';
  if(is_array($balise_deserializee))
    foreach($balise_deserializee as $k => $v) {
      $contexte = array_merge(array('cle' => $k), (is_array($v) ? $v : array('valeur' => $v))) ;
      $param = preg_split("/=/",$parametre);
      if(is_array($param)){
        $contexte[$param[0]] = $param[1];
      }
        
      $res = recuperer_fond('modeles/'.$modele,$contexte);
      $texte .= $res;
    }
  return $texte;
}

BoOz

On trolle même le dimanche ? Ok.

C'est vrai que c'est plus utile de travailler sur un truc qui n'a jamais été réellement utilisé plutôt que sur la boucle POUR...

D'après moi il y a une raison. Car à l'époque de sa création, ce "foreach" a été correctement documenté pourtant. Donc je pense que si personne n'a eu le courage de l'utiliser c'est qu'il ne correspond pas du tout à un besoin. Ou qu'à moitié en tout cas. En effet, devoir créer un nouveau fichier pour CHAQUE boucle qu'on veut faire !... Super la rigolade.

Ok il y a des problèmes avec POUR, mais qui peut nier que ça a vraiment correspondu à une attente de dizaines de développeurs sur la zone, qui l'utilisent désormais régulièrement et avec beaucoup de facilité ?

Vive les utilisateurs, vive le populisme !
Ouaiiiiiiiiiiis.

RastaPopoulos a écrit :
[...]

Hein ?

Merci de ne pas saboter le débat. Le besoin est clair, c'est de faire des itérations.

Créer un modèle pour afficher le contenu des itérations, c'est le principe d'un inclure. Je ne vois pas de soucis particulier.

En revanche il faut résoudre cette histoire de contexte. D'ou le message précédent, l'as tu lu ?

BoOz

Hello,

Voici le filtre |foreach reboosté avec la possibilité de passer plusieurs parametres en contexte pour le modèle.

De plus, après discussion sur irc nous avons pensé que le filtre

foreach était assez mal nommé, si on doit le généraliser pour faire des

itérations de modeles avec contexte inclus sur des tableaux, utile pour faire des squelettes, autant lui donner un nom clair, et different d'une fonction php bien connue.

Voici donc le nouveau filtre proposé : |repeter_modele

[(#TABLEAU|repeter_modele{modele,param=valeur,param2=valeur2,...})]

Dans cette implémentation, |foreach devient un alias de

repeter_modele{foreach}.

Voir le code ci dessous, si ca vous plait je le commit.

BoOz

//[(#TABLEAU|repeter_modele{modele,param=valeur,param2=valeur2,...})]
// http://doc.spip.org/@filtre_repeter_modele_dist
function filtre_repeter_modele_dist($balise_deserializee, $modele ='', $parametre='') {
    
  $parametres = func_get_args();
  unset($parametres[0],$parametres[1]);
    
  $texte = '';
  if(is_array($balise_deserializee))
    foreach($balise_deserializee as $k => $v) {
      $contexte = array_merge(array('cle' => $k), (is_array($v) ? $v : array('valeur' => $v))) ;
      if(is_array($parametres)){
        foreach($parametres as $param){
          $param = preg_split("/=/",$param);
          if(is_array($param)){
            $contexte[$param[0]] = $param[1];
          }
        }
      }
        
      $res = recuperer_fond('modeles/'.$modele,$contexte);
      $texte .= $res;
    }
  return $texte;
  
}

//[(#ENV*|unserialize|foreach)]
// http://doc.spip.org/@filtre_foreach_dist
function filtre_foreach($balise_deserializee, $modele = 'foreach') {
  return filtre_repeter_modele_dist($balise_deserializee, $modele);
}

BoOz wrote:

Il y a un truc que je ne comprends pas : pourquoi "modèle" ?

Je rappelle quand même que tout ce qui se trouve dans le dossier "modeles/" sont des squelettes appelables directement depuis un contenu SPIP, avec <modele>. En quoi les squelettes utilisés ici pour faire des itérations ont un quelconque rapport avec des choses à appeler depuis un contenu ? C'est pas un mélange bizarre ?

RastaPopoulos wrote:

Voici donc le nouveau filtre proposé : |repeter_modele

En quoi les squelettes utilisés ici pour faire des

itérations ont un quelconque rapport avec des choses à appeler depuis un contenu ? C'est pas un mélange bizarre ?

Pour etre honnête, j'ai étendu le code du filtre |foreach qui lui même utilisait des modeles sans trop me poser cette question.

J'ignore s'il y a un avantage par rapport à un autre type d'inclusion.

Surtout que dans le code c'est un recuperer_fond(), donc on doit pouvoir repeter_squelette sans que ca change rien techniqument.

Peut être que squelette évoque un gabarit complet (voire un ensemble de gabarits pour certains - sarka crew -) tandis que modele évoque plus une inclusion.

Si des vérérants de la balise foreach ont un souvenir de tout ca ?

BoOz