Solutions for generating dynamic javascript / CSS

One additional option, depending on the kind of parameters you need to pass in. Let’s call it (2a). You can also create PHP scripts which output dynamically-generated text/css or text/javascript rather than text/html, and provide them the data that they need using GET parameters rather than by loading up WordPress. Of course this only works if you need to pass in a relatively small number of relatively compact parameters. So, for instance, say you need to pass in only the URL of a post or the directory of a file or similar, you can do something like this:

In header.php:

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

In fancy-js.php:

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

etc.

But this only allows you access to the data directly passed in the GET parameters; and it will only work if the number of things you need to pass in is relatively small, and the representation of those things relatively compact. (Basically handful of string or numeric values — a username, say, or a directory; not a list of all of a user’s recent posts or something like that.)

As for which one of these options is the best — I don’t know; that depends on your use case. Option (1) has the merit of being simple, and clearly allowing you access to any WordPress data you could possibly need, without the performance hit of loading WordPress twice. It’s almost certainly what you should do unless you have a strong reason not to (e.g. due to the size of the stylesheet or script that you need to use).

If the size becomes big enough to cause a problem in terms of the weight of your one page, then you can try out (2) or (2a).

Or else — this is probably the better idea — you can try to separate out the parts of the script or the stylesheet that actually make use of the dynamic data from the parts that can be specified statically. Ssay you have a stylesheet that needs to be passed a directory from WordPress in order to set a background parameter for the #my-fancy element. You could put all of this into the head element:

 <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>

But why would you need to do that? There’s only one line here that depends on data from WordPress. Better to split out only the lines that depend on WordPress:

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

Put everything else in a static stylesheet that you load in with a standard link element (style.css or whatever):

 #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 ... */

And let the cascade do the work.

The same goes for JavaScript: rather than doing this:

 <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>

Instead put something like this in the head element:

 <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>

And then drop the rest into a static JavaScript file, rewriting the my_huge_function() and my_other_function() to make use of the globals WordPressPostData.url and WordPressPostData.author.

40K of CSS or 40K of JS can almost always be split into <1K that actually depends on dynamic data, and the rest, which can be specified in a static external file and then recombined using either the cascade (for CSS) or globally-accessible variables (globals, DOM elements, or whatever other cubby-hole you prefer, for JS).

Leave a Comment