PHP → Javascript → CSS

Je reprends ce que je racontais il y a quelques jours au sujet du passage de données entre PHP et Javascript et entre Javascript et CSS, histoire de ne pas avoir de script javascript ou de styles inline dans le code.

Je vais prendre pour exemple le plugin hScroll qui permet de définir quelques paramètres utilisés côté CSS.

Notez que cette version du plugin n’est pas encore diffusée et qu’elle le sera après la sortie de la version 2.15 de Dotclear, dont elle dépend.

Mise en place des paramètres avec PHP

Voilà le traitement — je n’ai mis que la partie qui nous intéresse — effectué sur le behavior publicHeadContent :

…
echo \dcUtils::jsJson('hscroll', [
    'color'  => ($core->blog->settings->hscroll->color ?: '#e9573f'),
    'top'    => ($core->blog->settings->hscroll->position == 'top' ? "$offset" . 'px' : 'unset'),
    'bottom' => ($core->blog->settings->hscroll->position == 'bottom' ? "$offset" . 'px' : 'unset'),
    'shadow' => ($core->blog->settings->hscroll->shadow ? '1' : '0')
]);

echo
\dcUtils::jsLoad($core->blog->getPF('util.js')) .
\dcUtils::jsLoad($core->blog->getPF('hScroll/js/cssvar.js')) .
\dcUtils::cssLoad($core->blog->getPF('hScroll/css/hscroll.css'));
…
  1. L’utilisation de dcUtils::jsJson() permet d’inclure les paramètres au format JSON dans l’entête.
  2. L’inclusion de util.js permet d’avoir accès la fonction javascript de décodage.
  3. cssvar.js gère le passage des paramètres du côté des CSS
  4. Enfin inclusion de la feuille de style qui utilisent les variables CSS

Le code de la fonction dcUtils::jsJson() est le suivant :

public static function jsJson($id, $vars)
{
    // Use echo dcUtils::jsLoad($core->blog->getPF('util.js')); to use the JS getData() decoder in public mode
    $ret = '<script type="application/json" id="' . html::escapeHTML($id) . '-data">' . "\n" .
        json_encode($vars, JSON_HEX_TAG | JSON_UNESCAPED_SLASHES) . "\n" . '</script>';
    return $ret;
}

Sachant que le script proprement dit du plugin (affichage de la barre de lecture) est inclus en fin de page via le behavior publicFooterContent :

…
echo
'<div id="hscroll-bar"><div id="hscroll-bar-inner"></div></div>' . "\n" .
\dcUtils::jsLoad($core->blog->getPF('hScroll/js/hscroll.js'));
…

Le code du-dit script étant le suivant :

function hscroll_bar() {
  const t = document.querySelector('#hscroll-bar');
  t.style.width = `${window.pageYOffset / (document.body.clientHeight - window.innerHeight) * 100}%`;
}
window.addEventListener('load', hscroll_bar);
window.addEventListener('scroll', hscroll_bar);

Récupération des données JSON et mise en place des variables CSS

Là c’est le script cssvar.js qui fait le job :

const hscroll_data = getData('hscroll');
…
document.documentElement.style.setProperty('--hscroll-color', hscroll_data.color);
document.documentElement.style.setProperty('--hscroll-top', hscroll_data.top);
document.documentElement.style.setProperty('--hscroll-bottom', hscroll_data.bottom);
document.documentElement.style.setProperty('--hscroll-shadow', hscroll_data.shadow);

La fonction getData() fournie dans util.js est utilisée pour récupérer les variables qui sont ensuite définies côté CSS. La fonction getData() est codée ainsi :

var getData = getData || function(id, clear = true) {
  let data = {};
  // Read the JSON-formatted data from the DOM. (from https://mathiasbynens.be/notes/json-dom-csp)
  // To be use with: <script type="application/json" id="myid-data">{"key":value, …}</script>
  const element = document.getElementById(`${id}-data`);
  if (element) {
    try {
      data = JSON.parse(element.textContent);
      if (clear) {
        // Clear the element’s contents
        element.innerHTML = '';
      }
    } catch (e) {}
  }
  return data;
};

Vous noterez que j’utilise un var et un test logique qui permet de ne pas redéfinir la fonction si jamais le fichier était appelé plusieurs fois.

Récupération/utilisation des variables côté CSS

Enfin, dans la CSS, les variables sont utilisées ainsi :

#hscroll-bar {
  height: 4px;
  position: fixed;
  top: var(--hscroll-top);
  bottom: var(--hscroll-bottom);
  left: 0;
  z-index: 3000;
  -webkit-backface-visibility: hidden;
  -moz-backface-visibility: hidden;
  backface-visibility: hidden
}
#hscroll-bar-inner {
  box-shadow: var(--hscroll-shadow);
  height: 100%;
  background-color: var(--hscroll-color);
}

Conclusion

Aucun script inline, aucun style inline non plus, tout est passé/décodé via JSON. Ça rend le code plus simple, chacun se débrouillant avec ce dont il a besoin et on ne mélange pas code HTML/Javascript/CSS dans le markup.

Tout bénéf’ donc \o/


Côté administration, il existe une fonction équivalente à dcUtils::jsJson() : dcPage::jsJson(), avec les mêmes paramètres. La fonction Javascript de récupération des données, getData(), est quant à elle disponible en permanence.

Ajouter un commentaire

Les champs suivis d'un * sont obligatoires

Les commentaires peuvent être formatés en utilisant la syntaxe Markdown Extra.

Ajouter un rétrolien

URL de rétrolien : https://open-time.net/trackback/13993

Haut de page