Portrait ou Paysage ?

Ceci est une ARCHIVE, peut-être périmée. Vérifiez bien les compatibilités !

Comment sélectionner les images d’une boucle DOCUMENTS en fonction de leur orientation.
Un exemple de nouvelles fonctionnalités de SPIP 1.8

Dans une boucle DOCUMENTS qui sert à afficher des images (par exemple pour une galerie), on peut vouloir sélectionner les images par leur orientation.

En fonction de la mise en page que l’on recherche, cela peut être important de savoir si l’image qu’on va afficher sera en portrait [1] ou en paysage [2].

Voici quelques solutions utilisant les nouvelles fonctionnalités de SPIP 1.8.

Orientation (0.2.0)
Pour les utilisateurs de la version 1.9, vous pouvez telecharger le plugin directement.

Ce qui vient à l’esprit

On sait que dans une boucle document, on peut accéder aux balises #HAUTEUR et #LARGEUR. Cela signifie que l’on peut aussi mettre un critère limitant la hauteur ou la largeur des DOCUMENTS sélectionnés :

<BOUCLE_doc(DOCUMENTS) {id_article} {largeur < 800}>
#LOGO_DOCUMENT
</BOUCLE_doc>

On pourrait donc être tenté de comparer la largeur et la hauteur de la même façon :

<BOUCLE_doc(DOCUMENTS) {id_article} {largeur < hauteur}>
#LOGO_DOCUMENT
</BOUCLE_doc>

SPIP autorise la première boucle. En effet, on peut comparer n’importe quelle colonne de la base de donnée avec une valeur constante. Cependant dans la 2e boucle proposée, la valeur à droite n’est pas une constante, mais un nom de colonne. Ce critère va donc échouer.

La solution intuitive n’était pas la bonne.

Une solution limitée : imbriquer les boucles

Quand on dit que la valeur à droite doit être une constante, cela veut dire qu’elle peut être :

  • une constante numérique (un id, une taille, etc...),
  • une chaîne de caractères (un titre d’article, de rubrique, etc...)
  • une expression régulière
  • la valeur d’une balise d’une boucle englobante.

Effectivement, quand on est dans une itération spécifique d’une boucle, les valeurs de ses balises sont constantes quand elles sont observées par les boucles imbriquées.

On va donc pouvoir utiliser une boucle englobante pour passer la taille du document à droite de l’opérateur :

<BOUCLE_doc(DOCUMENTS) {id_article}>
<BOUCLE_portrait(DOCUMENTS) {id_document} {hauteur >= #LARGEUR}>
#LOGO_DOCUMENT
</BOUCLE_portrait>
</BOUCLE_doc>

On boucle donc avec _doc pour trouver tous les documents d’un article (mais on pourrait utiliser d’autres critères). Ensuite, la boucle _portrait grâce au critère id_document ne sélectionne qu’un document (celui choisi par la boucle _doc).

Elle vérifie aussi que la hauteur de ce document soit plus grande ou égale à la largeur du document sélectionné par la boucle englobante (donc exactement le même).

Voici donc une première solution fonctionnelle pour sélectionner des documents en fonction de leur orientation.

Malheureusement, un critère souvent utilisé ne marchera pas correctement avec cette boucle : {a,b}. En effet, la limitation du nombre de résultats doit être appliquée à la première boucle. Mais celle ci sélectionne tous les documents et donc le compte de documents sera faussé.

Une solution plus souple : utiliser les doublons

Une solutions pour pouvoir utiliser le critère {a,b} est d’utiliser les doublons :

<BOUCLE_doc(DOCUMENTS) {id_article}>
<BOUCLE_paysage(DOCUMENTS) {id_document} {largeur >= #HAUTEUR} {doublons}>
</BOUCLE_paysage>
</BOUCLE_doc>

<BOUCLE_portrait(DOCUMENTS) {id_aticle} {doublons} {0,5}>
#LOGO_DOCUMENT
</BOUCLE_portrait>

Une première boucle parcours les documents que l’on ne veut pas et n’affiche rien, mais remplie la pile de doublons.
La deuxième boucle parcoure tous les documents sauf ceux qui sont dans doublons, c’est à dire ceux qui n’ont pas été éliminés par la boucle précédente.

Une solution intégrée : fournir de nouveaux critères

Bon, tout cela devient compliqué mais reste du code SPIP pur. Malheureusement, même la deuxième solution — dans des cas spéciaux — a certaines limitations.

Voici une solution utilisant l’extensibilité de la version 1.8 de SPIP, pour ajouter trois nouveaux critères de boucle. C’est du code php mais vous n’êtes pas obligé de le comprendre pour l’utiliser. Les critères {portrait} et {paysage} seront alors disponibles. Par exemple :

<BOUCLE_portrait(DOCUMENTS) {id_article} {portrait} {0,5}>
#LOGO_DOCUMENT
</BOUCLE_portrait>

Il faut placer ce code dans mes_fonctions.php3, ou dans un fichier qu’on incluera depuis mes_fonctions.php3.

Attention, les deux critères utilisent des inégalités strictes pour sélectionner les images. Ainsi, les images carrées : Hauteur = Largeur ne seront pas sélectionnées par ces deux critères. C’est pourquoi on ajoute aussi le critère {carre} qui retourne les images carrées.

<?php

function critere_portrait($idb, &$boucles, $param, $not) {
  $boucle = &$boucles[$idb];
  $table = $boucle->id_table;

  if ($not) 
	$boucle->where[] = $table.".hauteur <= ".$table.".largeur";
  else
	$boucle->where[] = $table.".hauteur > ".$table.".largeur";
}


function critere_paysage($idb, &$boucles, $param, $not) {
  $boucle = &$boucles[$idb];
  $table = $boucle->id_table;

  if ($not) 
	$boucle->where[] = $table.".largeur <= ".$table.".hauteur";
  else 
	$boucle->where[] = $table.".largeur > ".$table.".hauteur";
}

function critere_carre($idb, &$boucles, $param, $not) {
  $boucle = &$boucles[$idb];
  $table = $boucle->id_table;

  if ($not) 
	$boucle->where[] = $table.".largeur != ".$table.".hauteur";
  else
	$boucle->where[] = $table.".largeur = ".$table.".hauteur";
}
?>

Voici quelques explications pour ceux qui s’intéressent au code. Les trois fonctions font essentiellement la même chose :

  1. Les deux premières lignes récupèrent la boucle dans laquelle on se trouve et le nom de la table de la base concernée.
  2. On vérifie ensuite que le critère n’est pas inversé (par le signe « ! ») ; si c’est le cas, on utilise le critère de comparaison inverse.
  3. On ajoute enfin une nouvelle contrainte à la requête qui sera faite à la base. Cette contrainte compare les colonnes hauteur et largeur de la table concernée.

Notes

[1Verticale

[2Horizontale

Discussion

3 discussions

  • 3

    Bonjour,
    J’aimerais utiliser cette contribution sous forme de plugin pour la 1.9.1. Celui-ci est installé (en local) et activé.
    Ce nouveau critère est-il compatible avec une boucle ARTICLES ? J’affiche aléatoirement un logo d’article, dans un site de type galerie. J’aimerais que seuls les modes portrait soient à l’écran. J’ai testé, mais j’obtiens une erreur de type « critère non reconnu ».
    Cette erreur répond sans doute à la question...

    Merci pour votre contribution :)

    • Tu as bien compris ;)

      ce n’est pas possible d’appliquer ce critère à la boucle ARTICLES puisqu’il se base sur l’information de HAUTEUR et LARGEUR fournis pas la boucle, et il n’y a que la boucle DOCUMENTS qui a ces balises.

    • Bonjour,
      Quelqu’un aurait-il une solution pour effectuer ce tri (Paysage ou vertical) sur les logos ?

      En effet, j’aurai besoin d’y type d’affichage différent selon l’orientation du logo de l’articole.

      Merci ^^

    • On peut utiliser ça :

      [(#SET{largeur,#LOGO_SITE_SPIP|extraire_attribut{width}})]
      [(#SET{hauteur,#LOGO_SITE_SPIP|extraire_attribut{height}})]
       
      [(#GET{largeur}|>{#GET{hauteur}}|?{horizontal,vertical})]

    Répondre à ce message

  • 2

    Sur une version Spip 1.9 ce filtre ne marche plus, est-ce normal ou est-ce moi qui ai pu faire une erreur ?

    La version sous forme de plugin (pas facile à récupérer d’ailleurs via spip-zone, y aurait pas un zip à coller sur cette page par exemple ?) fonctionne correctement sans que je change mes squelettes.

    Répondre à ce message

  • 4

    salut, est-il possible que la contrib marche en affichant un message d’erreur avec la version cvs du jour ?
    Warning : Missing argument 4 for critere_paysage() in...

    mais l’affichage est correct

    • mortimer

      Aïe,

      effectivement, l’API pour cela a aussi changée dans la 1.8.2. Donc ça ne marchera pas si tu essais de faire un {!portrait} par exemple.

      Il faut ajouter dans les 3 fonctions, tout au début :
      $not = $param->not;

      et enlever $not de la liste des params de la fonction. Ainsi,
      critere_portrait($idb, &$boucles, $param, $not) devient : critere_portrait($idb, &$boucles, $param)

    • faut aussi l’ajouter à paysage ?

    • mortimer

      Salut,

      je suis désolé si c’etait pas clair :

      Il faut ajouter dans les 3 fonctions

      ça veut dire qu’il faut le faire partout : portrait, paysage et carre ;)

    • faut le faire aussi sur les deux autres types (carré et portrait)

    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