Carnet de notes

Derniers billets

  • ZCM - Squelette modulaire SPIP/ZCore

    , par jeanmarie

    L’idée de ce squelette est de moderniser ZDist V2 en le rendant HTML5 et en y intégrant différents besoins propres tels un agenda, les micro-datas, des façons d’afficher des images...

    Il est (plus que) largement inspiré de Intégraal de rastapopoulos et SPIPr de Nursit.

    Liste des variables personnalisables

    1. // ID de l'article contact pour les liens dans le pied de page
    2. define('_ZCM_ID_CONTACTS','1');
    3. // ID de l'article mentions légales pour les liens dans le pied de page
    4. define('_ZCM_ID_MENTIONS_LEGALES','2');
    5. // ID d'un autre article pour les liens dans le pied de page
    6. define('_ZCM_ID_AUTRE_ARTICLE_FOOTER','10');
    7. // Inclure le css de grillade pour les grille (voir doc pdf plus bas)
    8. define('_ZCM_GRILLADE',true);
    9. // Inclure le js et la css du modèle bloc dépliable
    10. define('_ZCM_BLOCS_DEPLIABLES', true);
    11. // Définir la balise par défaut des blocs dépliables (peut être surchargé par "balise=" mais doit être définit)
    12. define('_ZCM_BLOCS_DEPLIABLES_BALISE', 'h2');
    13. // Inclure la css permettant d'avoir des fonds perdus
    14. define('_ZCM_FOND_PERDU', true);
    15. // Définir la taille limite pour avoir, ou non, des fonds perdus
    16. define('_ZCM_FOND_PERDU_LARGEUR', '1000px');

    Télécharger

    Doc Grillade

    Les modèles

    Les blocs dépliables (exemple)
    <deplier|debut|titre=Le titre du bloc à déplier|soustitre=Le soustitre facultatif|balise=p>
    Le texte à déplier
    <deplier|fin>

    Les inclures

    Agenda

    Permet d’afficher, sous la forme d’une grille (si grillade activée) de vignettes, un agenda des événements.
    2 possibilités :
    - les événements à venir (paramètre a_venir=oui)
    - les événements de la rubrique (paramètre saison=oui)

    Doc complète.

    Exemple d’insertion
    Si on est à la racine du secteur, on est en mode agenda à venir, sin on est dans une sous rubrique, on est en mode tous les événements de la saison.

    1. [(#ID_RUBRIQUE|=={#ID_SECTEUR}|?{
    2. <INCLURE{fond=inclure/liste/agenda,env,ajax,id_secteur=1,affichage_long=oui,a_venir=oui,afficher_filtres=oui,afficher_mois=oui} />
    3. ,
    4. <INCLURE{fond=inclure/liste/agenda,env,ajax,id_rubrique,affichage_long=oui,saison=oui} />
    5. })]

    Télécharger

    Dates d’un événement

    Affiche les dates d’un événement en gérant les différents cas :
    - événement unique
    - événement sur la durée
    - plusieurs événements le même jour
    - plusieurs événements sur plusieurs jours

    On peut afficher les dates au format court ou long.

    Doc complète.

    <INCLURE{fond=inclure/dates-evenement,id_article} />

    Vignette d’article

    Affiche le logo de l’article, sinon un document image lié à l’article (avec gestion du rang), sinon le logo du site. Fonctionne avec le filtre image_responsive.

    Doc complète.

    <INCLURE{fond=inclure/vignette-article,id_article} />

    Les galeries et diaporamas d’images

    Le portfolio
    Affiche des images côte à côte avec possibilité de les agrandir : <INCLURE{fond=inclure/galerie/portfolio,id_article} />
    Doc complète.

    Le mosaïque simple
    Affiche 2 images côte à côte : <INCLURE{fond=inclure/galerie/mosaique-simple,id_article} />
    Doc complète.

    Le mosaïque variable
    Affiche une mosaïque de 4 images de tailles : <INCLURE{fond=inclure/galerie/mosaïque-variable,id_article} />
    Doc complète.

    Le diaporama
    Affiche un diaporama Slick avec les images de la rubrique ou de l’article : <INCLURE{fond=inclure/galerie/diaporama,id_article} />
    Doc complète.

    Le diaporama "focus d’accueil"
    Affiche un diaporama Slick avec les images d’une rubrique ou d’un article avec des liens : <INCLURE{fond=inclure/galerie/focus,id_article=12} />
    Doc complète.

    Dépendances

    L’idée est de garder un minimum de dépendances dans le plugin.

    1. <necessite nom="medias_responsive_mod" compatibilite="[1.8.0;]" />
    2. <necessite nom="metasplus" compatibilite="[1.2.5;]" />
    3. <utilise nom="responsivenav" compatibilite="[0.1.0;]" />
    4. <utilise nom="slick" compatibilite="[1.2.0;]" />
    5. <necessite nom="Zcore" compatibilite="[2.5.0;]" />

    Télécharger

    Taille des textes

    1em = 16px.
    Pour augmenter d’1px, augmenter de 0.625em.

    Taille des fonts

    Le repo

    https://gitlab.com/jmoupah/zcm

    To do

    • mosaïque : choisir les tailles des images
    • diaporama : faire fonctionner avec n’importe quel objet (auteur...)
    • modèle dates-spectacle : pouvoir afficher les horaires
    • Modèle vignette rwd : passer en lazyload + img_recardre proportions

    Liens

    Framework Z - Industrialisation des squelettes
    http://spipr.nursit.com/framework-z

    Zpip
    https://contrib.spip.net/Zpip

    Créer des squelettes avec Zcore
    https://contrib.spip.net/Creer-des-squelettes-avec-Zcore

    Zpip ou Z, Zcore et Thèmes
    https://www.spippourlesnuls.fr/?zpip-ou-z-zcore-et-themes,189

    SPIPr - SPIP reboot
    http://spipr.nursit.com/

    Sur la zone

    SPIP-r dist
    https://zone.spip.org/trac/spip-zone/browser/_squelettes_/spipr-dist

    Integraal
    https://zone.spip.org/trac/spip-zone/browser/_squelettes_/integraal/

  • Afficher sur une carte GIS des points dont on n’a que l’adresse

    , par jeanmarie

    Le besoin

    Afficher sur une carte des points dont on n’a que l’adresse.

    Le cas concret

    Afficher des points de ventes sur une carte à partir d’un document tableur (LibreOffice Calc, Microsoft Excel...) avec possibilité de géolocaliser le visiteur.

    Le principe

    Il faut géocoder les adresses, c’est à dire trouver leurs coordonnées GPS, dans un document CSV pour pouvoir les lire avec une boucle DATA et générer un fichier JSON que GIS pourra lire.

    Oui, rien que ça :)

    Le géocodage

    Via le site adresse.data.gouv.fr, on peut géocoder des adresses en fournissant un fichier CSV de ce type :

    EnseigneAdresseCode postalVille
    Magasin 1 Adresse 1 CP 1 Ville 1
    Magasin 2 Adresse 2 CP 2 Ville 2

    Il en ressort un fichier CSV avec différentes infos supplémentaires dont la latitude et la longitude de chaque enseigne.

    Lire le fichier CSV et générer le JSON

    Pour que le rédacteur ait la main sur la carte, on passe le CSV comme document joint de l’article dans lequel on va afficher la carte.

    On récupère donc l’URL de ce document avec une boucle DOCUMENTS pour la passer dans une variable source via un #SET

    Dans json/gis_pointsdevente.html

    1. <BOUCLE_source(DOCUMENTS){id_article}{extension=csv}{!par date}{0,1}> #SET{source,#URL_DOCUMENT}</BOUCLE_source>

    Les critères :
    {extension=csv} pour ne sélectionner que les documents .csv
    {!par date} pour toujours prendre le dernier documents envoyé
    {0,1} pour ne prendre qu’un document

    Ensuite, avec une boucle DATA, on extrait les infos souhaitées du CSV pour construire le JSON.

    La petite subtilité ici est que, si une entrée n’a pas de coordonnées (parce que le géocodage n’a pas fonctionné pour une adresse par exemple), le JSON sera inutilisable.

    Pour palier à ça, on teste la présence de la longitude pour chaque entrée avant de faire le JSON. Pour ce faire, vu le mélange de syntaxe SPIP/JSON, on passe par un inclure pour que ça fonctionne.

    Si vous êtes sûr de votre CSV parce que vous l’avez vérifié et corrigé, vous pouvez supprimer le test et éviter ainsi l’inclure.

    1. <BOUCLE_csv(DATA){source csv, #GET{source}}{","}{cle>0}>[(#VALEUR{4}|!={''}|oui)
    2. <INCLURE{fond=inclure/json_pointsdevente,
    3. id=#COMPTEUR_BOUCLE,
    4. lon=#VALEUR{5},
    5. lat=#VALEUR{4},
    6. enseigne=#VALEUR{0},
    7. adresse=#VALEUR{1},
    8. cp=#VALEUR{2},
    9. ville= #VALEUR{3}} />
    10. ]</BOUCLE_csv>

    Télécharger

    Les critères :
    {cle>0} pour ne pas prendre en compte la 1ère ligne qui correspond à l’entête du tableau avec les noms des colonnes.
    {","} pour respecter la syntaxe JSON entre chaque propriétée

    Note
    #VALEUR{0} correspond à la valeur de la 1ère colonne, #VALEUR{1}, celle de le deuxième, etc...

    Dans inclure/json_pointsdevente.html

    1. {
    2. "type": "Feature",
    3. "geometry": {"type": "Point", "coordinates": [[(#ENV{lon})], [(#ENV{lat})]]},
    4. "id":"#ENV{id}",
    5. "properties": {[
    6. (#SET{titre,<h3>#ENV{enseigne}</h3>})]
    7. "title":[(#GET{titre}|json_encode)],[
    8. (#SET{description,#ENV{adresse}<br />#ENV{cp} #ENV{ville} })]
    9. "description":[(#GET{description}|json_encode)][
    10. (#CHEMIN_IMAGE{#ENV*{icone,0}}|sinon{#CHEMIN{#ENV*{icone,0}}}|gis_icon_properties)]
    11. }
    12. }

    Télécharger

    Afficher la carte

    Dans inclure/pointsdevente.html

    On affiche un lien pour que le visiteur puisse se géolocaliser avec une url type www.domaine.net/ma_page.html?geoloc=oui

    1. <a href="[(#SELF|parametre_url{geoloc,oui})]" class="ajax">me géolocaliser</a>

    Et, en fonction de la présence, ou non, du paramètre ?geoloc=oui dans l’URL, on affiche la carte avec ou sans géolocalisation du visiteur.

    1. [(#ENV{geoloc}|=={oui}|?{
    2. [(#INCLURE{fond=modeles/carte_gis,
    3. objets=pointsdevente,
    4. id_article=#ENV{id_article},
    5. localiser_visiteur=oui})]
    6. ,
    7. [(#INCLURE{fond=modeles/carte_gis,
    8. objets=pointsdevente,
    9. id_article=#ENV{id_article},
    10. centrer_auto=oui})]
    11. })]

    Télécharger

    Note
    Pour simplifier le code, je n’ai gardé que les paramètres indispensables à GIS dans notre cas, mais il est possible changer le zoom si le visiteur demande la géolocalisation pour afficher les points proches de lui de façon plus lisible.

    Dans le squelette de votre article

    1. <INCLURE{fond=inclure/pointsdevente,env,ajax,geoloc=#ENV{geoloc}} />

    Et hop, le tour est joué.

    Merci à b_b pour la piste et les outils.

    Les ressources

    La base adresse nationale
    Un référentiel national ouvert : de l’adresse à la coordonnée géographique
    https://adresse.data.gouv.fr

    La documentation du plugin GIS4
    article 4189

    Tester votre JSON
    Utiliser l’extension JSON Lite pour votre navigateur
    https://github.com/lauriro/json-lite

    Sur Contrib
    https://contrib.spip.net/GIS-JSON-CSV-et-boucle-DATA

  • Passer un tableau de valeur à un critère de façon optionnelle

    , par jeanmarie

    Le besoin

    Pouvoir filtrer le résultat d’une boucle dans un inclure en fonction de certains critères tout en gardant cette boucle fonctionnelle en l’absence de ces critères.

    Le cas concret

    Via un même inclure, afficher toutes les algues dans la rubrique algues et seulement celles présentes dans un produit sur la page produit avec un seul et même squelette.

    Le principe

    Les produits et les algues sont des articles liés entre eux par des mots clefs algues (groupe de mot-clefs 1).
    Chaque article algue (rubrique 13) a le mot clef algue lui correspondant et chaque article a le(s) mot-clef(s) algue qu’il contient.

    La rubrique algues

    Dans la rubrique algues, c’est facile, on veut afficher toutes les algues donc on fait simplement l’inclure :

    1. <INCLURE{fond=inclure/les-algues} />

    La page produit

    Dans la page produit, c’est (un peu) plus compliqué :

    On commence par rentrer dans un tableau les mots-clefs algues liés au produit.

    1. [(#REM) On déclare le tableau ]
    2. #SET{algues,#ARRAY}
    3.  
    4. [(#REM) On boucle sur les mot-clefs de l'article et on rempli le tableau ]
    5. <BOUCLE_alguesduproduit(MOTS){id_article}{id_groupe=1}> #SET{algues,#GET{algues}|push{#ID_MOT}}</BOUCLE_alguesduproduit>

    Télécharger

    Note : attention à bien laisser un espace dans la BOUCLE_alguesduproduit, sinon, elle ne renvoi rien et le tableau n’est pas rempli.

    Puis, on passe tout ça à l’inclure :

    1. <INCLURE{fond=inclure/les-algues,id_mot=#GET{algues} />

    L’inclure

    Ensuite, c’est dans l’inclure que ça se joue :

    1. [(#REM) On boucle sur les articles de la rubrique 13 dont l'id_mot a été passé via un tableau à l'environnement
    2. Pour que la boucle fonctionne même si il n'y a pas de tableau, il faut utiliser le critère conditionnel ?IN ]
    3.  
    4. <B_les_algues>
    5. <ul>
    6. <BOUCLE_les_algues(ARTICLES){id_rubrique=13}{id_mot ?IN #ENV{id_mot}}>
    7. <li><a href="#URL_ARTICLE">#TITRE</a></li>
    8. </BOUCLE_les_algues>
    9. </ul>
    10. </B_les_algues>

    Télécharger

    La doc : https://www.spip.net/fr_article4010.html

  • Supprimer le paramètre et l’ancre de pagination d’une url

    , par jeanmarie

    Soit une adresse https://www.brestculture.fr/-agenda-.html?debut_agenda_vignettes=30#pagination_agenda_vignettes dont on souhaite enlever les paramètres de pagination debut_agenda_vignettes=30 et #pagination_agenda_vignettes.

    On commence par rentrer l’url de la page dans une variable nommée... url (#originalité)

    1. var url = window.location.href;

    On supprime ensuite le paramètre définissant le début de la pagination (debut_agenda_vignettes=30) en prennant en compte le fait qu’il peut être précédé d’un ’ ?’ ou d’un ’&’ (#cleverguy)

    1. url = url.replace(/{\?,&}debut_([a-z0-9_]+)=([0-9]+)/,'');

    Enfin, on enlève l’ancre de pagination.

    1. url = url.replace(/#pagination_([a-z0-9_]+)/,'');

    Si on décortique

    {\?,&} Le début de la chaine recherchée est un ? ou un #

    debut_([a-z_]+) on cherche un truc du genre "debut_machin_truc_avec_des_tirets_bas_et_chiffres_ou_pas"

    #pagination_([a-z0-9_]+) on cherche un truc du genre "#pagination_machin_truc_avec_des_tirets_bas_et_chiffres_ou_pas"

    Et le tour est joué !

    Note

    la regex est valable peut importe le langage

    Ressources

    Tester les regex : https://regex101.com ou https://regexr.com
    CheatSheet : https://www.cheatography.com/davechild/cheat-sheets/regular-expressions/ ou en doc joint

  • Manips mySQL / phpMyadmin

    , par jeanmarie

    Ajouter des entrées dans une table existante

    Associer un mot clef à plusieurs articles

    1. INSERT INTO spip_mots_liens (id_mot, id_objet, objet) VALUES (3, 53, 'article'), (3, 52, 'article'), (3, 50, 'article');

    Source http://fr.wikihow.com/cr%C3%A9er-une-table-sous-MySQL

    Modifier des entrées dans une table existante

    Déplacer l’article n°1 dans la rubrique 5

    1. UPDATE `spip_articles` SET `id_rubrique`="5" WHERE `id_article`=1;

    Déplacer tous les articles du secteur 5 dans la rubrique 5 (pour supprimer les sous-rubrique

    1. UPDATE `spip_articles` SET `id_rubrique`="5" WHERE `id_secteur`=5;

    Trouver les documents qui ont plusieurs rôles et n’afficher que ceux sans rôle

    1. SELECT * FROM spip_documents_liens
    2. WHERE id_document IN
    3. (
    4. SELECT id_document FROM spip_documents_liens
    5. GROUP BY id_document
    6. HAVING COUNT(id_document)>1
    7. )
    8. AND ROLE=""

    Télécharger

  • Ne pas afficher un menu si il ne contient qu’une entrée

    , par jeanmarie

    Cas concret : on veut mettre en place un menu de navigation entre les articles d’une même rubrique. Le problème est que si on n’a qu’un article, il s’affiche, ce qui ne sert à rien et est perturbant.

    1. <B_menu>
    2. <div class="menu menu-container">
    3. <ul class="menu-items menu-liste">
    4. <BOUCLE_menu(ARTICLES) {id_rubrique} {!par titre}>[(#TOTAL_BOUCLE|>{1}|oui)
    5. <li class="item menu-entree[ (#EXPOSE)]">
    6. <a href="#URL_ARTICLE">[(#TITRE|couper{80})]</a>
    7. </li>
    8. ]</BOUCLE_menu>
    9. </ul>
    10. </div>
    11. </B_menu>

    Télécharger

    Si #TOTAL_BOUCLE est supérieur à 1, tu affiches ce que tu veux.
    Sinon, le test ne renvoie rien est la boucle vide ne s’affiche pas.

    Une précision importante : les crochets ouvrants et fermant du test doivent obligatoirement être collés aux balises ouvrantes et fermantes de le la boucle. Sinon, la boucle renvoie des espaces même si le test est négatif.

  • Afficher les dates des 1er et dernier évènements liés à un article

    , par jeanmarie

    Le but ici est d’afficher les dates des 1er et dernier évènements liés à un article.
    La petite subtilité est que, si l’article à 2 évènements le même jour mais à des heures différentes, on ne veut afficher qu’une seule fois le jour pour éviter d’avoir "17 janvier 2016 > 17 janvier 2016".

    1. [(#REM) On rentre tous les évènements par date dans un tableau ]
    2. #SET{tableau_evenements,#ARRAY}
    3. <BOUCLE_evenements(EVENEMENTS){id_article}{par date}>
    4. #SET{tableau_evenements, #GET{tableau_evenements}|push{#DATE_DEBUT|affdate}}
    5. </BOUCLE_evenements>
    6.  
    7. [(#REM) Avec 2 boucles DATA, on sort le 1er et le dernier évènement ]
    8. <BOUCLE_date_debut(DATA){source tableau,#GET{tableau_evenements}}{0,1}{par cle}>#SET{date_debut,#VALEUR}</BOUCLE_date_debut>
    9. <BOUCLE_date_fin(DATA){source tableau,#GET{tableau_evenements}}{0,1}{!par cle}>#SET{date_fin,#VALEUR}</BOUCLE_date_fin>
    10.  
    11. [(#REM) Si les 2 évènements ont lieu le même jour, on n'affiche que le 1er,
    12. sinon, on affiche les 2 ]
    13. [(#GET{date_debut}|=={#GET{date_fin}}|?{
    14. #GET{date_debut}
    15. ,
    16. #GET{date_debut}" > "#GET{date_fin}
    17. })]

    Télécharger