web-dev-qa-db-fra.com

Des solutions pour générer du javascript/CSS dynamique

Supposons que vous deviez générer du code javascript ou CSS qui dépend du contexte actuel.

Par exemple, vous avez un formulaire sur la page d'accueil qui déclenche une demande ajax lors de l'envoi, et un formulaire différent sur la page unique. Ou, dans le cas de CSS, vous voulez créer un thème qui permette à ses utilisateurs de créer leur propre mise en page, de changer de couleur, etc.

Solutions que je vois jusqu'à présent:

  1. Inclure le code dans la section head du document (ou à la fin dans le cas de JS)

  2. Faites une demande spéciale qui sort le code, comme site.com?get_assets. Ceci est lent car WP est chargé deux fois.

  3. Stockez-le dans des fichiers temporaires pendant un certain temps et chargez-le à partir de là. Pas très fiable pour les thèmes publics ou les plugins.

  4. Javascript uniquement - rendez-le statique en le plaçant dans un fichier normal qui est chargé à chaque fois. Dans ce cas, vous devrez obliger votre code à gérer n'importe quelle situation.

Connaissez-vous les autres? Où irais-tu?

14
onetrickpony

Une option supplémentaire, en fonction du type de paramètres à transmettre. Appelons-le (2a). Vous pouvez également créer PHP scripts générant de manière dynamique text/css ou text/javascript plutôt que text/html et leur fournir les données dont ils ont besoin à l'aide de paramètres GET plutôt qu'en chargeant WordPress. Bien entendu, cela ne fonctionne que si vous devez transmettre un nombre relativement petit de paramètres relativement compacts. Ainsi, par exemple, supposons que vous n’ayez besoin de transmettre que l’URL d’une publication ou le répertoire d’un fichier ou un fichier similaire, vous pouvez procéder de la manière suivante:

Dans header.php:

 <script type="text/javascript" src="<?php print get_stylesheet_directory_uri(); 
 ?>/fancy-js.php?foo=bar&amp;url=<?php print urlencode(get_permalink($post->ID)); ?>"></script>

En fantaisie-js.php:

 <?php
 header("Content-type: text/javascript");
 ?>
 foo = <?php print json_encode($_GET['foo']); ?>;
 url = <?php print json_encode($_GET['url']); ?>;

etc.

Mais cela ne vous permet que d'accéder aux données directement transmises dans les paramètres GET; et cela ne fonctionnera que si le nombre d'éléments que vous devez transmettre est relativement petit et si la représentation de ces éléments est relativement compacte. (Fondamentalement une poignée de valeurs de chaîne ou numériques - un nom d'utilisateur, par exemple, ou un répertoire; pas une liste de toutes les publications récentes d'un utilisateur ou quelque chose comme ça.)

En ce qui concerne laquelle de ces options est la meilleure - je ne sais pas; cela dépend de votre cas d'utilisation. L’option (1) a le mérite d’être simple et de vous permettre clairement d’accéder à toutes les données WordPress dont vous pourriez avoir besoin, sans avoir à charger deux fois WordPress. C’est presque certainement ce que vous devriez faire sauf si vous avez une raison forte de ne pas le faire (par exemple, en raison de la taille de la feuille de style ou du script que vous devez utiliser).

Si la taille devient suffisamment grande pour poser un problème en termes de poids d'une page, vous pouvez essayer (2) ou (2a).

Ou bien - c'est probablement la meilleure idée - vous pouvez essayer de séparer les parties du script ou de la feuille de style qui utilisent réellement les données dynamiques des parties pouvant être spécifiées de manière statique. Ssay, vous avez une feuille de style qui doit recevoir un répertoire de WordPress afin de définir un paramètre d’arrière-plan pour l’élément # my-fancy. Vous pouvez mettre tout cela dans l'élément head:

 <style type="text/css">
 #my-fancy-element {
      background-image: url(<?php print get_stylesheet_directory_uri(); ?>images/fancy.png);
      padding: 20px;
      margin: 20px;
      font-weight: bold;
      text-transform: uppercase;
      font-size: 12pt;
      /* ... KB and KB of additional styles ... */
 }
 #another-fancy-element {
     /* ... KB and KB of additional styles ... */
 }
 /* ... KB and KB of additional styles ... */
 </style>

Mais pourquoi auriez-vous besoin de faire ça? Il n'y a qu'une ligne ici qui dépend des données de WordPress. Mieux vaut ne séparer que les lignes qui dépendent de WordPress:

 <style type="text/css">
 #my-fancy-element {
      background-image: url(<?php print get_stylesheet_directory_uri(); ?>images/fancy.png);
 }
 </style>

Placez tout le reste dans une feuille de style statique que vous chargez avec un élément de lien standard (style.css ou autre):

 #my-fancy-element {
      /* background-image provided dynamically */
      padding: 20px;
      margin: 20px;
      font-weight: bold;
      text-transform: uppercase;
      font-size: 12pt;
      /* ... KB and KB of additional styles ... */
 }
 #another-fancy-element {
     /* ... KB and KB of additional styles ... */
 }
 /* ... KB and KB of additional styles ... */

Et laissez la cascade faire le travail.

La même chose vaut pour JavaScript: plutôt que de faire ceci:

 <script type="text/javascript">
 // Here comes a huge function that uses WordPress data:
 function my_huge_function () {
     // Do a million things ...

     jQuery('#my-fancy').append('<a href="'+<?php json_encode(get_permalink($GLOBALS['post']->ID)); ?>+'">foo</a>);

     // Do a million more things ...

     my_other_function(<?php print json_encode(get_userdata($GLOBALS['post']->post_author); ?>);
 }

 function my_other_function (user) {
     // Do a million things ...
 }
 </script>

Au lieu de cela, mettez quelque chose comme ceci dans l'élément head:

 <script type="text/javascript">
 var WordPressPostData = {
 url: <?php print json_encode(get_permalink($GLOBALS['post']->ID)); ?>,
 author: <?php print json_encode(get_userdata($GLOBALS['post']->post_author)); ?>
 }
 </script>

Et déposez ensuite le reste dans un fichier JavaScript statique, en réécrivant my_huge_function () et my_other_function () pour utiliser les globales WordPressPostData.url et WordPressPostData.author.

40K de CSS ou 40K de JS peuvent presque toujours être divisés en <1K qui dépendent en fait de données dynamiques, le reste pouvant être spécifié dans un fichier externe statique puis recombiné à l'aide de la cascade (pour CSS) ou globalement accessible. les variables (globals, éléments DOM ou tout autre cube que vous préférez, pour JS).

8
radgeek

Le cas dynamique de CSS est assez simple.

Créez simplement une fonction qui génère les définitions CSS dynamiques à l'intérieur des balises <style type="text/css"></style>, puis raccordez cette fonction à wp_print_styles. par exemple.

<?php
function mytheme_dynamic_css() {
    $options = get_option( 'mytheme_options' );
    ?>
    <style type="text/css">
    /* Dynamic H1 font family */
    h1 { font-family: <?php echo $options['h1_font_family']; ?>;
    </style>
    <?php
}
add_action( 'wp_print_styles', 'mytheme_dynamic_css' );
?>

Ou, disons que vous avez des jeux de couleurs préconfigurés; vous pouvez mettre en file d'attente la feuille de style appropriée en fonction du paramètre utilisateur actuel:

<?php
function mytheme_enqueue_colorscheme_stylesheet() {
    $options = get_option( 'mytheme_options' );
    $color_scheme = $options['color_scheme'];
    wp_enqueue_style( $colorscheme, get_template_directory_uri() . '/css/' . $color_scheme . '.css' );
}
add_action( 'wp_enqueue_scripts', 'mytheme_enqueue_colorscheme_stylesheet' );
?>

Notez que, dans ce cas, la fonction s'accroche à wp_enqueue_scripts, étant donné que WordPress n'a pas de hook d'action wp_enqueue_styles.

5
Chip Bennett

J'y pensais depuis un moment. Votre question me fait y revenir. Je ne suis pas sûr que ce soit une bonne idée ou non, alors j'aimerais que les experts commentent.

Et si i écrivez le fichier javascript/css via php lorsque l'administrateur sauvegarde les données. Ce sera une écriture unique jusqu'à ce que l'utilisateur modifie à nouveau la présentation (ce que l'utilisateur ne peut pas faire trop souvent). De cette façon, nous n’accédons à la base de données pour les paramètres utilisateur qu’une seule fois lorsqu’il enregistre des données.

Après avoir écrit le fichier, ce sera un fichier javascript/css régulier, nous n’aurons donc pas à appeler la base de données à chaque chargement du thème.

Une question à laquelle il faut répondre: Que se passera-t-il lorsqu'un visiteur tente d'accéder au site à l'instant où php écrit le fichier?

Laissez-moi savoir ce que vous pensez.

2
Sisir

Pour les petits morceaux de script, que vous pouvez ne pas vouloir inclure dans un fichier séparé, par exemple parce qu'ils sont générés dynamiquement, WordPress 4.5 et d'autres offres wp_add_inline_script . Cette fonction verrouille le script sur un autre script. Supposons, par exemple, que vous développiez un thème et que vous souhaitiez que votre client puisse insérer ses propres scripts (tels que Google Analytics ou AddThis) via la page des options. Exemple .

Pour les styles, il existe wp_add_inline_style , qui fonctionne fondamentalement de la même manière. Vous l'utiliseriez, par exemple, pour parcourir tous vos mods de personnalisation et les rassembler dans une chaîne appelée $all_mods, que vous ajouteriez ensuite à votre feuille de style principale:

if (!empty($all_mods)) wp_add_inline_style ('main-style', $all_mods);
1
cjbj