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

Web dev

Truc, astuces et tuto sur le CMS SPIP ou sur le développement web en général.

Du text-overflow : ellipsis et un élément à width : 100%.

J’étais en train de bricoler une div avec une largeur à 100% et un texte-overflow ellipsis.

Cela ne fonctionne pas en l’état :

  1. .ma_div {
  2. display: block;
  3. overflow: hidden;
  4. white-space: nowrap;
  5. width: 100%;
  6. text-overflow: ellipsis;
  7. }

Pourquoi ? Je ne sais pas trop, mais avec quelques règles en plus on peut avoir le résultat que l’on attend, a savoir une div « fuilde » et un texte avec « ... » pour ce qui dépasse :

  1. .ma_div {
  2. display: table;
  3. overflow: hidden;
  4. white-space: nowrap;
  5. width: 100%;
  6. table-layout: fixed;
  7. text-overflow: ellipsis;
  8. }
Voir en ligne : text-overflow : ellipsis in table-cell without width

Trouver toutes les rubriques enfants d’une rubrique #SPIP

[Edit] : Comme signalé dans un commentaire, il existe bien une fonction native qui s’occupe de cela.

Il est parfois intéressant d’avoir la liste complètes des sous-rubriques d’une rubrique.

Par exemple, pour conditionner l’affichage d’un élément à une rubrique et tous ces enfants.

Il n’existe pas de fonction SPIP pour faire cela (ou en tout cas je ne l’ai pas trouvée). Voici donc un peu de code pour régler le problème.
C’est un collègue qui est à l’origine de cette fonction, je l’ai adaptée.

Attention, il faut PHP >= 5.5 ou installer le plugin SPIP bonux, à cause de la fonction array_column.

  1. /**
  2.  * Retrouver les enfants directs d'une rubrique.
  3.  *
  4.  * @param int $id_rubrique
  5.  * @access public
  6.  * @return array tableau contenant les id_rubrique direct.
  7.  */
  8. function trouver_enfant($id_rubrique) {
  9. include_spip('base/abstract_sql');
  10. $sous_rubriques = sql_allfetsel('id_rubrique', 'spip_rubriques', 'id_parent='.intval($id_rubrique));
  11. return array_column($sous_rubriques, 'id_rubrique');
  12. }
  13.  
  14. /**
  15.  * Trouver les sous-rubriques d'une rubrique.
  16.  *
  17.  * @param int $id_rubrique l'id de la rubrique
  18.  * @return array une liste d'id_rubrique
  19.  */
  20. function trouver_enfants($id_rubrique) {
  21.  
  22. // Trouver la première série de sous-rubrique.
  23. $sous_rubriques = trouver_enfant($id_rubrique);
  24.  
  25. // S'il n'y a pas de sous rubriques, on sort de la boucle avec juste la rubrique de base
  26. if (count($sous_rubriques) === 0) {
  27. return array($id_rubrique);
  28. } else {
  29. // On cherche en profondeur.
  30. foreach ($sous_rubriques as $id_sous_rubrique) {
  31. $recur = trouver_enfant($id_sous_rubrique);
  32.  
  33. // Il y a des enfants, on les ajoute à la liste des sous rubrique
  34. // déjà trouvée.
  35. if ($recur) {
  36. $sous_rubriques = array_merge($sous_rubriques, $recur);
  37. }
  38. }
  39.  
  40. // Placer la rubrique initiale en première position.
  41. array_unshift($sous_rubriques, $id_rubrique);
  42.  
  43. return $sous_rubriques;
  44. }
  45. }

Formulaire générique d’édition de méta #SPIP

L’idée derrière ce formulaire est assez simple, pouvoir gérer n’importe quelle valeur de la table spip_metas et la modifiée. Si elle n’existe pas, la méta sera crée.

Il convient de prendre en compte qu’il y a 2 types de méta dans spip :

  • les métas simples, le casier ne contient qu’une seul valeur .
  • les métas plus complexent qui sont des tableaux php sérialisé.

Cela couvre un besoin similaire à Identité Extra, mais de manière plus générique.

L’idée finale serait d’avoir un plugin de gestion des métas du site (et donc des options des plugins) plus générique et plus facile d’accès. Je trouve qu’il pourrait être plus simple de déclarer des options de plugin sans avoir a déclaré systématiquement un CVT complet.

Fichier formulaires/editer_meta.html :

  1. <div class="formulaire_spip formulaire_#FORM">
  2.  
  3. [<p class="reponse_formulaire reponse_formulaire_erreur">
  4. (#ENV*{message_erreur})
  5. </p>]
  6. [<p class="reponse_formulaire reponse_formulaire_ok">
  7. (#ENV*{message_ok})
  8. </p>]
  9.  
  10. [(#EDITABLE|oui)
  11. <form action="#ENV{action}" method="post">
  12. #ACTION_FORMULAIRE{#ENV{action}}
  13.  
  14. #GENERER_SAISIES{#ENV{_saisies}}
  15.  
  16. <p class="boutons">
  17. <input type="submit" class="submit" value="<:pass_ok:>" />
  18. </p>
  19. </form>
  20. ]
  21. </div>

fichier formulaires/editer_meta.php :

  1. <?php
  2.  
  3. if (!defined('_ECRIRE_INC_VERSION')) {
  4. return;
  5. }
  6.  
  7. /**
  8.  * Fonction saisie pour le formulaire d'édition générique de méta
  9.  *
  10.  * @param string $casier nom du meta casier
  11.  * @param string $meta nom de l'éventuel sous-méta
  12.  * @param array $options tableau d'options :
  13.  *
  14.  * ```php
  15.  * $options_defaut = array(
  16.  * 'type_saisie' => 'input',
  17.  * 'label' => 'label'
  18.  * );
  19.  * ```
  20.  *
  21.  * @access public
  22.  * @return array
  23.  */
  24. function formulaires_editer_meta_saisies_dist($casier, $meta = null, $options = array()) {
  25.  
  26. // option par défaut
  27. $options_defaut = array(
  28. 'type_saisie' => 'input',
  29. 'label' => 'label'
  30. );
  31. // Fusionner les options par défaut avec les options de l'utilisateur
  32. $options = array_merge($options_defaut, $options);
  33.  
  34. // Récupérer le meta casier et créer sa saisie
  35. $casier = ($meta) ? $casier.'/'.$meta : $casier;
  36. $saisies = array(
  37. 'saisie' => $options['type_saisie'],
  38. 'options' => array(
  39. 'nom' => $casier,
  40. 'label' => $options['label']
  41. )
  42. )
  43. );
  44.  
  45. return $saisies;
  46. }
  47.  
  48. /**
  49.  * Fonction charger pour le formulaire d'édition générique de méta
  50.  *
  51.  * @param string $casier nom du meta casier
  52.  * @param string $meta nom de l'éventuel sous-méta
  53.  * @param array $options tableau d'options :
  54.  *
  55.  * ```php
  56.  * $options_defaut = array(
  57.  * 'type_saisie' => 'input',
  58.  * 'label' => 'label'
  59.  * );
  60.  * ```
  61.  *
  62.  * @access public
  63.  * @return array
  64.  */
  65. function formulaires_editer_meta_charger_dist($casier, $meta = null, $options = array()) {
  66. // Récupérer le casier
  67. $casier = ($meta) ? $casier.'/'.$meta : $casier;
  68.  
  69. // Lire la configuration
  70. include_spip('inc/config');
  71. $contexte = lire_config($casier, array());
  72.  
  73. // Dans le cas d'une saisie simple, on s'assure de renvoyer un tableau
  74. // valide pour la fonction charger
  75. if (!is_array($contexte)) {
  76. $contexte = array($casier => $contexte);
  77. }
  78.  
  79. return $contexte;
  80. }
  81.  
  82. /**
  83.  * Fonction traiter pour le formulaire d'édition générique de méta
  84.  *
  85.  * @param string $casier nom du meta casier
  86.  * @param string $meta nom de l'éventuel sous-méta
  87.  * @param array $options tableau d'options :
  88.  *
  89.  * ```php
  90.  * $options_defaut = array(
  91.  * 'type_saisie' => 'input',
  92.  * 'label' => 'label'
  93.  * );
  94.  * ```
  95.  *
  96.  * @access public
  97.  * @return array
  98.  */
  99. function formulaires_editer_meta_traiter_dist($casier, $meta = null, $options = array()) {
  100.  
  101. // Enregistrer la méta
  102. include_spip('inc/config');
  103.  
  104. // Récupérer l'ancienne configuration du casier
  105. $old_config = lire_config($casier);
  106. if (is_array($old_config)) {
  107. // Dans le cas d'une méta complexe, on va fusionner les fusionner avec
  108. // la nouvelle
  109. $new_config = _request($casier);
  110. $new_config = array_merge($old_config, $new_config);
  111. } else {
  112. // Cas d'une saisie simple, on enregistre simplement la meta
  113. $new_config = _request($casier);
  114. }
  115.  
  116. // Ecrire la nouvelle méta
  117. $ecrire = ecrire_config($casier, $new_config);
  118.  
  119. // Retour du formulaire
  120. if ($ecrire) {
  121. return array(
  122. 'editable' => true,
  123. 'message_ok' => _T('info_modification_enregistree')
  124. );
  125. } else {
  126. return array(
  127. 'editable' => true,
  128. 'message_erreur' => _T('erreur')
  129. );
  130. }
  131. }

Un fichier sourcemap SASS pour Foundation

Un de mes collègues a trouvé une solution pour avoir un fichier source map quand on compile Foundation.

Son fichier fait d’autres trucs, je n’ai extrait que la partie source map.

On commence par installer gulp-sourcemap :

  1. npm install gulp-sourcemaps --save-dev

Ensuite on adapte le fichier gulpfile.js pour qu’il génère le sourcemap :

  1. var gulp = require('gulp');
  2. var $ = require('gulp-load-plugins')();
  3.  
  4. var sassPaths = [
  5. 'bower_components/foundation-sites/scss',
  6. 'bower_components/motion-ui/src'
  7. ];
  8.  
  9. gulp.task('sass', function() {
  10. return gulp.src('scss/app.scss')
  11. .pipe($.sourcemaps.init())
  12. .pipe($.sass({
  13. includePaths: sassPaths,
  14. outputStyle: 'compressed' // if css compressed **file size**
  15. }).on('error', $.sass.logError))
  16. .pipe($.autoprefixer({
  17. browsers: ['last 2 versions', 'ie >= 9']
  18. }))
  19. .pipe($.sourcemaps.write('../css'))
  20. .pipe(gulp.dest('css'));
  21. });
  22.  
  23. gulp.task('default', ['sass'], function() {
  24. gulp.watch(['scss/**/*.scss'], ['sass']);
  25. });

Menu responsive avec foundation

Depuis la version 6 du framework SASS/CSS Foundation, le composant qui sert à créer le menu principal du site, à savoir la « top bar » n’est plus un menu responsif « out of the box ».

C’est a vous d’en construire un avec les composants, comme l’explique la documentation.

Voici une structure html qui devrait couvrir la majorité des besoins. N’ont pas que c’est bien compliqué à réaliser, mais j’en ai marre de la refaire encore et toujours.

  1. <div class="title-bar" data-responsive-toggle="main-menu" data-hide-for="medium">
  2. <button class="menu-icon" type="button" data-toggle></button>
  3. <div class="title-bar-title">Menu</div>
  4. </div>
  5. <div class="top-bar" id="main-menu">
  6. <div class="top-bar-left">
  7. <ul class="vertical medium-horizontal menu dropdown" data-responsive-menu="drilldown medium-dropdown" data-parent-link="true">
  8. <li>
  9. <a href="#">Lien</a>
  10. <ul class="menu vertical">
  11. <li>
  12. <a href="">Lien</a>
  13. <ul class="menu vertical">
  14. <li>
  15. <a href="">Lien</a>
  16. </li>
  17. <li>
  18. <a href="">Lien</a>
  19. </li>
  20. <li>
  21. <a href="">Lien</a>
  22. </li>
  23. </ul>
  24. </li>
  25. <li>
  26. <a href="">Lien</a>
  27. </li>
  28. <li>
  29. <a href="">Lien</a>
  30. </li>
  31. </ul>
  32. </li>
  33. <li><a href="#">Lien</a></li>
  34. <li><a href="#">Lien</a></li>
  35. <li><a href="#">Lien</a></li>
  36. <li><a href="#">Lien</a></li>
  37. <li><a href="#">Lien</a></li>
  38. </ul>
  39. </div>
  40. </div>