var Phenix = function () {
Troll du Web depuis 1996

SPIP

Contrôler les index des tableaux #SPIP

SPIP possède un mécanisme de tableau dans le compilateur. C’est plutôt rudimentaire et mériterait certainement plus d’attention de la part des développeurs.

Dans beaucoup de cas, ils sont de précieux alliés mais rapidement limités. On les abandonne généralement rapidement au profit d’une fonction php. Soit parce que le code devient illisible, soit parce qu’ils ne sont pas assez souples.

Cependant, il y a quand même moyen de faire des choses assez puissantes sans prise de tête particulière. L’installation de spip_bonux est indispensable, cela permet d’accéder aux balises #SET_PUSH et #SET_MERGE qui rendent le code plus lisible.

Un système de news par secteur ET par mots-clés

J’ai besoin d’afficher tous les articles d’un secteur mélangés avec les articles qui possèdent un mot-clé défini.
L’idée est de créer un module de « news » qui peut être enrichi par des articles qui ne seraient pas dans la rubrique « news ».
L’idée est simple : remplir un tableau a l’aide de deux boucles SPIP et puis l’afficher avec une boucle DATA.

  1. [(#REM) Initialiser le tableau ]
  2. [(#SET{news, #ARRAY})]
  3. <BOUCLE_article(ARTICLES){id_secteur=1}{par date}{inverse}{lang}{0,2}>
  4. [(#SET_PUSH{news, #ID_ARTICLE})]
  5. </BOUCLE_article>
  6.  
  7. [(#REM) Recherche sur le mot-clé "news" ]
  8. <BOUCLE_mot(ARTICLES){id_mot=42}{par date}{inverse}{lang}{0,2}>
  9. [(#SET_PUSH{news, #ID_ARTICLE})]
  10. </BOUCLE_mot>

#GET{news} contient maintenant 4 id_articles : les deux derniers articles du secteur 1 et les deux derniers articles possédant le mot-clé 42.

Mais comme c’est un système de news, il faut tirer l’affichage par date. Or, les données du tableau sont tirées par ordre de boucles : d’abord, les informations de la boucle article, ensuite les informations de la boucle d’article_mot.

En réalité, ce dont j’ai besoin, c’est de la possibilité de trier mon tableau par date une fois qu’il a été généré par les boucles. Il faut donc que je sauvegarde la date de l’article dans mon tableau.

  1. [(#REM) Initialiser le tableau ]
  2. [(#SET{news, #ARRAY})]
  3. <BOUCLE_article(ARTICLES){id_secteur=1}{par date}{inverse}{lang}{0,2}>
  4. [(#SET_PUSH{news, #ARRAY{id_article, #ID_ARTICLE, date, #DATE}})]
  5. </BOUCLE_article>
  6.  
  7. [(#REM) Recherche sur le mot-clé "news" ]
  8. <BOUCLE_mot(ARTICLES){id_mot=42}{par date}{inverse}{lang}{0,2}>
  9. [(#SET_PUSH{news, #ARRAY{id_article, #ID_ARTICLE, date, #DATE}})]
  10. </BOUCLE_mot>

Voilà, donc maintenant, #GET{news} est un tableau qui contient 4 tableaux à deux clés : id_article et date.

Ensuite, via une petite astuce php, on va utiliser une des deux valeurs comme clé pour recomposer un tableau. Rien de complexe, tout est dans PHP :

  1. [(#REM) Simplifier le tableau pour avoir id_article => date ]
  2. [(#SET{news, #GET{news}|array_column{date, id_article}})]

Array_column est une fonction PHP 5.5. Mais spip_bonux l’apporte au version inférieur.

Ensuite, il ne reste plus qu’à faire une boucle data triée par valeur.

Voici le code complet :

  1. [(#REM)
  2. On va calculer les news:
  3. - Soit cela se trouve dans le secteur des news
  4. - Soit il y a le mot-clé news
  5. ]
  6.  
  7. [(#REM) Initialiser le tableau ]
  8. [(#SET{news, #ARRAY})]
  9. <BOUCLE_article(ARTICLES){id_secteur=1}{par date}{inverse}{lang}{0,2}>
  10. [(#SET_PUSH{news, #ARRAY{id_article, #ID_ARTICLE, date, #DATE}})]
  11. </BOUCLE_article>
  12.  
  13. [(#REM) Recherche sur le mot-clé "news" ]
  14. <BOUCLE_mot(ARTICLES){id_mot=42}{par date}{inverse}{lang}{0,2}>
  15. [(#SET_PUSH{news, #ARRAY{id_article, #ID_ARTICLE, date, #DATE}})]
  16. </BOUCLE_mot>
  17.  
  18. [(#REM) Simplifier le tableau pour avoir id_article => date ]
  19. [(#SET{news, #GET{news}|array_column{date, id_article}})]
  20.  
  21. <section class="section-news">
  22. <span class="label article-section"><:titre_news:></span>
  23. [(#REM) Affichage de articles du tableau ]
  24. <B_data_news>
  25. <ul class="news-list">
  26. <BOUCLE_data_news(DATA){source tableau, #GET{news}}{par valeur}{inverse}{0,2}>
  27. <li><INCLURE{fond=inclure/article_resume, id_article=#CLE} /></li>
  28. </BOUCLE_data_news>
  29. </ul>
  30. </B_data_news>
  31. </section>

Générer automatiquement des touch-icons avec #SPIP

Comme beaucoup de choses en développement web, les touch-icons [1] c’est le bordel.
Des formats différents en fonction des écrans, en fonction des résolutions d’écrans, des versions d’Android en vrac, et des développeurs perdus au milieu.

Bref, voici un petit squelette SPIP basé sur le travail Mathias Bynens.

L’idée est de placer un fichier apple-touch-icon.png dans le dossier squelettes/ de SPIP pour le décliner automatiquement dans toutes les autres versions.
Le fichier ne sera pas agrandi donc il vaut mieux utiliser un fichier de minimum 192px.

Dans certains cas, la gestion automatique n’est pas idéale.
On peut alors placer un fichier apple-touch-icon-VALEURxVALEUR.png pour remplacer celui générer automatiquement.
Par exemple, si je veux remplacer le fichier 72px : apple-touch-icon-72x72.png

  1. [(#REM)
  2. Favicon touch icon.
  3. Voir https://mathiasbynens.be/notes/touch-icons
  4.  
  5. Ce fichier va générer les favicons pour un maximum de device.
  6. Il n'est pas inutile de passer ce squelette dans le filtre supprimer_ligne_vide (https://gist.github.com/phenix-factory/1dc0195bd655a654b9ef)
  7. ]
  8.  
  9. [(#REM)
  10. Tableau des tailles, en px
  11. Pour le moment, ils n'ont pas encore pondu autre chose que des icônes carrées. On espère que cela ne change pas.
  12. ]
  13.  
  14. [(#SET{taille_device,
  15. [(#ARRAY{
  16. 192,192,
  17. 180,180,
  18. 152,152,
  19. 144,144,
  20. 120,120,
  21. 114,114,
  22. 76,76,
  23. 72,72,
  24. 60,60,
  25. 57,57})]})]
  26.  
  27. <BOUCLE_generateur_touch_icone(DATA){source tableau, #GET{taille_device}}>
  28. [(#REM)
  29. L'utilisateur fourni un fichier spécifique, on affiche directement
  30. ]
  31.  
  32. [(#CHEMIN{apple-touch-icon-#VALEURx#VALEUR.png}|oui)
  33. [<link rel="[(#VALEUR|=={192}?{icon, apple-touch-icon-precomposed})]" sizes="#VALEURx#VALEUR" href="(#CHEMIN{apple-touch-icon-#VALEURx#VALEUR.png})">]
  34. ]
  35.  
  36. [(#REM)
  37. Pas de fichier spécifique, on va créer l’icône si le fichier générique le permet.
  38. ]
  39. [(#CHEMIN{apple-touch-icon-#VALEURx#VALEUR.png}|non
  40. |et{#CHEMIN{apple-touch-icon.png}|hauteur|>={#VALEUR}|oui}
  41. |et{#CHEMIN{apple-touch-icon.png}|largeur|>={#VALEUR}|oui})
  42. [<link rel="[(#VALEUR|=={192}?{icon, apple-touch-icon-precomposed})]" sizes="#VALEURx#VALEUR" href="(#CHEMIN{apple-touch-icon.png}|image_reduire{#VALEUR,#VALEUR}|extraire_attribut{src})">]
  43. ]
  44. </BOUCLE_generateur_touch_icone>

Un Gist est disponible pour ce code.

[1Les icônes qui s’affichent quand un site web est ajouté dans la liste des app d’un smartphone par exemple


DOMPDF, générer des PDF à partir de vos squelettes !

Ce plugin intègre la librairie DOMPDF à SPIP et fourni un API pour exporter directement le résultat d’un squelette SPIP en PDF.

API

Ce plugin fournit une fonction d’exportation du résultat d’un squelette qui s’utilise comme ceci :

  1. // Charger l'API
  2. $exporter_pdf = charger_fonction('exporter_pdf', 'inc');
  3. $exporter_pdf($squelette_ou_html, array $context);

Modifier la génération des URLs de #SPIP

SPIP dispose de quelques « schémas » d’URL par défaut. Dans la majorité des cas, ils conviennent aux goûts de chacun.

Cependant, il peut arriver que l’on ait envie de modifier la façon dans les URLs sont créées.
Dans mon cas, j’avais envie de changer les URLs Arborescentes qui créée par défaut un schéma objet/titre.

Cela ne me convenait pas dans le cas des auteurs, auteur/nom_auteur ne signifiait rien, je voulais un visiteur/nom_visiteur.

Ce qu’il faut savoir

SPIP possède une table dans laquelle il place toutes les urls du site. Sans surprise, elle a pour nom... spip_urls.
Une fois qu’une url est ajoutée dans cette base, elle n’en bougera plus. Même si on change de schéma.
Si l’on change le schéma des URLs, les anciennes continueront de fonctionner, en plus des nouvelles.

C’est l’un des rares cas où vider le cache ne suffit pas pour faire des tests, il faut aussi supprimer les URLs de la table. Je vous déconseille fortement de faire cela avec un site en production...

Utiliser les bons pipelines

Il existe 2 pipelines pour modifier les URLs. Toutes ne sont pas modifiables :

  • propres_creer_chaine_url pour les URLs Propres, les URLs Propres+.html et les URLs Libres.
  • arbo_creer_chaine_url pour les URLs Arborescentes.

Ces pipelines retournent un tableau du style :

  1. $flux = array(
  2. "data" => "article/test",
  3. "objet" => array(
  4. "url" => null,
  5. "date" => null,
  6. "id_parent" => null,
  7. "perma" => null,
  8. "titre" => "test",
  9. "lang" => null,
  10. "parent" => '0',
  11. "type_parent" => '',
  12. "type" => "article",
  13. "id_objet" => 24
  14. )
  15. );

L’url se trouve dans la cellule data, il suffit de la modifier !
La cellule objet contient des informations que l’on peut exploiter.

Exemple

Par défaut, les url arbo créent une url auteur/nom_de_l’auteur. Or, j’ai envie de changer et d’utiliser « visiteur » à la place de "auteur’, voici à quoi devrait ressembler mon pipeline :

  1. /**
  2.  * On bricole les URLs dans ce pipeline
  3.  *
  4.  * @param mixed $flux
  5.  * @access public
  6.  * @return mixed
  7.  */
  8. function prefix_arbo_creer_chaine_url($flux) {
  9. // On chope les auteurs pour créer des urls "visiteur"
  10. if ($flux['objet']['type'] == 'auteur') {
  11. // On inclut les fonctions d'édition d'url par sécurité
  12. include_spip('action/editer_url');
  13.  
  14. // Créer une URL "visiteur"
  15. $flux['data'] = 'visiteur/'.url_nettoyer($flux['objet']['titre'],_URLS_ARBO_MAX,_URLS_ARBO_MIN,'-',_url_arbo_minuscules?'strtolower':'');
  16. }
  17.  
  18. return $flux;
  19. }

J’ai repris la fonction url_nettoyer telle qu’elle était utilisée par le core.