Carnet Wiki

Boucle DATA et CSV associés à un article

Cf https://discuter.spip.net/t/integration-dune-boucle-data-dans-un-article-avec-le-fichier-csv-en-document-joint/170333

Question  : Comment mettre en place une boucle DATA afin de générer une chronologie à partir d’un fichier en format CSV ?

Réponse : La meilleure façon serait de l’intégrer dans un « modèle » (dossier « modeles/ » de n’importe quel plugin ou squelettes) afin ensuite de pouvoir l’appeler dans les textes de n’importe quel contenu SPIP (article ou autres) : <chronologie_csv|param_a=valeur_a|param_b=valeur_b>. modeles/chronologie_csv.html pourrait ensuite être intégré à un article avec un <chronologie_csv1234> où « 1234 » serait l’identifiant du document CSV associé à l’article.

Suite OK : voici le code actuellement fonctionnel avec quelques explications ;

-  VALEUR {X} : X est le numéro de la colonne, à rappeler que X=0 est la premiere colonne du tableur (Librecalc)
-  Par la suite, la mise en forme se fait en CSS
-  À la fin de la boucle on trouve le bouton et le script qui permet de dérouler ou réduire les informations complémentaires.

[(#REM) 3. Vos feuilles de style pour l'habillage de la chronologie]
[<link rel="stylesheet" href="(#CHEMIN{css/chrono.css}|direction_css|timestamp)" type="text/css" />]
#INSERT_HEAD

<div class="chrono"> <!--mise en forme du contenu -->
<B_documents_joints> <!-- début de la boucle -->
  <!-- type et nom du doc [dans /], colone de classement -->
  <BOUCLE_csv(DATA){source csv, IMG/csv/chronologie_desarmement_source.csv}
    {par /9}{"<br>"}>
    <!-- Bloc date -->
    <div class="chrono_bloc">
      <!-- Bloc texte -->
      <div class="chrono_text">
        <!-- Titre principale du traité -->
        <h2>#VALEUR{3}</h2>
        <p>Nom complet du traité : #VALEUR{2}</p>
        <p>Signature : #VALEUR{0}</p>
        <p>Entrée en vigueur : #VALEUR{1}</p>
        <div class="chrono_content">
          <h3>Historique</h3>
          <p>#VALEUR{4}</p>
          <h3>Position de la France</h3>
          <p>#VALEUR{5}</p>
          <h3>Actualité du traité</h3>
          <p>#VALEUR{6}</p>
          <h3>Ressources et références</h3>
          <p>#VALEUR{7}</p>
        </div>
      </div>
      
<button class="unroll" type="button">+</button>
      <div class="chrono_date_box">
        <div class="chrono_date">#VALEUR{9}</div>
      </div>
    </div>
    </BOUCLE_csv>
  </B_documents_joints>
</div>

<script>
  // on click the current .unroll unroll the sibling .chrono_content and change the button' text
  document.querySelectorAll('.unroll').forEach(item => {
    item.addEventListener('click', event => {
      item.previousElementSibling.classList.toggle('unrolled');
      if (item.innerHTML == '+') {
      item.innerHTML = '-';
    } else {
      item.innerHTML = '+';
    }
  })
})
</script>

Page résultat : https://www.obsarm.info/spip.php?article561

Accès au fichier

Dans ce code, c’est le critère {source csv, nomfichiercsv} de la boucle DATA qui définit quel est le fichier des données sur lesquelles la boucle va itérer, et il faut modifier le modele si le nom de fichier change, ou si on veut l’utiliser dans un autre article avec un autre fichier.

Pour éviter cela, il serait possible de chercher et récupérer le document csv lié à l’article, par exemple en retenant le 1er des documents liés à l’article ayant l’extension .csv, en triant par le titre.

-  récupérer le fichier :

<BOUCLE_csv(DOCUMENTS){id_article}{extension=csv}{par num titre}{0,1}> #SET{source_csv,#FICHIER} </BOUCLE_csv>


-  puis utiliser #GET{source_csv} dans la boucle DATA

Cela permet d’utiliser le même modèle dans un autre article : il chargera le fichier CSV de cet autre article. C’est assez précisément ce qui est décrit dans cet article : Tutoriel : Afficher sur une carte GIS des points dont on n’a que l’adresse

Ce qui donne au final :

[(#REM) 3. Vos feuilles de style pour l'habillage de la chronologie]
[<link rel="stylesheet" href="(#CHEMIN{css/chrono.css}|direction_css|timestamp)" type="text/css" />]
#INSERT_HEAD

<div class="chrono"> <!--mise en forme du contenu -->
<B_documents_joints> <!-- début de la boucle -->
  <BOUCLE_csv(DOCUMENTS){id_article}{extension=csv}{par num titre}{0,1}>
     #SET{source_csv,#FICHIER} 
  </BOUCLE_csv>
  
  <BOUCLE_chrono(DATA){source csv, #GET{source_csv}}{par /8}{"<br>"}>
    <!-- Bloc date -->
    <div class="chrono_bloc">
      <!-- Bloc texte -->
      <div class="chrono_text">
        <h2>#VALEUR{3}</h2>
        <!-- colonne traité (surement col 2) -->
        <p>Nom complet du traité : #VALEUR{2}</p>
        <p>Adoption : #VALEUR{0}</p>
        <p>Entrée en vigueur : #VALEUR{1}</p>
        <div class="chrono_content">
          <h3>Historique</h3>
          <p>#VALEUR{4}</p>
          <h3>Position de la France</h3>
          <p>#VALEUR{5}</p>
          <h3>Actualité du traité</h3>
          <p>#VALEUR{6}</p>
          <h3>Ressources et références</h3>
          <p>#VALEUR{7}</p>
        </div>
      </div>
      <button class="unroll" type="button">+</button>
      <div class="chrono_date_box">
        <div class="chrono_date">#VALEUR{8}</div>
      </div>
      
    </div>
    </BOUCLE_chrono>
  </B_documents_joints>
</div>

<script>
  // on click the current .unroll unroll the sibling .chrono_content and change the button' text
  document.querySelectorAll('.unroll').forEach(item => {
    item.addEventListener('click', event => {
      item.previousElementSibling.classList.toggle('unrolled');
      if (item.innerHTML == '+') {
      item.innerHTML = '-';
    } else {
      item.innerHTML = '+';
    }
  })
})
</script>
JLuc - Mise à jour :30 juin 2023 à 10h16min